Architecture et langages Web (NFA040)

Positionnement et mise en page

Olivier Pons
(pons@cnam.fr)

2022

Positionnement et feuilles de styles

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>

Titre

Paragraphe 1 Paragraphe 1 Paragraphe 1 Paragraphe 1

Paragraphe 2 Paragraphe 12 Paragraphe 2 Paragraphe 2 Paragraphe 2

  • liste ...
  • liste...

La propriété display

La propriété display définie l'affichage et influencera les mécanismes de positionnement

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

li {display:inline}

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>

Titre

Paragraphe 1 Paragraphe 1 Paragraphe 1 Paragraphe 1

Paragraphe 2 Paragraphe 12 Paragraphe 2 Paragraphe 2 Paragraphe 2

  • liste ...
  • liste...

par exemple si on ajoute la propriété css

h2+p {display:none}

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>

Titre

Paragraphe 1 Paragraphe 1 Paragraphe 1 Paragraphe 1

Paragraphe 2 Paragraphe 12 Paragraphe 2 Paragraphe 2 Paragraphe 2

  • liste ...
  • liste...

Principales valeurs de display

inline

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)

block
l'élément est disposé dans un bloc rectangulaire dont on peut fixer la taille.
none
l'élément n'est pas affiché du tout
inline-block
extérieurement inline, peut contenir des blocs.
flex
le contenue suivra le modèle des boites fléxibles
grid
le contenue suivra le modèle de grille

Positionnement CSS

On va voir essentiellement 4 façon de positionner des éléments

  1. via la propriété position
  2. via la propriété float
  3. via les boites flexibles (flexbox)
  4. via les grilles (grid)

La propriété position

position peut prendre différentes valeurs :
Les principales

Il existe deux autres propriétés, fixed et sticky, que nous détaillons pas ici.

Position:static

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).

#div-1 {
     position:static;
}

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.

Exemple : 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

Position:relative

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.


<style>
    #div-1 {
     position:relative;
     top:20px;
     left:-40px;
    }
</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

Position:absolute

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:

<style>
    #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

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.

Position:relative + position:absolute

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

Exemple : mise en page deux colonnes avec relative et absolute

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

Exemple : deux colonnes avec relative + absolute et une hauteur fixée

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

Exemple : dessiner avec relative + absolute

 <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...

Les flottants: float

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.

<style>
img {float:right} 
</style>

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

<style>
img {float:left} 
</style>

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.

Exemple : colonnes avec float

Si on float une colonne à gauche puis une autre colonne à gauche elle vont se coller l'une à l'autre.

<style>
 #div-1a {
     float:left;
     width:150px;
    }
    #div-1b {
     float:left;
     width:150px;
    }


</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

Exemple : deux colonnes avec float et clear

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

Les boites flexibles (flexbox)

et les grilles (Grid)

font l'objet de lesson séparés: