Positionnement avancé

Le « Positionnement statique » est le flux normal de la page avec laquelle nous avons travaillé jusqu’ici. Le modèle de boîte CSSles float et les mises en page avec flexbox fonctionnent tous dans ce flux «statique», mais ce n’est pas le seul schéma de positionnement disponible en CSS.

Les trois autres types de positionnement sont le positionnement «relatif», le positionnement «absolu» et le positionnement «fixe». Chacun d’entre eux vous permet de positionner manuellement des éléments en utilisant des coordonnées spécifiques, à l’inverse des options plus sémantiques de flexbox et des float. Au lieu de dire «Placez cette boîte au centre de son contenant», le positionnement avancé vous permet de dire des choses comme «Mettez cette boîte 20 pixels au-dessus et 50 pixels à la droite de l’origine de son parent.

La grande majorité des éléments sur une page Web doivent être disposés selon le flux statique de la page. Ces autres schémas de positionnement entrent en jeu lorsque vous voulez faire des choses plus avancées comme modifier la position d’un élément particulier ou animer un composant d’interface utilisateur sans influencer les éléments environnants.

Ce chapitre est divisé en deux parties. Nous commencerons par examiner le positionnement relatif, absolu et fixe de manière isolée, puis nous appliquerons tout ce que nous avons appris pour fabrqiuer un menu déroulant.

Setup

Commencez par créer un nouveau dossier advanced-positioning et un nouveau fichier appelé schemes.html avec le balisage suivant:

<!DOCTYPE html>
<html>
  <head>
    <meta charset='UTF-8'/>
    <title>Positioning Is Easy!</title>
    <link href='styles.css' rel='stylesheet'/>
  </head>
  <body>

    <div class='container'>
      <div class='example relative'>
        <div class='item'><img src='images/static.svg' /></div>
        <div class='item item-relative'><img src='images/relative.svg' /></div>
        <div class='item'><img src='images/static.svg' /></div>
      </div>
    </div>
    
    <div class='container'>
      <div class='example absolute'>
        <div class='item'><img src='images/static.svg' /></div>
        <div class='item item-absolute'><img src='images/absolute.svg' /></div>
        <div class='item'><img src='images/static.svg' /></div>
      </div>
    </div>

    <div class='container'>
      <div class='example fixed'>
        <div class='item'><img src='images/static.svg' /></div>
        <div class='item item-fixed'><img src='images/fixed.svg' /></div>
        <div class='item'><img src='images/static.svg' /></div>
      </div>
    </div>

  </body>
</html>
HTML

Nous avons trois exemples à utiliser, tous avec la même structure HTML. Changer le comportement de positionnement à l’intérieur de chacun aura des effets très différents.

Cette page utilise des images pour rendre nos exemples un peu plus clair. Conservez le dossier images parent lorsque vous décompressez les fichiers dans votre projet. Assurez-vous de créer le fichier styles.csset de le remplir avec le code CSS suivant:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 1200px;
}

.container {
  display: flex;
  justify-content: center;
}

.example {
  display: flex;
  justify-content: space-around;
  
  width: 800px;
  margin: 50px 0;
  background-color: #D6E9FE;
}

.item img {
  display: block;
}
CSS

Rien de nouveau ici, juste quelques techniques flexbox familières pour créer une grille d’éléments. La seule chose étrange est la hauteur explicite height sur l’élément <body>, qui nous permettra de faire défiler la page pour faire la démonstration de différents comportements de positionnement.

Éléments positionnés

La propriété CSS position vous permet de modifier le schéma de positionnement d’un élément particulier. Sa valeur par défaut, comme vous pouvez l’imaginer, est static. Lorsque la propriété position d’ un élément n’a pas sa valeur par défaut, elle est appelée « élément positionné ». Les éléments positionnés sont ce dont parle tout ce chapitre.

Il est possible de mélanger les différents schémas de positionnement. Encore une fois, la plupart des éléments d’une page web doit être positionnée de manière statique, mais il est courant de trouver des éléments positionnés relativement et absolument à l’intérieur d’autres éléments qui font partie du flux normal de la page.

Positionnement relatif

Le «positionnement relatif» déplace les éléments par rapport à l’endroit où ils apparaîtraient normalement dans le flux statique de la page.

Transformons l’élément .item-relative dans schemes.html en un élément relativement positionné. Ajoutez la règle suivante à styles.css:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 1200px;
}

.container {
  display: flex;
  justify-content: center;
}

.example {
  display: flex;
  justify-content: space-around;
  
  width: 800px;
  margin: 50px 0;
  background-color: #D6E9FE;
}

.item img {
  display: block;
}

.item-relative {
  position: relative;
  top: 30px;
  left: 30px;
}
CSS

Le code position: relative; en fait un élément positionné, et les propriétés topet left vous permettent de définir dans quelle mesure l’élément se décale de sa position statique. Cela ressemble en quelque sorte à la définition d’une coordonnée ( x , y ) pour l’élément.

Le positionnement relatif fonctionne de manière similaire aux marges, avec une différence très importante: ni les éléments environnants ni l’élément parent ne sont affectés par les valeurs top et left. Tout les autres éléments de .item-relative est rendu rend comme s’il était dans sa position d’origine. C’est comme si le déplacement de la boite était appliqué après que le navigateur ait terminé la mise en page.

Les propriétés top et left se mesurent à partir des bords supérieur et gauche de la boîte d’origine, respectivement. Nous pouvons décaler la boîte par rapport aux autres bords avec les propriétés bottom et right.

Par exemple, ce qui suit va pousser la boîte dans la direction opposée:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 1200px;
}

.container {
  display: flex;
  justify-content: center;
}

.example {
  display: flex;
  justify-content: space-around;
  
  width: 800px;
  margin: 50px 0;
  background-color: #D6E9FE;
}

.item img {
  display: block;
}

.item-relative {
  position: relative;
  top: 30px;
  right: 30px;
}
CSS

Notez que ces propriétés acceptent les valeurs négatives, ce qui signifie qu’il y a deux façons de spécifier le même décalage. Nous pourrions tout aussi bien utiliser top:-30px; à la place de la bottom: 30px;.

Positionnement absolu

Le « positionnement absolu » est exactement comme le positionnement relatif, sauf que le décalage est relatif à la totalité de la fenêtre du navigateur au lieu de la position d’origine de l’élément. Comme il n’y a plus de relation avec le flux statique de la page, considérez ceci comme le moyen le plus manuel de mettre en place un élément.

Jetons un coup d’oeil en ajoutant la règle suivante à notre feuille de style:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 1200px;
}

.container {
  display: flex;
  justify-content: center;
}

.example {
  display: flex;
  justify-content: space-around;
  
  width: 800px;
  margin: 50px 0;
  background-color: #D6E9FE;
}

.item img {
  display: block;
}

.item-relative {
  position: relative;
  top: 30px;
  right: 30px;
}

.item-absolute {
  position: absolute;
  top: 10px;
  left: 10px;
}
CSS

Notre structure HTML est exactement la même que l’exemple précédent, mais cela colle l’image violette dans le coin supérieur gauche de la fenêtre du navigateur. Vous pouvez également essayer de définir une valeur bottom ou right pour avoir une idée plus claire de ce qui se passe.

L’autre effet intéressant de absolute est qu’il supprime complètement un élément du flux normal de la page. Ceci est plus facile à voir avec les éléments alignés à gauche, alors changeons temporairement la propriété justify-content de notre classe .example:

.example {
  display: flex;
  justify-content: flex-start;  /* Update this */
  /* ... */
}
CSS

Dans notre exemple de positionnement relatif (la première rangée), il y a toujours un espace où l’élément positionné était, mais avec un positionnement absolu, cet espace a disparu. C’est comme si .item-absolute n’existait pas pour ses parents et pour ses éléments environnants. Assurez-vous de changer le justify-content en space-around avant de continuer.

Ce comportement n’est pas vraiment utile la plupart du temps, car cela voudrait dire que tout ce qui se trouve sur votre page doit être positionné de manière absolue. Sinon, nous obtiendrions des chevauchements imprévisibles d’éléments statiques avec des éléments absolus. Alors, pourquoi la propriété absolute existe-t-elle ?

Positionnement absolu (relativement)

Le positionnement absolu devient beaucoup plus pratique lorsqu’il est relatif à un autre élément qui se trouve dans le flux statique de la page. Heureusement, il existe un moyen de changer le système de coordonnées d’un élément positionné de manière absolue.

Les coordonnées des éléments absolus sont toujours relatives au conteneur le plus proche qui est un élément positionné. Il ne retombe sur le navigateur que lorsque aucun de ses ancêtres n’est positionné. Donc, si nous modifions l’élément parent de .item-absolute pour qu’il soit relativement positionné, il devrait apparaître dans le coin supérieur gauche de cet élément plutôt que dans la fenêtre du navigateur.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 1200px;
}

.container {
  display: flex;
  justify-content: center;
}

.example {
  display: flex;
  justify-content: space-around;
  
  width: 800px;
  margin: 50px 0;
  background-color: #D6E9FE;
}

.item img {
  display: block;
}

.item-relative {
  position: relative;
  top: 30px;
  right: 30px;
}

.absolute {
  position: relative;
}

.item-absolute {
  position: absolute;
  top: 10px;
  left: 10px;
}
CSS

La div .absolute est disposé dans le flux normal de la page, et nous pouvons déplacer manuellement .item-absolute partout où nous en avons besoin. C’est parfait, car si nous voulons modifier le flux normal du conteneur, par exemple, pour une mise en page mobile, tout élément positionné de manière absolu se déplacera automatiquement avec lui.

Remarquez comment nous n’avons pas spécifié de coordonnées de décalage pour .absolute. Nous utilisons un positionnement relatif dans le seul but de permettre à notre élément absolu de revenir dans le flux normal de la page. C’est ainsi que nous combinons en toute sécurité un positionnement absolu avec un positionnement statique.

Positionnement fixe

Le « positionnement fixe » a beaucoup de chose en commun avec le positionnement absolu: il est très manuel, l’élément est supprimé du flux normal de la page et le système de coordonnées est relatif à l’ensemble de la fenêtre du navigateur. La principale différence est que les éléments fixes ne défilent pas avec le reste de la page.

Allez-y et mettez à jour notre troisième exemple pour utiliser le positionnement fixe:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 1200px;
}

.container {
  display: flex;
  justify-content: center;
}

.example {
  display: flex;
  justify-content: space-around;
  
  width: 800px;
  margin: 50px 0;
  background-color: #D6E9FE;
}

.item img {
  display: block;
}

.item-relative {
  position: relative;
  top: 30px;
  right: 30px;
}

.absolute {
  position: relative;
}

.item-absolute {
  position: absolute;
  top: 10px;
  left: 10px;
}

.item-fixed {
  position: fixed;
  bottom: 0;
  right: 0;
}
CSS

Cela placera l’image rouge dans le coin inférieur droit de l’écran. Essayez de faire défiler la page, et vous découvrirez qu’elle ne bouge pas avec le reste des éléments de la page, alors que l’image pourpre qui est positionnée de manière absolue le fait.

Cela vous permet de créer des barres de navigation qui restent toujours à l’écran, ainsi que ces bannières pop-up ennuyeuses qui ne disparaissent jamais.

Éléments positionnés pour l’animation

Ceci dépasse un peu la portée de ce cours, car ce cours traite du HTML et du CSS, pas du JavaScript. Cependant, l’animation est l’un des principaux cas d’utilisation du le positionnement relatif et absolu, alors jetons un coup d’oeil et animons un de nos éléments.

Ces schémas de positionnement avancés permettent à JavaScript de déplacer des éléments tout en évitant tout type d’interaction avec les éléments environnants. Par exemple, essayez de copier-coller ce qui suit dans schemes.html après le troisième élément .container. L’élément <script> devrait être le dernier chose à l’intérieur de <body>.

<script>
  var left = 0;

  function frame() {
    var element = document.querySelector('.item-relative');
    left += 2;
    element.style.left = left + 'px';
    if (left >= 300) {
      clearInterval(id)
    }
  }

  var id = setInterval(frame, 10)
</script>
JavaScript

Ce code JavaScript crée une animation simple qui met continuellement à jour la propriété left de .item-relative. Lorsque vous rechargez la page, vous devriez voir l’image bleue flotter sur le bord droit de son conteneur.

C’est un exemple assez rudimentaire, mais vous pouvez voir comment il est applicable aux animations de l’interface utilisateur. Si vous tentiez d’obtenir le même effet en manipulant les propriétés margin ou padding, vous déplaceriez par inadvertance les boîtes statiquement positionnées et / ou l’élément .example.

Éléments positionnés pour les menus

