Cette traduction est en cours.

Le positionnement permet de sortir les éléments en dehors du flux classique de mise en page du document, et de les faire se comporter différemment, par exemple de se positionner tout en haut d'un autre, ou de toujours se maintenir à la même position à l'intérieur d'une fenêtre d'affichage (viewport) d'un navigateur. Cet article explique les différentes valeurs de position, et comment les utiliser.

Prérequis: Les fondamentaux du HTML (étudiez Introduction au HTML), et une idée du fonctionnement de CSS (étudiez Introduction à CSS.)
Objectif: Apprendre le fonctionnement du positionnement en CSS.

Le flux du document

Le positionnement est un sujet plutôt complexe, avant de plonger dans le code réexaminons et développons un peu la théorie de la disposition pour nous donner une idée de son fonctionnement.

Premièrement, les boîtes en tant qu'élément individuel sont agencées en prenant le contenu de l'élément, puis en ajoutant la marge intérieure, la bordure et la marge extérieure autour — c'est ce modèle de boîte à nouveau, que nous regardions plus tôt. Par défaut, le contenu d'un élément de type bloc (block) fait 100% de la largeur de son élément parent, et est aussi grand que son contenu peut l'être. Les éléments de type en ligne (inline) sont aussi grands que leur contenu, et aussi larges que leur contenu. Vous ne pouvez pas définir de largeur ou de hauteur sur un élément de type en ligne — ils se positionnent seulement à l'intérieur du contenu d'un élément de type bloc. Si vous voulez contrôler la taille d'un élément de type en ligne, vous devez le définir comme se comportant comme un élément de type bloc avec display: block;.

Ceci explique les éléments individuellement, mais qu'en est-il de la manière dont les éléments interagissent entre-eux? Le flux de disposition classique (mentionné dans l'article d'introduction de la mise en page) est le système par lequel les éléments sont placés à l'intérieur de la fenêtre d'affichage du navigateur. Par défaut, les éléments de type bloc sont agencés verticalement dans la fenêtre d'affichage — chacun d'eux apparaîtra sur une nouvelle ligne en-dessous de celui qui le précède, et ils seront séparés par n'importe quelles marges extérieures définies sur eux.

Les éléments de type en ligne se comportent différemment — ils n'apparaissent pas sur de nouvelle lignes; à la place, ils restent sur la même ligne que les autres et également de tout contenu de texte adjacent (ou enveloppant), aussi longtemps qu'il y a d'espace à remplir dans la largeur de l'élément parent de type bloc. Si il n'y a pas assez d'espace, alors le surplus de texte ou d'éléments sera déplacer sur une nouvelle ligne.

Si deux éléments adjacents ont des marges extérieures définies et que les deux marges se touchent, la plus épaisse prend le dessus, et la plus petite disparaît — cela s'appelle la fusion des marges (margin collapsing) et nous l'avons déjà rencontrés auparavant.

Regardons un simple exemple qui explique tout ça:

<h1>Basic document flow</h1>

<p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p>

<p>By default we span 100% of the width of our parent element, and we are as tall as our child content. Our total width and height is our content + padding + border width/height.</p>

<p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p>

<p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements will <span>wrap onto a new line if possible (like this one containing text)</span>, or just go on to a new line if not, much like this image will do: <img src="https://mdn.mozillademos.org/files/13360/long.jpg"></p>
body {
  width: 500px;
  margin: 0 auto;
}

p {
  background: aqua;
  border: 3px solid blue;
  padding: 10px;
  margin: 10px;
}

span {
  background: red;
  border: 1px solid black;
}

Nous réadapterons cet exemple un bon nombre de fois au travers de cet article, lorsque nous montrerons les effets des différentes options de positionnement qui nous sont offertes.

Nous aimerions que vous suiviez tout du long  des exercices sur votre propre ordinateur, si possible — prenez une copie de 0_basic-flow.html sur notre dépôt Github ( code source ici) et utilisez le comme point de départ.

Introduction au positionnement

L'idée globale du positionnement est de nous permettre d'outrepasser le comportement du flux de disposition classique décris au-dessus, afin de produire des effets intéresants. Qu'est ce qu'il se passerait si vous vouliez légèrement déplacer la position de quelques boîtes à l'intérieur d'une mise en page de leurs positions par défaut dans le flux du document, pour donner un peu d'excentricité, de bouleversement? Le positionnement est votre outil. Ou si vous voulez créer un élément d'interface utilisateur qui flotte en haut d'autres parties de la page, et/ou qui reste à la même place à l'intérieur de la fenêtre du navigateur peu importe à quel point la page défile? Le positionnement rend de telles agencements possibles.

Il y a de nombreux types différents de positionnement dont vous pouvez profiter sur les éléments HTML. Pour rendre effectif un type en particulier de positionnement sur un élément, nous utilisons la propriété position.

Le positionnement statique

Le positionnement static est celui par défaut que chaque élément reçoit — cela veut tout simplement dire "place l'élément dans sa position classique dans le flux de disposition du document — rien de spécial à faire ici".

Pour le démontrer, et avoir votre exemple configuré pour les prochaines sections, ajoutez tout d'abord une  class nommée positioned pour le deuxième <p> dans le HTML:

<p class="positioned"> ... </p>

Maintenant ajoutez la règle suivante au bas de votre CSS:

.positioned {
  position: static;
  background: yellow;
}

Si maintenant vous sauvegardez et actualisez, vous verrez qu'il n'y a pas de différence du tout, à l'exception de la mise à jour de la couleur de l'arrière-plan du deuxième paragraphe. C'est très bien — comme nous l'avons dit plus tôt, le positionnement statique est le comportement par défaut!

Remarque: Vous pouvez voir un exemple à ce stade de l'article sur ce lien 1_static-positioning.html (voir le code source).

Le positionnement relatif

Le positionnement relatif est la premier type de positionnement que nous allons voir. C'est très similaire au positionnement statique, à l'exception qu'un fois l'élément positionné occupe sa place dans le flux de disposition classique du document, vous pouvez modifier sa position finale, incluant la posibilité de chevaucher d'autres éléments de la page. Faites le et mettez à jour la déclaration de la position dans votre code:

position: relative;

Si vous sauvegardez et actualisez à ce moment, vous ne verrez pas du tout de changement — alors comment modifier la position de l'élément? Vous avez besoin des propriétés top, bottom, left, et right, que nous expliquerons dans la prochaine section.

Présentation de top, bottom, left, et right

top, bottom, left, et right sont utilisés au côté de position pour spécifier exactement comment déplacer l'élément positionné. Pour l'essayer, ajouter les déclarations suivantes à la règle .positioned dans votre CSS:

top: 30px;
left: 30px;

Remarque: Les valeurs de ces propriétés peuvent prendre n'importe laquelle des unités sur lesquelles vous espériez compter — les pixels, les mm, les rem, les %, et ainsi de suite.

Si maintenant vous sauvegardez et actualisez, vous verrez un résultat à peu près comme celui-ci:

Sympa, hein? Ok, ce n'était probablement pas ce que vous espériez — pourquoi est-ce que le déplacement s'est effectué vers le bas et à droite si nous avons spécifié en haut et à gauche? À l'entendre comme ça, ça peut paraître illogique, c'est seulement la manière dont fonctionne le positionnement relatif — vous devez penser à une force invisible qui pousse le coté de l'élément positionné, le déplaçant dans la direction opposé. Pour exemple, si nous spécifions top: 30px;, une force pousse le haut de la boîte, entraînant son déplacement vers le bas de 30px.

Remarque: Vous pouvez voir un exemple à ce stade de l'article sur ce lien 2_relative-positioning.html (voir le code source).

Le positionnement absolu

Le positionnement absolu nous apporte des résultats bien différents. Essayons de changer la déclaration de la position dans votre code comme ce qui suit:

position: absolute;

Si maintenant vous sauvegardez et actualisez, vous devriez voir quelque chose comme ceci:

En premier lieu, remarquez que l'intervalle où l'élément positionné devrait se trouver dans le flux du document ne s'y trouve plus — le premier et le troisième élément sont tous les deux à proximité comme si il n'existait plus! Hé bien, dans un sens, c'est exact. Un élément positionné en absolu ne fait plus partie du flux de disposition classique du document. À la place, il se trouve sur sa propre couche séparé de tout le reste. C'est très utile! — cela signifie que nous pouvons créer une fonctionnalité d'interface graphique isolée qui n'interfère pas avec la position d'autres éléments sur la page — par exemple des boîtes d'informations contextuelles (popup) et des menus de contrôles, des panneaux roulants (rollover panels), des fonctionnalités d'interface utilisateur qui peuvent se glisser/déposer n'importe où sur la page, et bien plus encore.

Ensuite, observez que la position de l'élément a changée — c'est parce que top, bottom, left, et right se comportent diféremment avec le positionnement absolu. À la place d'indiquer la direction dans laquelle l'élement doit se déplacer, ils spécifient la distance que l'élément doit avoir par rapport aux côtés de l'élément contenant. Donc, dans ce cas, nous sommes en train de dire que l'élément absolu positionné devrait se trouver à 30px du haut de "l'élément contenant", et à 30px côté gauche.

Remarque: Vous pouvez utiliser top, bottom, left, et right pour redimensionner les éléments selon vos besoins. Essayez de définir top: 0; bottom: 0; left: 0; right: 0; et margin: 0; sur vos éléments positionnés et voyez ce qu'il se produit! Remettez tout à l'ordre initial ensuite...

Remarque: Oui, les marges affectent toujours les éléments positionnés. Toutefois, la fusion de marges ne le fait pas.

Remarque: Vous pouvez voir un exemple à ce stade de l'article sur ce lien 3_absolute-positioning.html (voir le code source).

Les contextes de positionnement

Quel élément est "l'élément contenant" d'un élément positionné en absolu? Par défaut, est-ce que c'est l'élément <html> — l'élément positionné est imbriqué dans le <body> dans le code source HTML, mais dans le rendu final, c'est 30px éloigné du haut et de la gauche du bord de la page, qui n'est autre que l'élément <html>. Cela s'appelle plus précisément le contexte de positionnement d'élément.

Nous pouvons changer ce contexte de positionnement — par rapport à quel élément est positionné l'élément positionné en absolu. Cela s'effectue en définissant le positionnement sur un des autres éléments ancêtres — un des éléments où il est imbriqué (vous ne pouvez pas le positionné relativement à un élément où il n'est pas imbriqué). Pour l'illustrer, ajoutez la déclaration suivante à vos règles du body:

position: relative;

Cela devrait donner le résultat suivant:

À présent lélément positionné se tient relativement à l'élément <body>.

Remarque: Vous pouvez voir cet exemple à ce stade à 4_positioning-context.html (voir le code source).

Présentation du z-index

Tout ce positionnement en absolu est un bon amusement, mais il y a autre chose que nous n'avons pas encore considéré — quand les éléments commencent à en chevaucher d'autres, qu'est-ce qui détermine quel élément apparaît au-dessus d'un autre? Dans l'exemple que nous avons vus jusqu'à présent, nous avons eu un seul élément positionné dans le contexte de positionnement, et il apparaît tout en haut, car les éléments positionnés l'emportent sur les élémentd non positionnés. Qu'est-ce qu'il en est lorsqu'il y en a plus d'un?

Essayez d'ajouter le code suivant à votre CSS, pour rendre l'le premier paragraphe en positionnement absolu également:

p:nth-of-type(1) {
  position: absolute;
  background: lime;
  top: 10px;
  right: 30px;
}

At this point you'll see the first paragraph colored green, moved out of the document flow, and positioned a bit above from where it originally was. It is also stacked below the original .positioned paragraph, where the two overlap. This is because the .positioned paragraph is the second paragraph in the source order, and positioned elements later in the source order win over positioned elements earlier in the source order.

Can you change the stacking order? Yes, you can, by using the z-index property. "z-index" is a reference to the z-axis. You may recall from previous points in the source where we discussed web pages using horizontal (x-axis) and vertical (y-axis) coordinates to work out positioning for things like background images and drop shadow offsets. (0,0) is at the top left of the page (or element), and the x- and y-axes run across to the right and down the page (for left to right languages, anyway.)

Web pages also have a z-axis — an imaginary line that runs from the surface of your screen, towards your face (or whatever else you like to have in front of the screen). z-index values affect where positioned elements sit on that axis — positive values move them higher up the stack, and negative values move them lower down the stack. By default, positioned elements all have a z-index of auto, which is effectively 0.

To change the stacking order, try adding the following declaration to your p:nth-of-type(1) rule:

z-index: 1;

You should now see the finished example:

Note that z-index only accepts unitless index values; you can't specify that you want one element to be 23 pixels up the Z-axis — it doesn't work like that. Higher values will go above lower values, and it is up to you what values you use. Using 2 and 3 would give the same effect as 300 and 40000.

Note: You can see the example at this point live at 5_z-index.html (see source code).

Fixed positioning

There is one more type of positioning to cover — fixed. This works in exactly the same way as absolute positioning, with one key difference — whereas absolute positioning fixes an element in place relative to the <html> element or its nearest positioned ancestor, fixed positioning fixes an element in place relative to the browser viewport itself. This means that you can create useful UI items that are fixed in place, like persisting navigation menus.

Let's put together a simple example to show what we mean. First of all, delete the existing p:nth-of-type(1) and .positioned rules from your CSS.

Now, update the body rule to remove the position: relative; declaration and add a fixed height, like so:

body {
  width: 500px;
  height: 1400px;
  margin: 0 auto;
}

Now we're going to give the <h1> element position: fixed;, and get it to sit at the top center of the viewport. Add the following rule to your CSS:

h1 {
  position: fixed;
  top: 0;
  width: 500px;
  margin: 0 auto;
  background: white;
  padding: 10px;
}

The top: 0; is required to make it stick to the top of the screen; we then give the heading the same width as the content column and use the faithful old margin: 0 auto; trick to center it. We then give it a white background and some padding, so the content won't be visible underneath it.

If you save and refresh now, you'll see a fun little effect whereby the heading stays fixed, and the content appears to scroll up and disappear underneath it. But we could improve this more — at the moment some of the content starts off underneath the heading. This is because the positioned heading no longer appears in the document flow, so the rest of the content moves up to the top. We need to move it all down a bit; we can do this by setting some top margin on the first paragraph. Add this now:

p:nth-of-type(1) {
  margin-top: 60px;
}

You should now see the finished example:

Note: You can see the example at this point live at 6_fixed-positioning.html (see source code).

Experimental: position sticky

There is a new positioning value available called position: sticky, support for which is not very widespread yet. This is basically a hybrid between relative and fixed position, which allows a positioned element to act like it is relatively positioned until it is scrolled to a certain threshold point (e.g. 10px from the top of the viewport), after which it becomes fixed.  See our position: sticky reference entry for more details and an example.

Résumé

I'm sure you had fun playing with basic positioning — it is one of the essential tools behind creating complex CSS layouts and UI features. With that in mind, in the next article we'll have even more fun with positioning — there we'll go a step further and start to build up some real world useful things with it.

 

Dans ce module

 

Étiquettes et contributeurs liés au document

Contributeurs à cette page : Alan_Braut
Dernière mise à jour par : Alan_Braut,