Positionnement et mise en page
Olivier Pons
(pons@cnam.fr)
2022
Problème : obtenir une mise en page complexe
Au départ, la mise en page de base est une composition de boîtes de la largeur de l'écran.
Empilement des boites en question
<body>
<div style="background-color: lightgray">
<h2 style="background-color: red">Titre</h2>
<p style="background-color: red">
Paragraphe 1 Paragraphe 1 Paragraphe 1 Paragraphe 1
</p>
<p style="background-color: red">
Paragraphe 2 Paragraphe 12
Paragraphe 2 Paragraphe 2 Paragraphe 2
</p>
<ul style="background-color: red"><li>liste ...</li><li>liste...</li></ul>
</div>
</div>
</body>
Paragraphe 1 Paragraphe 1 Paragraphe 1 Paragraphe 1
Paragraphe 2 Paragraphe 12 Paragraphe 2 Paragraphe 2 Paragraphe 2
La propriété display définie l'affichage et influencera les mécanismes de positionnement
Permet essentiellement de fixer si l'élément se conduit comme un bloc (block) , s'insère au fil du texte (inligne) , ou suis le nouveau modèle de boite flexible ou de grille.
nombreuses autres valeurs (éléments de tableaux, etc).
On rappel que par default
p,h1,...h6, ul,ol, dl, li, dl,dd, table …
sont de type
block
a, em, strong, img ...
sont de type inline
Mais on peut le modifier, par exemple, si on ajoute la propriété CSS
l'exemple précédent devient:
<body>
<div style="background-color: lightgray">
<h2 style="background-color: red">Titre</h2>
<p style="background-color: red">
Paragraphe 1 Paragraphe 1 Paragraphe 1 Paragraphe 1
</p>
<p style="background-color: red">
Paragraphe 2 Paragraphe 12
Paragraphe 2 Paragraphe 2 Paragraphe 2
</p>
<ul style="background-color: red"><li>liste ...</li><li>liste...</li></ul>
</div>
</div>
</body>
Paragraphe 1 Paragraphe 1 Paragraphe 1 Paragraphe 1
Paragraphe 2 Paragraphe 12 Paragraphe 2 Paragraphe 2 Paragraphe 2
display:none
masque l'élément et le retire du flux d'affichage de la page (mais pas
de l'arbre DOM).par exemple si on ajoute la propriété css
L'exemple précèdent devient (le paragraphe 1 est masqué)
<div style="background-color: lightgray">
<h2 style="background-color: red">Titre</h2>
<p style="background-color: red">
Paragraphe 1 Paragraphe 1 Paragraphe 1 Paragraphe 1
</p>
<p style="background-color: red">
Paragraphe 2 Paragraphe 12
Paragraphe 2 Paragraphe 2 Paragraphe 2
</p>
<ul style="background-color: red"><li>liste ...</li><li>liste...</li></ul>
</div>
Paragraphe 1 Paragraphe 1 Paragraphe 1 Paragraphe 1
Paragraphe 2 Paragraphe 12 Paragraphe 2 Paragraphe 2 Paragraphe 2
l'élément ne crée pas de nouvelle zone. Il s'insère dans un paragraphe existant. Pas de passage à la ligne.
<p style="background-color: red;">un paragraphe normal (en block)</p>
<p style="display: inline; background-color: red; margin: 3px; ">un paragraphe
en inline</p>
<p style="display: inline; background-color: red;margin: 3px;">un second
paragraphe en inline bla bla bla bla bla bla bla bla bla bla
bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla
bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla
bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla
bla bla bla
</p>
un paragraphe normal (en block)
un paragraphe en inline
un second paragraphe en inline bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla
Notez qu'il n'est pas possible de fixer la taille des éléments
inline
(il faut utiliser block, inline-block, ou float)
On va voir essentiellement 4 façon de positionner des éléments
position
peut prendre différentes valeurs :
Les principales
Il existe deux autres propriétés, fixed et sticky, que nous détaillons pas ici.
Quand le navigateur interprète le code html (et le css) il positionne les éléments.
Le positionnement par défaut de tous les élément est :
position:static
, qui signifie que l'élément n'est pas
explicitement positionné et apparaît là ou il doit normalement
apparaître dans le document.
Normalement vous n'avez pas à le spécifier sauf pour remplacer un positionnement qui a été mis précédemment (avec une autre valeur).
Les éléments de type bloc apparaissent les uns en dessous des
autres dans l'ordre d'apparition dans le code source.
Les éléments de type inline les uns à coté des autres.
position:static
<div id="div-before">
<p>id = div-before</p>
</div>
<div id="div-1">
<div id="div-1-padding">
<p>id = div-1</p>
<div id="div-1a">
<p>id = div-1a</p>
<p>Lorem ipsum dolor sit amet, consectetuer
adipiscing elit. Integer pretium dui sit amet
felis. Integer sit amet diam. Phasellus ultrices
viverra velit.</p>
</div>
<div id="div-1b">
<p>id = div-1b</p>
<p>Lorem ipsum dolor sit amet, consectetuer
adipiscing elit. Integer pretium dui sit amet
felis. Integer sit amet diam. Phasellus ultrices
viverra velit. Nam mattis, arcu ut bibendum
commodo, magna nisi tincidunt tortor, quis
accumsan augue ipsum id lorem.</p>
</div>
<div id="div-1c">
<p>id = div-1c</p>
</div>
</div>
</div><!-- /id=div-1-padding /id=div-1 -->
<div id="div-after">
<p>id = div-after</p>
</div>
id = div-before
id = div-1
id = div-1a
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit.
id = div-1b
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit. Nam mattis, arcu ut bibendum commodo, magna nisi tincidunt tortor, quis accumsan augue ipsum id lorem.
id = div-1c
id = div-after
Si vous spécifiez position:relative, alors vous pouvez utiliser les propriétés: - top - bottom - left - right
pour déplacer les éléments relativement à l'endroit ou ils devraient normalement se trouver dans le document.
Déplaçons div-1
vers le bas de 20 pixels, et vers la
gauche de 40 pixels:
#div-1 {
position:relative;
top:20px;
left:-40px;
}
On positionne d'abord tous les éléments puis on déplace l’élément sans toucher aux autres.
Remarquez que l'espace ou div-1
aurait du être si nous
ne l'avions pas déplacer est maintenant un espace vide. L'élément
suivant (div-after
) ne bouge pas quand nous déplaçons
div-1
. En fait div-1 occupe encore l'espace original dans
le document.
id = div-before
id = div-1
id = div-1a
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit.
id = div-1b
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit. Nam mattis, arcu ut bibendum commodo, magna nisi tincidunt tortor, quis accumsan augue ipsum id lorem.
id = div-1c
id = div-after
Si on spécifie position:absolute, l'élément est
retiré du flux du document
(ce qui change le positionnement des éléments suivants) puis placé à
l'endroit exact ou vous le demandez.
Déplaçons div-1a
dans le coins supérieur droit de la
page:
id = div-before
id = div-1
id = div-1a
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit.
id = div-1b
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit. Nam mattis, arcu ut bibendum commodo, magna nisi tincidunt tortor, quis accumsan augue ipsum id lorem.
id = div-1c
id = div-after
Remarquez que cette fois comme div-1a
est enlevé du
document, les autres éléments de la page sont positionnés différemment
ici div-1b
, div-1c
, et div-after
remontent puisque div-1a
n'est plus là
Remarquez aussi que le fait de positionner les choses de manière
absolues dans la page comme div-1a
en haut à droite n'est
pas toujours suffisant. On aimerait parfois un positionnement de
div-1a
relativement à div-1
.
c'est le retour des positions relatives.
Si on choisi un positionnement relative pour
div-1
(mais sans le déplacer), tout les éléments qu'il
contient seront positionnés relativement à div-1
.
Si on met alors un positionnement absolu sur div-1a
, nous
pouvons le déplacer dans le coin supérieur droit de
dvi-1
:
<style>
#div-1 {
position:relative;
}
#div-1a {
position:absolute;
top:0;
right:0;
width:200px;
}
</style>
id = div-before
id = div-1
id = div-1a
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit.
id = div-1b
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit. Nam mattis, arcu ut bibendum commodo, magna nisi tincidunt tortor, quis accumsan augue ipsum id lorem.
id = div-1c
id = div-after
On montre maintenant comment faire une mise en page sur 2 colonnes en utilisant relative et absolute
<style>
#div-1 {
position:relative;
}
#div-1a {
position:absolute;
top:0;
right:0;
width:200px;
}
#div-1b {
position:absolute;
top:0;
left:0;
width:200px;
}
</style>
id = div-before
id = div-1
id = div-1a
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit.
id = div-1b
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit. Nam mattis, arcu ut bibendum commodo, magna nisi tincidunt tortor, quis accumsan augue ipsum id lorem.
id = div-1c
id = div-after
Un des avantage d'utiliser du positionnement absolu est qu'on peut
positionner les éléments dans n'importe quel ordre sans tenir compte de
l'ordre ou ils apparaissent dans le html. Ici div-1b
est
avant div-1a
.
Mais qu'est il arrivé aux autres éléments ? Il sont remontés et sont donc masqués par le positionnement absolu. Voyons comment éviter cela
Une solution est de mettre une hauteur fixe aux 2 éléments
Mais ce n'est pas une solution viable pour la plupart des développements , car nous ne savons généralement pas quelle quantité de texte il y aura dans l'élément ou les fontes exactes qui seront utilisées.
<style>
#div-1 {
position:relative;
height:250px;
}
#div-1a {
position:absolute;
top:0;
right:0;
width:50%;
}
#div-1b {
position:absolute;
top:0;
left:0;
width:50%;
}
</style>
id = div-before
id = div-1
id = div-1a
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit.
id = div-1b
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit. Nam mattis, arcu ut bibendum commodo, magna nisi tincidunt tortor, quis accumsan augue ipsum id lorem.
id = div-1c
id = div-after
<style>
#tete {
width: 40px;
height: 40px;
border-radius: 20px;
background: pink;
border:solid;
position:relative;
}
.o {
position:absolute;
width: 5px;
height: 5px;
background-color: blue;
border-radius: 20px;
top:10px;
}
#o1 {left:12px;}
#o2 {right:12px;}
#n{
position:absolute;
width: 5px;
height: 10px;
background-color: orange;
top:20px;
left:18.5px
}
#b{
position:absolute;
top:35px;
left:15px;
border-bottom-left-radius: 30px;
border-bottom-right-radius:30px;
border-bottom: 0;
border: 6px solid red;
}
</style>
<div id="tete">
<div id="o1" class="o"></div>
<div id="o2" class="o"></div>
<div id="n"></div>
<div id="b"></div>
</div>
Évidemment ca devient plus fun quand on l'anime avec du js...
Initialement conçue pour "faire flotter" des images dans un bloc de texte
On met l'élément en float:left
ou en
float:right
pour le repousser le plus possible à gauche ou
à droite et permettre au texte de l'enrober. C'est typiquement utiliser
pour les images mais ca marche les autres éléments.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
ou
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
Mais propriété float à été abondamment utilisés pour créer des dispositions sur plusieurs colonnes dans des pages web (aujourd'hui on preferera souvent les flex).
Pour des colonnes de hauteur variable le positionnement absolu ne marche pas nous devons donc utiliser une autre solution.
Si on float
une colonne à gauche puis une autre colonne
à gauche elle vont se coller l'une à l'autre.
id = div-before
id = div-1
id = div-1a
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit.
id = div-1b
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit. Nam mattis, arcu ut bibendum commodo, magna nisi tincidunt tortor, quis accumsan augue ipsum id lorem.
id = div-1c
id = div-after
Après les éléments flottants, on peut nettoyer (clear) le flaot pour que le reste s'affiche.
La propriété clear
peut prendre trois valeurs: -
none
: l'élément sera affiché à côte de l'élément
précédent. - left
: l'élément sera affiché au-dessous de
l'élément précédent si ce dernier est à float:left
-
right
: l'élément sera affiché au-dessous de l'élément
précédent si ce dernier est à float:rigth
. -
both
: l'élément sera affiché au-dessous de l'élément
précédent si ce dernier est à float:left
ou
float:rigth
.
<style>
#div-1a {
float:left;
width:190px;
}
#div-1b {
float:left;
width:190px;
}
#div-1c {
clear:both;
</style>
id = div-before
id = div-1
id = div-1a
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit.
id = div-1b
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer pretium dui sit amet felis. Integer sit amet diam. Phasellus ultrices viverra velit. Nam mattis, arcu ut bibendum commodo, magna nisi tincidunt tortor, quis accumsan augue ipsum id lorem.
id = div-1c
id = div-after
et les grilles (Grid)
font l'objet de lesson séparés:
les flexbox
et le topo specifique aux regles
rarcourcies