Nous avons fait le tour de toutes ces techniques de positionnement. Essayons de faire quelque chose de concret avec elles ! Dans le reste de ce chapitre nous allons appliquer nos nouvelles compétences pour fabriquer un menu de navigation sophistiqué avec une liste déroulante interactive pour l’un de ses liens. Nous allons construire cette page entièrement à partir de zéro.

Le positionnement fixe nous permettra de faire en sorte que le menu reste en haut de la page, et le positionnement relatif nous donnera une ancre pour la liste déroulante positionnée de manière absolue. Nous aurons également l’occasion de parler des meilleures pratiques pour la fabrication de menu de navigation et de voir des applications pratiques des pseudo-classes dont nous avons parlé dans le chapitre sur les selecteur CSS.

Pour commencer, nous avons besoin d’une nouvelle page web appelée menu.html qui a un en-tête et un simple menu

<!DOCTYPE html>
<html lang='en'>
  <head>
    <meta charset='UTF-8'/>
    <title>Awesome!</title>
    <link href='menu.css' rel='stylesheet'/>
  </head>
  <body>

    <div class='header'>
      <div class='logo'><img src='images/awesome-logo.svg'/></div>
      <ul class='menu'>
        <li class='dropdown'><span>Features ▾</span></li>
        <li><a href='#'>Blog</a></li>
        <li><a href='#'>Subscribe</a></li>
        <li><a href='#'>About</a></li>
      </ul>
    </div>

  </body>
</html>
HTML

Les menus de navigation devraient presque toujours être codés comme une liste <ul> au lieu d’un groupe d’éléments <div>. Ce code sémantique rend la navigation de votre site beaucoup plus accessible aux moteurs de recherche. Notez également comment nous préparons pour notre menu déroulant en ajoutant un attribut class au premier <li> de la liste. La balise <span> nous permettra de différencier le menu du sous-menu qu’elle révèle.

Ensuite, nous avons besoin d’une nouvelle feuille de style appelée menu.css qui rend notre .header un peu plus comme une en-tête:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 1200px;
  font-size: 18px;
  font-family: sans-serif;
  color: #5D6063;
}

a:link,
a:visited {
  color: #5D6063;
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

.header {
  position: fixed;
  display: flex;
  justify-content: space-between;
  
  width: 100%;
  padding: 50px;
  background: #D6E9FE;
}
CSS

Tout cela devrait vous être familier, notez la position fixed de notre .header, qui maintient notre menu de navigation au-dessus de tout contenu dans la page.

Éléments de menu en ligne

En dépit d’être codé comme des listes non ordonnées, la plupart des menus de navigation ne ressemblent pas réellement à une liste. Nous pouvons résoudre ce problème en rendant les éléments de la liste des éléments en ligne au lieu de blocs par l’intermédiaire de la propriété display. Ajouter ce qui suit à menu.css:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 1200px;
  font-size: 18px;
  font-family: sans-serif;
  color: #5D6063;
}

a:link,
a:visited {
  color: #5D6063;
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

.header {
  position: fixed;
  display: flex;
  justify-content: space-between;
  
  width: 100%;
  padding: 50px;
  background: #D6E9FE;
}

.menu {
  margin-top: 15px;
}

.menu > li {
  display: inline;
  margin-right: 50px;
}

.menu > li:last-of-type {
  margin-right: 0;
}
CSS

Nous devons utiliser des sélecteurs d’enfant ici à la place des sélecteurs descendants parce que nous voulons seulement sélectionner les éléments <li> qui sont directement dans le .menu. Cela deviendra important une fois que nous aurons ajouté notre sous-menu, qui a ses propres éléments <li> que nous ne voulons pas modifier avec cette règle. Cet extrait ajoute également des marges à tous les éléments de la liste, mais les suppriment du dernier <li> en utilisant la pseudo-classe :last-of-type. C’est une technique assez courante pour créer des marges entre les éléments.

Sous-menus

Notre sous-menu va ressembler au menu de niveau supérieur, sauf qu’il sera imbriqué dans un élément de liste. Modifiez l’élément .menu pour qu’il corresponde à ce qui suit, en s’assurant que toute la liste .features-menu est enveloppée dans le premier <li> de l’élément .menu.

<!DOCTYPE html>
<html lang='en'>
  <head>
    <meta charset='UTF-8'/>
    <title>Awesome!</title>
    <link href='menu.css' rel='stylesheet'/>
  </head>
  <body>

    <div class='header'>
      <div class='logo'><img src='images/awesome-logo.svg'/></div>
      <ul class='menu'>
        <li class='dropdown'><span>Features ▾</span>
          <ul class='features-menu'>           
            <li><a href='#'>Harder</a></li>
            <li><a href='#'>Better</a></li>
            <li><a href='#'>Faster</a></li>
            <li><a href='#'>Stronger</a></li>
          </ul>  
        </li>
        <li><a href='#'>Blog</a></li>
        <li><a href='#'>Subscribe</a></li>
        <li><a href='#'>About</a></li>
      </ul>
    </div>

  </body>
</html>
HTML

Cela fournit beaucoup d’informations cruciales pour les moteurs de recherche. Cela permet à Google de voir que tous ces nouveaux éléments sont associés à l’ étiquette Features et qu’ils forment une section isolée de notre site Web. Vous devez toujours coder des menus de navigation complexes avec ce type de structure.

En ce qui concerne le CSS, nous traiterons plus tard de la partie interactive de la liste déroulante. Pour l’instant, il suffit de styliser notre sous-menu comme nous le voulons. Ajoutez quelques styles simples afin que nous puissions voir la boîte que nous essayons de positionner:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 1200px;
  font-size: 18px;
  font-family: sans-serif;
  color: #5D6063;
}

a:link,
a:visited {
  color: #5D6063;
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

.header {
  position: fixed;
  display: flex;
  justify-content: space-between;
  
  width: 100%;
  padding: 50px;
  background: #D6E9FE;
}

.menu {
  margin-top: 15px;
}

.menu > li {
  display: inline;
  margin-right: 50px;
}

.menu > li:last-of-type {
  margin-right: 0;
}

.features-menu {
  display: flex;
  flex-direction: column;
  background: #B2D6FF;
  border-radius: 5px;
  padding-top: 60px;
}

.features-menu li {
  list-style: none;
  border-bottom: 1px solid #FFF;

  padding: 0 40px 10px 20px;
  margin: 10px;
}

.features-menu li:last-of-type {
  border-bottom: none;
}
CSS

Le sous-menu lui-même est stylisé correctement, mais il apparaît au mauvais endroit et perturbe le positionnement du reste de nos éléments de menu. On pouvait s’y attendre car il est toujours positionné de manière statique, ce qui signifie qu’il interagit toujours avec ses parents et les éléments environnants.

Pour créer la mise en page souhaitée, nous devons faire appel à nos nouvelles compétences en matière de positionnement CSS..

Sous-menus absolus (relativement)

Nous voulons que nos autres éléments de menu de niveau supérieur s’affichent comme auparavant, comme si le sous-menu n’était même pas là. Attendez une seconde … c’est le comportement exact des éléments positionnés de manière absolume. Ajoutez ces quelques lignes à la règle .features-menu:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 1200px;
  font-size: 18px;
  font-family: sans-serif;
  color: #5D6063;
}

a:link,
a:visited {
  color: #5D6063;
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

.header {
  position: fixed;
  display: flex;
  justify-content: space-between;
  
  width: 100%;
  padding: 50px;
  background: #D6E9FE;
}

.menu {
  margin-top: 15px;
}

.menu > li {
  display: inline;
  margin-right: 50px;
}

.menu > li:last-of-type {
  margin-right: 0;
}

.features-menu {
  display: flex;
  flex-direction: column;
  background: #B2D6FF;
  border-radius: 5px;
  padding-top: 60px;
  position: absolute;      
  top: -25px;
  left: -30px;
}

.features-menu li {
  list-style: none;
  border-bottom: 1px solid #FFF;

  padding: 0 40px 10px 20px;
  margin: 10px;
}

.features-menu li:last-of-type {
  border-bottom: none;
}
CSS

Génial! Le sous-menu ne fait plus partie du flux statique de la page, donc nos éléments de menu de niveau supérieur sont de retour à la normale. Cependant, le sous-menu doit apparaître sous l’ étiquette Features (Pas dans le coin de la fenêtre du navigateur). Quelle coïncidence … nous venons d’apprendre comment le faire!

Le sous-menu est situé dans <li class='dropdown'>. Il faut le transformer en un élément positionné pour changer le système de coordonnées utilisé par notre position absolue:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 1200px;
  font-size: 18px;
  font-family: sans-serif;
  color: #5D6063;
}

a:link,
a:visited {
  color: #5D6063;
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

.header {
  position: fixed;
  display: flex;
  justify-content: space-between;
  
  width: 100%;
  padding: 50px;
  background: #D6E9FE;
}

.menu {
  margin-top: 15px;
}

.menu > li {
  display: inline;
  margin-right: 50px;
}

.menu > li:last-of-type {
  margin-right: 0;
}

.features-menu {
  display: flex;
  flex-direction: column;
  background: #B2D6FF;
  border-radius: 5px;
  padding-top: 60px;
  position: absolute;      
  top: -25px;
  left: -30px;
}

.features-menu li {
  list-style: none;
  border-bottom: 1px solid #FFF;

  padding: 0 40px 10px 20px;
  margin: 10px;
}

.features-menu li:last-of-type {
  border-bottom: none;
}

.dropdown {
  position: relative;
}
CSS

Ok, prochain problème. Notre sous-menu est au bon endroit, mais maintenant il couvre l’ étiquette Features.

z-index

Nous n’avons jamais eu à traiter de problèmes de profondeur avant. Jusqu’à présent, tous nos éléments HTML sont affichés au-dessus ou au-dessous de manière intuitive. Mais, puisque nous faisons des choses avancées, nous allons nous appuyer sur le navigateur pour déterminer quels éléments apparaissent au-dessus des autres.

La propriété z-index vous permet de contrôler la profondeur des éléments sur la page. Si vous considérez votre écran comme un espace 3D, les valeurs négatives z-index vont plus profond dans la page et les valeurs positives sortent de la page.

En d’autres termes, l’élément .features-menu doit avoir une valeur z-index inférieure à l’ étiquette Features. La valeur z-index par défaut est 0, alors réglons la valeur des deux élément sur un chiffre plus élevés que cela. Nous avons enveloppé l’étiquette Features dans un <span>, ce qui nous permet de le styliser via un sélecteur enfant, comme ceci:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 1200px;
  font-size: 18px;
  font-family: sans-serif;
  color: #5D6063;
}

a:link,
a:visited {
  color: #5D6063;
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

.header {
  position: fixed;
  display: flex;
  justify-content: space-between;
  
  width: 100%;
  padding: 50px;
  background: #D6E9FE;
}

.menu {
  margin-top: 15px;
}

.menu > li {
  display: inline;
  margin-right: 50px;
}

.menu > li:last-of-type {
  margin-right: 0;
}

.features-menu {
  display: flex;
  flex-direction: column;
  background: #B2D6FF;
  border-radius: 5px;
  padding-top: 60px;
  position: absolute;      
  top: -25px;
  left: -30px;
  z-index: 1;
}

.features-menu li {
  list-style: none;
  border-bottom: 1px solid #FFF;

  padding: 0 40px 10px 20px;
  margin: 10px;
}

.features-menu li:last-of-type {
  border-bottom: none;
}

.dropdown {
  position: relative;
}

.dropdown > span {
  z-index: 2;
  position: relative;  /* This is important! */
  cursor: pointer;
}
CSS

L’ étiquette Features devrait maintenant apparaître au dessus du sous-menu. Prenez note de cette la ligne position: relative;. Elle est nécessaire car seuls les éléments positionnés font attention à leur propriété z-index. C’est facile à oublier, alors faites une note mentale pour la prochaine fois que vous rencontrez des problèmes de profondeur et que vos règles CSS ne semblent pas avoir d’effet.

Pseudo-classes pour les menus déroulants

Ok! Sous-menu terminé! Notre dernière tâche est de le cacher jusqu’à ce que l’utilisateur le survole. Rappelez-vous de la pseudo-classe :hover du chapitre Selecteur CSS ? Nous pouvons utiliser cela pour transformer notre sous-menu en une liste déroulante interactive.

Tout d’abord, nous devons modifier notre règle .features-menu pour afficher uniquement le sous-menu lorsque l’utilisateur survole en ajoutant un sélecteur descendant :hover. Mettez à jour le sélecteur code>.features-menu pour qu’il corresponde à ce qui suit:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 1200px;
  font-size: 18px;
  font-family: sans-serif;
  color: #5D6063;
}

a:link,
a:visited {
  color: #5D6063;
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

.header {
  position: fixed;
  display: flex;
  justify-content: space-between;
  
  width: 100%;
  padding: 50px;
  background: #D6E9FE;
}

.menu {
  margin-top: 15px;
}

.menu > li {
  display: inline;
  margin-right: 50px;
}

.menu > li:last-of-type {
  margin-right: 0;
}

.dropdown:hover .features-menu {
  display: flex;
  flex-direction: column;
  background: #B2D6FF;
  border-radius: 5px;
  padding-top: 60px;
  position: absolute;      
  top: -25px;
  left: -30px;
  z-index: 1;
}

.features-menu li {
  list-style: none;
  border-bottom: 1px solid #FFF;

  padding: 0 40px 10px 20px;
  margin: 10px;
}

.features-menu li:last-of-type {
  border-bottom: none;
}

.dropdown {
  position: relative;
}

.dropdown > span {
  z-index: 2;
  position: relative;  /* This is important! */
  cursor: pointer;
}
CSS

Ensuite, nous devons d’abord masquer le sous-menu en utilisant la propriété display. Ajouter une nouvelle règle à menu.css:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  height: 1200px;
  font-size: 18px;
  font-family: sans-serif;
  color: #5D6063;
}

a:link,
a:visited {
  color: #5D6063;
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

.header {
  position: fixed;
  display: flex;
  justify-content: space-between;
  
  width: 100%;
  padding: 50px;
  background: #D6E9FE;
}

.menu {
  margin-top: 15px;
}

.menu > li {
  display: inline;
  margin-right: 50px;
}

.menu > li:last-of-type {
  margin-right: 0;
}

.dropdown:hover .features-menu {
  display: flex;
  flex-direction: column;
  background: #B2D6FF;
  border-radius: 5px;
  padding-top: 60px;
  position: absolute;      
  top: -25px;
  left: -30px;
  z-index: 1;
}

.features-menu { 
  display: none;
}

.features-menu li {
  list-style: none;
  border-bottom: 1px solid #FFF;

  padding: 0 40px 10px 20px;
  margin: 10px;
}

.features-menu li:last-of-type {
  border-bottom: none;
}

.dropdown {
  position: relative;
}

.dropdown > span {
  z-index: 2;
  position: relative;  /* This is important! */
  cursor: pointer;
}
CSS

Régler la propriété display sur none pour faire disparaitre complètement un élément. En outrepassant cette valeur avec flex dans la règle :hover, nous demandons au navigateur de montrer .features-menu à nouveau. Cette combinaison intelligente de sélecteurs descendants et de pseudo-classes nous permet de masquer ou de montrer conditionnellement un élément.

Résumé

Dans ce chapitre, nous avons examiné quatre nouveaux schémas de disposition CSS:

  • Relatif
  • Absolu
  • Relativement absolu
  • Fixe

Le positionnement relatif consistait à ajuster la position d’un élément sans affecter ses boîtes environnantes. Le positionnement absolu a pris des éléments hors du flux statique de la page et les a placés par rapport à la fenêtre du navigateur, alors qu’un positionnement relativement absolu nous a permis de nous raccrocher au flux statique de la page. Enfin, le positionnement fixe permet créer des éléments qui ne défilent pas avec le reste de la page.

Nous avons utilisé ces nouvelles techniques de positionnement pour créer un menu de navigation plutôt sophistiqué. Si cela vous est apparu compliqué, c’est parce que c’était le cas. Mais ne vous inquiétez pas, vous n’avez pas besoin de mémoriser le code HTML et CSS derrière notre menu. Votre objectif est de comprendre à quoi servent ces différentes formes de positionnement.

Ce menu était également un très bon exemple de la façon dont le fait de commencer avec le balisage HTML rend la vie beaucoup plus facile. Tout d’abord, nous avons créé la structure sémantique que nous voulions. Ensuite , nous avons écrit du code CSS pour positionner les boîtes là où nous les voulions.

Il y a toujours un gros problème avec notre menu: il n’est pas conçu pour les appareils mobiles. Les smartphones et les tablettes n’ont pas de moyen de survoler et notre présentation ne s’affiche pas bien lorsque le navigateur est plus étroit que 960 pixels.

error: Content is protected !!