Introduction brève à CSS

Najib Tounsi

☰ Contenu

  1. Background
  2. C'est quoi CSS
  3. Pourquoi les styles
  4. Comment décrire un style
  5. Comment donner un style à un élément
  6. Différentes façons de donner un style à un élément
    1. Sélectionner l'élément visé par le style
    2. Sélecteur universel
    3. Sélecteur de classe d'éléments
    4. Sélecteur pour éléments avec attribut id
      1. class vs iD
    5. Sélecteurs contextuels
    6. Sélecteurs imbriqués au premier niveau (élément fils)
    7. Sélecteurs d'éléments adjacents
    8. Groupement de sélecteurs
    9. Sélecteurs d'éléments avec un attribut donné
  7. Où déclarer les styles
  8. Styles plus avancés
    1. Pseudo element / Classes
    2. Web fonts @font-face
    3. Modèle de boites
      1. Exemples :
      2. a noter
  9. Styles pour la mise en pages
    1. Le modèle de style grid
    2. Le Modèle de style Flex
      1. propriétés de base
      2. Axes des items.
      3. Autres Propriétés
  10. Références pour en savoir plus

Background

HTML

C'est quoi CSS

CSS, Cascading Style Sheets, est un langage de style.

Il permet de concevoir la façon de présenter les éléments HTML d'une page. Plus exactement,  il permet de changer le style de présentation par défaut d'une page par un navigateur.

Exemples : Les paragraphes suivants ont différents styles :

Paragraphe avec texte en italique ou en gras ou fonte fantaisiste  (style d'écriture ou de police)

Paragraphe en bleu royal  sur fond blanc (style de couleur de texte).

Paragraphe en noir sur fond bleu ciel (style de couleur de fond)

Paragraphe avec un léger retrait à gauche

Paragraphe aligné à droite

Paragraphe encadré

... Cadre plus stylé.

etc.

Pourquoi les styles

Comment décrire un style

Un style est déclaré de la forme simple :

propriété : valeur;

propriété
est le type de propriété qu'on désire affecter, par exemple la couleur, la police, la taille etc...
valeur
une affectation possible, par exemple bleu pour une couleur, Arial pour la police, 40px pour la taille.

Les exemples précédents ont respectivement les déclarations de style suivantes :

font-style : italic ;

font-weight : bold ;

font-family : 'Apple Chancery', 'Lucida calligraphy' ;

color : royalblue ;

background-color : lightskyblue ;

margin-left : 40px ;

text-align : right

border : 1px solid black et ensuite border : 0.4em inset lightblue;

où les noms de propriétés et les valeurs sont auto-explicatifs.

Les valeurs peuvent revêtir différentes formes. Par exemple une couleur peut être écrite avec son nom blue, ou sa valeur combinaison de trois couleurs de base rgb(0, 0, 255), ou l'équivalent hexadécimal #0000ff. Les dimensions et les tailles des polices peuvent être données en plusieurs unités: pixel px ou em (taille de la lettre m) ou autre cm etc. (Voir les noms de couleurs de base avec leur équivalent numérique, les noms de couleurs étendues, et les différentes unités.)

Comment donner un style à un élément

Un style est donnée sous la forme :

sélecteur-d-élément  { propriété: valeur; ... }

qu'on appelle règle de style ou simplement règle (si le contexte est sans ambiguïté).

Un sélecteur d'élément indique l'élément concerné par la règle est suivi d'un bloc de déclarations de styles,  séparés par point-virgule si plusieurs.

Exemple :

P {
text-align : right;
}

Ici, P est dit sélecteur d'élément. Il permet d'appliquer le style text-align : right;  aux paragraphes P  (en fait, à tous les éléments dont le nom coïncide avec "P"). Un texte de paragraphe sera donc aligné à droite.

NB. Dans la suite, les noms d'éléments HTML sont donnés en majuscule dans un souci de présentation pour les distinguer de la syntaxe CSS.

On peut énumérer plusieurs propriétés de style, séparées par point-virgule ; pour  un même sélecteur.

 TD {
   border : solid 1px;   font-size : 12pt;
width : 5em;
}

Une cellule de tableau TD sera large (width) de 5 em, avec une bordure (border) de un pixel et une police de 12 points de taille (font-size) pour le contenu texte.

On peut mettre toutes les déclarations de style pour un sélecteur dans une même ligne. Mais il est préférable de séparer pour une meilleure lisibilité. Le format CSS est libre.

Si plusieurs sélecteurs d'éléments reçoivent un même style, on peut les énumérer séparés par virgule , .

 H1, H2, H3, H4, H5, H6 {
text-decoration : underline;
}

Tous les titres de section seront soulignés.

Avant de passer à la façon de sélectionner un éléments pour affecter un style, notons la liste des propriétés déjà vues.

Quelques propriétés et quelques unes des valeurs
Propriété Sens Exemple de valeur
color, background-color Couleur de texte et de fond
blue, #ccffff, rgb(204, 255, 255)
border Bordure
solid 1px, solid grey 12px...
font-family Police
'Apple Chancery' , Arial, Amiri ...
font-size
Taille de police
12pt, 85%...
font-style
Style d'écriture, italique, droit
italic, normal ...
font-weight
Grosseur cd police
bold, bolder, normal, 400
margin-left Marge gauche
40px, 2cm, auto ...
text-align Texte aligné à droite ou à gauche
right, left ...
text-decoration décoration de texte, soulignement, clignement ...
underline, none, blink ...
width Largeur d"élément
20em, 55% ...

Différentes façons de donner un style à un élément

Il y a plusieurs façons de définir des sélecteurs d'éléments pour appliquer  un style.

Sélectionner l'élément visé par le style

Comme ci-dessus,

 P {
text-align: right;
}

Cette règle attribue le style donné à tous les éléments (dont le nom coïncide avec) P.

Sélecteur universel

Le sélecteur universel * coïncide avec tous les noms  d'éléments.

* { font-style: normal }

donne style de police normal, ni italique ni gras, à tous les textes d'une page.

Sélecteur de classe d'éléments

Le sélecteur de classe est un identificateur qui commence par le caractère ..  Il permet d'appliquer un style à une classe d'éléments choisis.

.fort { font-weight: bolder }

Tout élément ayant un attribut class avec la valeur fort se voient appliquer le style caractères gras.

<P class="fort"> ... paragraphe important ... </P>
<P> bla bla
<SPAN class="fort"> passage important ... </SPAN>
autre bla bla
</P>
Noter que le caractère . ne figure pas ici avec la valeur de l'attribut class.

On peut aussi appliquer plusieurs sélecteurs de classe à un même élément. Etant donné un autre sélecteur de classe .bleu {color : blue}.

<SPAN class="fort bleu"> texte important ET bleu </SPAN>

Il est par ailleurs possible de restreindre ce type de sélecteur avec un élément donné.

BLOCKQUOTE.fort{ font-weight: bolder }

S'applique uniquement aux éléments <blockquote> et ayant l'attribut  class = "fort".

<BLOCKQUOTE class="fort"> ... </BLOCKQUOTE>

Sélecteur pour éléments avec attribut id

Comme le sélecteur de classe, on peut définir une règle de style pour les éléments qui ont l'attribut id qui coïncide avec le sélecteur. On utilise le caractère # (au lieu de .)

#entete { font-weight: bolder }

Tous les éléments ayant un attribut id = "entete" se voient appliquer cette règle.

<H2 id="entete"> titre formaté en caractères gras </H2>

La même remarque que précédemment, on peut combiner avec un élément . 

H2#entete { font-weight: bolder }

applique le style uniquement aux éléments titre de section <H2>  ayant l'attribut id = "entete".

On aura remarquer que .abc ou #idf se comportent pareillement sauf que dans un cas on utilise l'attribut class="idf" et dans l'autre l'attribut id="idf".

class vs. id

Groupement de sélecteurs

Déjà vu plus haut, on peut factoriser un style pour plusieurs sélecteurs séparés par virgule.

  H1, H2, H3, H4, H5, H6 {
text-decoration : underline;
}

Tous les titres de section seront soulignés.

Sélecteurs contextuels

Il est parfois désirable de donner un style à un éléments quand il se trouve dans un certain endroit, e.g. est imbriqué dans un élément donné,  suit tel autre élément dans la page etc. Ces situations sont décrite par des notations dite sélecteurs contextuels.

Exemple : Appliquer un style à un élément uniquement  quand il est imbriqué dans un autre élément donné.

PRE EM { color: red; font-weight: bold;}

donne un style de police bold et red aux éléments <em> quand ils se trouvent à l'intérieur d'un paragraphe <pre>. (Comme certains exemple ici).

L'imbrication peut être à tout niveau.

Un exemple typique serait (combiné avec un sélecteur de classe spécifique) :

DIV#navigation A {
color:#3333ff;
}

pour donner le style spécifié aux différents  textes de lien, éléments A, mais qui se trouvent dans la partie navigation d'une page, i.e. éléments div avec attribut id = "navigation". (OK, il y a l'élément <nav> pour cela, mais ce n'est pas le propos ici)

On peut spécifier ce style uniquement aux texte de liens qui se trouvent imbriqués au premier niveau de cette partie. La syntaxe qui suit le permet.

Sélecteurs imbriqués au premier niveau (élément fils)

le symbole supérieur > permet de donner un style à un élément uniquement  quand il est descendant direct d'un élément donné. (Imbrication premier niveau.)

DIV#Navigation > A {
color:#3333ff;
}
<DIV id="Navigation">
<P>
<A>Un premier lien non concerné</A>
</P>
<A>
Un second lien concerné par le style</A>
</DIV>

Uniquement le second lien sera touché par la règle de style.

Ce  type de sélecteur peut servir quand on voudrait donner un style à des éléments de section sans que cela s'applique aux sections plus internes.

Pour retenir la notation idf > idf, penser à un chemin d'accès fichier dossier > dossier... dans les fenêtres des OS ou à des sous-menus menu > menu ... qui suggèrent des imbrications

Sélecteurs d'éléments adjacents

Le signe plus + permet de donner un style à un élément quand il vient juste après un autre dans le source HTML. L'exemple suivant est significatif :

IMG + P {
font-style:italic;
}

Un paragraphe qui vient juste après une image sera en italique (pour commenter l'image par exemple...)

Là aussi, pour se rappeler la notation idf + idf, penser à la concaténation dans C ou Java. chaîne+chaîne... qui suggère des éléments adjacents.

Sélecteurs d'éléments ayant un attribut donné

On peut de donner un style à un élément qui est muni d'un attribut donné avec une valeur donnée. notation.

P[maCouleur = "blue"] {color: blue;}

A utiliser comme suit :

<P maCouleur="blue"> Texte affiché en bleu.</P>

NB. Ne pas confondre avec la notation comme  p.bleu (cf. ci-dessus) qui spécifie l'élément ayant la valeur "bleu" pour l'attribut class.

Un usage typique c'est avec l'attribut HTML lang.

P [lang="ar"] { font-size: 105%; }

Cette règle augmente de 5% la taille de police des paragraphes <p> ayant l'attribut lang qui vaut "ar" (censés être écrit en Arabe). Exemple :

<P lang="ar"> نص عربي </P>

Cette forme de sélecteur p [lang="ar"] est très puissante. Surtout très utile pour les parties de pages écrites en des langues  différentes.

* [lang="ar"] { font-size: 105%; }
* [lang="fr"] { font-size: 95%; }

Ici, tous les éléments (sélecteur universel *) dont le contenu est déclaré en Arabe auront une police de taille  5% supérieure à la normale.  Ceux écrits en Français, seront de 5% inférieurs. (En supposant que les polices choisies pour ces langues exigent d'harmoniser les tailles...)

Voilà en ce qui concerne les principales notations de sélecteurs. Voir la liste des sélecteurs CSS (ou cette référence).

Où déclarer les styles

On peut déclarer un style de plusieurs façon.

1) En ligne avec un élément : avec l'attribut style pour l'élément.

  <p style="color: blue;">Ce paragraphe ci devrait apparaître en bleu.</p>

Le style est spécifique à cet élément p portant la déclaration.

2) Interne à la page: dans le document HTML avec l'élément <style> dans la zone <head>.
<!DOCTYPE html>
<html><head> <style> p { font-family: arial;}
.bleu { color: blue;} </style>
...
</head>
+
<body>
... <a class="bleu">Texte de lien devrait apparaître en bleu.</a> <p>Ce paragraphe devrait être en police Arial. </p>
<p class="bleu">Celui-là est bleu en plus... </p> </body>
</html>
3) Feuille de style externe : Un fichier texte .css externe  à la page et contenant des règles de styles.
  /* fichier monStyle.css    */

p { font-family: Arial;}
.bleu { color: blue;}

Ce fichier pouvant importer d'autres feuilles de style avec la règle-@ @import url(...);. A l'intérieur des parenthèses l'URL de fichier à importer. (Les règles-@, sont de règles qui indiquent un comportement à CSS, ici importer une feuille de style. On en verra une autre plus bas).

@import url (autre.css);

Cette règle-@ doit être utilisée avant toutes les autres, et les règles de style importés sont insérées à cet endroit.

La page HTML contiendra alors un élément <link> de type stylesheet qui met en relation la page avec le fichier CSS.

<!DOCTYPE html>
<html><head>
<link rel="stylesheet" href="monStyle.css">
</head>

<body>
... <a class="bleu">Texte de lien devrait apparaître en bleu.</a> <p> Ce paragraphe devrait en police Arial. </p> </body> </html>

L'intérêt ici est double. D'une part le fichier CSS peut s'appliquer à d'autres pages HTML qui y font référence par  <link ...>, et d'autre part on peut effectuer des changements dans la feuille de style sans toucher la page HTML.

Ces trois catégories de style sont qualifiées de style auteur, car elle sont conçues avec le document HTML.

Si aucun style auteur n'est déclarée pour une propriété et un élément donnés, ce sont des valeurs par défaut du navigateur qui s'appliquent. Par exemple caractères gras et police plus grande pour les éléments titre <h1>... <h3>, écriture italique pour un élément <em> etc. (cf. Default style sheet for HTML 4).

Remarque : L'utilisateur (lecteur de la page) peut influencer des styles défauts du navigateur au niveau de la configuration de ce dernier. Il est même possible de choisir un style considéré plus important que le style auteur de la page. Cela est particulièrement utile pour l'accessibilité par exemple.

Styles en "cascade" et héritage

 Les règles de style applicables à un élément donné proviennent donc de différentes sources et se rajoutent les unes après les autres en cascade.

Les règles de style déclarées en ligne avec l'attribut style se rajoutent à celles déjà déclarées en entête avec l'élément <style> lesquelles se rajoutent aux règles déclarées dans des feuilles de style externes avec <link rel="stylesheet"...>, (qui, elles, se rajoutent au style interne du navigateur).

Exemple :

Se rajoutent à "caractère gras et police plus grande" du navigateur pour donner un titre h1 tel que :

Titre h1 stylé en cascade

D'un autre côté, un élément imbriqué hérite des styles d'un élément ascendant.

Si ce titre h1  est imbriqué par exemple dans header ayant le style text-transform:capitalize;, il hérite en plus de ce style pour devenir (début de mots en lettres capitales) :

Titre h1 stylé en cascade lettres Capitales

Cela dit, le mécanisme de cascade et d'héritage des règles de style ne se passe pas sans ... règles.

Cas 1. L'ordre  d'apparition des déclarations de règles est significatif. S'il y a conflit de règles, i.e. même propriété affectée plus d'une fois par des valeurs différentes, c'est celle apparaissant en dernier qui s'applique. Cela donne l'avantage à un auteur de surclasser une règle déjà déclarée auparavant — ou provenant de feuille de style écrite par  une autre personne. C'est ainsi qu'on peut changer le style défaut du navigateur avec une règle CSS donnée.

De même, une règle color: blue; par exemple figurant dans un  fichier externe .css  (<link> déclaré avant <style>) peut être changée en color: green; à déclarer dans le document lui-même dans la partie <style> justement, ou en ligne de façon spécifique à un élément avec l'attribut style="..." . Dans ce dernier cas on peut aussi changer une règle définie dans la partie <style> de la page.

Exemple :

//////  Fichier exemple.css 
color: blue;
//////  HTML 

<link href="exemple.css" ....>
<style>
p { color: red;
  color: green;
}
.purple{ color:purple ;}
</style>
....
<p>Green surclasse Blue</p> <p style ="color : brown;">Brown surclasse les autres</p>
<p class="purple">Purple surclasse les autres</p>

La ligne 11 donnera "Green surclasse Blue" en vert car color : green; est la dernière règle rencontrée parmi les trois des lignes 2, 5 et 6.

La ligne 12 donnera "Brown surclasse les autres" en marron car la règle color : brown; est donnée en ligne spécifiquement à l'élément concerné. (Exercice : quelle couleur avec <p style="color: brown; color: yellow;"> ? Réponse :  yellow.).

La ligne 13 donnera "Purple surclasse les autres" en mauve. Le sélecteur de classe est plus spécifique que le sélecteur élément.

Exercice : Tester le code suivant

<p  class="purple" style="color:grey;">
    Quelle couleurs ?
</p>

(Réponse : grey l'emporte. le texte sera en gris.)

Ce pendant, un auteur de feuille de style CSS peut souhaiter donner une priorité plus grande à une règle estimée importante. Dans ce cas, il suffit de marquer cette règle par la notation !important juste après la valeur.

Dans l'exemple ci-dessus, si on met en ligne 5

  color: red !important;

cette règle s'appliquera aux quatre paragraphes sus-mentionnés qui auront tous cette couleur.  Il en serait de même, tous les paragraphes en bleu, si on avait mis la mention !important dans la règle de la feuille de style externe (ligne 2 au lieu de ligne 5).

Cas 2.  Tous les styles ne s'héritent pas.

Regardons d'abord un exemple de propriétés pouvant être héritées d'un élément donné vers les éléments imbriqués. Une police Arial définie pour un élément <article> est héritée par des éléments <span> imbriqués, si non redéfinie.
<style> 
article { font-family: Arial;} .it { font-style: italic;} .ser { font-family: Serif;}
</style> ...
<article> Texte en Arial. <span class="ser">En Serif.</span> <span class="it">En Arial et en italic</span> </article>

Ce code donnera :

Héritage fonte

Le style font-family: Arial; s'applique à tous le contenu de  article y compris les éléments internes, tant que ce style n'est pas redéfini par un élément interne (ligne 9)   ̶  lequel élément interne peut à l'occasion rajouter son propre style comme italic (ligne 10).

Cependant tout n'est pas à hériter. Des choses comme width, margin, padding, border ne s'héritent pas. Sinon, si par exemple la bordure était héritée, tous les éléments internes auraient leurs propres bordures qui s'empileraient. Ce qui n'est pas probablement pas souhaitable.

Attention cependant aux tailles exprimées en %. Dans certains cas, chaque imbrication verrait sa taille augmentée (ou réduite) proportionnellement par rapport à l'élément parent. Un exemple simple avec ajustement de taille de police:

<style>
p, em, a {font-size: 150%;}
</style>
... <p>abc
<em>abc
<a href="">abc
</a>
 </em>
</p>

Donnera :

Police plus grande en cascade

Où chaque mot est 150% plus grand que le précédent.

On peut éviter un tel désagrément en  "inhibant" un changement de taille en cascade avec la valeur particulière inherit. Par exemple :

<style>
p {font-size: 150%;}
p * { font-size: inherit;}
</style>

  Donnera :

Taille police héritée

Cette solution de contournement est particulièrement utile quand on utilise par exemple le pseudo élément :lang pour changer la taille de police pour des textes dans un document bi/multilingue. Voir ci-après.

Styles plus avancés

Pseudo element / Classe

Pseudo-classe

Noté :état

Pour styler les éléments se trouvant dans un certain état, c'est à dire ayant une qualité, par exemple le premier  decendant :first-child, ou faisant l'objet d 'un événement, par exemple désigné par un pointeur :hover.

Exemples :

etc. Liste complète.

Pseudo-élément

Noté ::partie-d-élément

Les pseudo-éléments sont éléments abstraits, qui ne sont pas explicitement crées par HTML. Ils sert à sélectionner et styler une partie de document qui n'est pas nécessairement représentée par un élément HTML. Par exemple styler la première lettre (::first-letter) ou première ligne (::first-line) d'un paragraphe, désigner l'avant (::before) ou l'après (::after) d'un élément. Usage typique :

etc. Liste complète.

:lang()

Voir § suivant.

Web fonts et @font-face

La propriété font-family

Si un document ne spécifie pas une police particulière,  le navigateur en choisit une par défaut qui varie selon le navigateur (paramètre configurable). Mais on peut choisir soi-même la police de caractère d'un document ou d'un contenu. Pour cela on a la propriété font-family

p {
font-family : Arial, Sans-serif, "Century Schoolbook", Serif;
}

On énumère une liste de noms de polices séparés par virgule. Le navigateur choisit la première police si elle est supportée, sinon il a recours aux suivantes dans l'ordre. Polices dites fallback fonts. Un nom de police peut être propre à une fonte donnée, comme Arial ou Century Schoolbook, ou bien un nom générique d'une famille de police : serif, Sans-serif.

La règle-@ @font-face

Le choix d'une police pour un texte n'a pas toujours un but d'embellissement. Le choix de police est partie prenante du message porté par un texte, sinon il est indiqué par le script dans lequel le texte est écrit. Or il arrive que la police choisie par l'auteur d'un document ne se trouve ni dans la navigateur ni dans le système sous-jacent. Pour éviter un choix de police par défaut, la solution est de faire télécharger par la page la police nécessaire le cas échéant. Pour cela, les auteurs peuvent spécifier un fichier contenant une police. La règle-@ @font-face est prévu à cet effet.

@font-face {
  font-family: "maPolice";
  src: url("./mapolice.woff");
}

La première ligne font-family : sert à affecter un nom à la police dont le fichier source est spécifié dans la deuxième ligne src: url() qui en donne l'adresse URL.

Après il s'agit d'utiliser le nouveau nom comme les autres polices.

body {
font-family : maPolice, Arial, Sans-serif, "Century Schoolbook", Serif;
}

Ce mécanisme s'avère utile quand on souhaite utiliser sa police préférée pour les textes Arabes par exemple.

@font-face {
  font-family: 'maPoliceAmiri';
  src: url(https://fonts.gstatic.com/s/amiri/v13/J7aRnpd8CGxBHpUrtLMS7JNKIjk.woff2) 
format('woff2'); font-style: normal; font-weight: 400; }

Cela donnera :
    texte en police Amiri

au lieu d'une police défaut comme : الاستمرار في مزاولة مهامهم الهندسية و المهنية عبر البرمجة الكاملة

Noter le type de police, ici .woff/woff2 (Web Open Font Format versions 1 and 2), très courant actuellement. On trouve aussi parfois .ttf (True Type Format), .otf (Open Type Fonts) etc.

Une police donnée peut supporter les caractères de plusieurs langues. Ausi, pour ne pas avoir à télécharger la police pour une langue donnée si on n'utilise aucun caractère de cette langue, on peut rajouter au bloc  @font-face la ligne :

unicode-range: U+0600-06FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE80-FEFC;

avec la propriété CSS unicode-range qui donne les intervalles de points code Unicode des caractères nécessitant cette police Amiri.

On peut mettre tous les blocs @font-face {...}  dans un seul fichier CSS et l'importer avec la directive @import. Exemple :

@import url(//fonts.googleapis.com/earlyaccess/notonaskharabic.css); 

Polices pour l'Arabe bien lisibles sur toute taille d'écran, sous-titres ou texte défilant.

A noter enfin qu'il se peut qu'un navigateur ne supporte pas un certain format de police. Il faut alors spécifier plusieurs sources src : pour plusieurs formats dans le bloc @font-face. Noter aussi que les polices de caractères ne sont pas toutes libres ou gratuites. 

:lang()

Cette pseudo classe s'utilise par exemple comme :

:lang(ar) {
    font-family: Amiri, 'Traditional Arabic', serif;
    font-size: 18px; 
  }

:lang(ar) * { font-size: inherit;}

Le premier sélecteur (L1) est pour préciser les polices et leur taille pour les caractères Arabes dans les éléments ayant l'attribut  lang="ar".

Faire cependant attention ici quand on utilise des tailles relatives, e.g. font-size: 110%; .  Le problème c'est que la règle peut s'appliquer à plusieurs éléments imbriqués et donc augmenter la taille de 110% à chaque étape (voir § "cascade et héritage" plus haut) . D'où le deuxième sélecteur (L6) qui est là pour dire que partout (tous les éléments ayant lang="ar") la taille est à hériter d'un élément parent sans avoir besoin de l'augmenter à chaque étape.

Modèle de boites de CSS

Les éléments HTML sont agencés par "boites" (box) lors de leur mise en page à l'affichage. Une boite est une zone en rectangle qui entoure chaque contenu d'un élément HTML en créant un espace (marge) autour comme suit :

CSS Box Model
Le modèle boite de CSS.  Seul le contenu
est visible et la bordure si elle est tracée.

Ce modèle permet de gérer l'apparence d'un élément : décorer le contenu et l'espace autour, manipuler la taille de cet espace, son écart par rapport aux éléments adjacents etc.

Les propriétés générales pour manipuler cette zone autour du contenu sont :

Chacune de ces propriétés peut être éclatée en 4 segments avec l'ajout de suffixes: haut (-top), droite (-right), bas (-bottom)  et gauche (-left). Exemples : margin-top, padding-right, border-left etc.

Deux autres propriétés sont à considérer aussi, width et height, qui contrôlent les dimensions du contenu effectif de l'élément (texte, image, ...)

Exemples

1) Ce contenu ci et ce contenu là ont respectivement un fond jaune et un fond vert.
Style :  background-color:lightyellow; et background-color:lightgreen;.

2) Ce contenu en ligne, en plus de la couleur de fond, a un bord fin (1 px) et tracé en bleu.
Style : border: 1px solid blue;. L'ordre des trois propriétés n'est pas important.

3) On rajoute un espacement interne de 1 em autour  de ce contenu en ligne avec  padding: 1em;

4) Même exemple, en mode bloc cette fois-ci, avec un décalage à gauche. Style : margin-left: 2cm;

contenu en mode bloc décalé à gauche ...

5) Avec en plus une marge supérieure margin-top: 2.5em; (un peu trop grande)

contenu en mode bloc  décalé à gauche avec une marge en haut ...

Remarque : Pour les éléments blocs, et sans redéfinitions,  les marges hautes et basses sont prédéfinies non nulles par le navigateur (typiquement 16px).

6) Autre exemple (élément bloc) : usage de width et height

contenu sur fond bleu ciel  (SkyBlue #87ceeb), espacé par rapport aux bords et affiché en mode bloc centré ...

avec le style :

width : 280px;       /* largeur du contenu en boîte */
height : 100px; /* hauteur du contenu en boîte */ margin : auto; /* des marges pour centrer un bloc */ padding: 10px 6px 8px 6px; /* espacement interne : haut, droite, bas et gauche*/
/* Ce qui suit est pour la décoration */
background-color: skyBlue ; /* couleur de fond */
box-shadow: 5px 4px 3px silver; /* ombre à droite et en bas, fond gris */ border-radius: 5px; /* angles arrondis */
NB. Seules ces quatre premières lignes concernent la boîte. Les lignes suivantes ont valeur décorative.

a noter

Le modèle s'applique aussi bien aux éléments block (surtout) avec retour à la ligne avant et après (ex. <p>, <article>, <li> etc...),  qu'aux éléments inline (ex. <a>, <span>,<em> etc.).  Cela se manifestera sur comment la boîte se comporte en termes de mise en page et par rapport aux autres boîtes. Par exemple, @@ marge-haut/bas ne marche pas pour inline.

En plus, l'agencement de ces boîtes peut se faire dans différentes directions : vers la droite ou vers la gauche pour les box inline, vers le bas ou vers le haut pour les box block. Ces directions sont contrôlées par le mode d'écriture CSS).

Voir l'ensemble des propriétés du modèle box de CSS.

Styles pour la mise en pages

Pour positionner des éléments alignés les uns par rapport aux autres comme dans des lignes et des colonnes, on utilisait des tableaux. Mais les tableaux sont fait pour un autre usage et ont en outre des caractéristiques particulière qui font que ce n'est donc pas le bon choix pour la disposition d'éléments dans une page.

Avec les modèles grid et flex de CSS on peut positionner des éléments à des endroits bien choisis dans une page ou à l'intérieur d'un élément particulier (par exemple un formulaire),  et on peut leur appliquer un style adéquat.

Ci-après un bref aperçu de ces deux modèles.

Le modèle de style grid

Le style grid est une grille, lignes et colonnes, où on place les éléments dans des cases appropriées. Les cases d'une telle grille sont extensibles et ajustables à volonté.

Une grille doit être attachée à un élément, qui est le conteneur des objets alignées et qui doit avoir le style d'affichage display : grid;

Exemple-1 : le cas le plus simple est une grille déclarée display : grid; sans plus.

 #conteneur {
display : grid;
}

Ce sélecteur correspond à une grille avec une seule colonne et autant de lignes que d'éléments à contenir. Un élément div conteneur de cette grille sera de la forme :

<div id="conteneur ">
...
</div>

La figure suivante montre un exemple d'un tel conteneur (fond vert) avec des objets (fond gris) en cinq lignes sur une colonne. On dit aussi slot (en anglais.) pour les emplacements dans la grille et item pour les éléments qui y sont placés.

Exemple 1 de grille simple
Une grille simple une colonne et plusieurs lignes

La figure 2 montre un conteneur (fond vert) et des emplacements (fond gris). La décoration est en sus pour l'exemple, en particulier on a réduit la largeur du conteneur à un pourcentage de la largeur totale de la page.

Cette grille a été obtenue par :

 CSS

 #conteneur {
display : grid;
}

 HTML (abstraction faite de la décoration)

<div id="conteneur">
    <span>un <b>1er</b> objet (item) ici</span>
    <span>un <b>2e</b> objet là</span>
    <span>
        <img src="Img/cat.png" 
style="width: 35px; float: left; margin-right: 2px;" /> un <b>3e</b> encore qui est en fait une image </span> <span>un quatrième <b>4e</b> ici</span> <span>et un autre <b>5e</b> qui est un texte qui peut
éventuellement devenir assez long pour occuper
d'avantage d'espace.</span> </div>

La grille matérialisée ici par l'élément <div> stylé conteneur, et les objets dedans sont matérialisés ici par les éléments <span>. Chaque élément défini dans le <div> est rajouté à la grille.

Sans spécification supplémentaire, une grille contient une seul colonne et autant de lignes que d'éléments HTML dedans (5 ici).

(Source).

Exemple-2 : La grille suivante s'étend sur deux colonnes.

 #conteneur {
    display : grid;
    grid-template-columns: auto auto;  
 }

On a rajouté la propriété grid-template-columns avec la valeur  auto deux fois, pour deux colonnes de taille automatique. Sur l'exemple précédent cela donne :

Grid deux colonnes
Même grille que précédemment en deux colonnes.

On voit donc les cinq éléments répartis sur deux colonnes. Cette grille a été obtenue par le CSS :

 #conteneur {
   display : grid;
   grid-template-columns: auto auto;
 }

Le  HTML est le même.

Il y a différentes propriétés pour spécifier les lignes et les colonnes d'une grille.

Exemple-3 Dans la grille suivante on a spécifié les tailles des colonnes... de différentes façons :

 #conteneur {
 display : grid;
 grid-template-columns: max-content 165px 25%;  

A la propriété grid-template-columns on a donné trois valeurs (pour trois colonnes) en : pourcentage 25% de la taille de la grille pour la troisième colonne,  pixels 165 pour la deuxième et en max-content (taille de la case maximum) pour la première. Cela donne sur le même exemple :

Grid trois colonnes tailles données
Même grille que précédemment en trois colonnes avec des
tailles données.

A noter :

Cet un mauvais exemple de spécification ici. Si on utilise ce genre de propriétés, les valeurs doivent être adaptées au type de contenu et à la mise en page souhaitée. Valeurs possibles, auto, max(min)-content , taille en px, cm etc. Utiliser auto ou un pourcentage de largeur de grille est en général satisfaisant.

Exemple-4 : Dans l'exemple suivant, les emplacements dans ma grille sont nommés :

 #conteneur {
   display : grid;
   grid-template-areas:
      "a b"
      "c d";
 } 

Dans cette grille les emplacements sont nommés a, b, c et d en deux lignes deux colonnes. Le modèle est introduit par la propriété grid-template-areas (ou grid tout court).

On complète le CSS en utilisant la propriété grid-area pour désigner les cases à occuper:

  #empl1 { grid-area: a; } 
  #empl2 { grid-area: b; }
  #empl3 { grid-area: c; }
  #empl4 { grid-area: d; }

L'usage de ce modèle en HTML pourra être :

<div id="conteneur"> 
  <div id="empl1">Un contenu placé en a</div>
  <div id="empl2">un autre placé en b</div>
  <div id="empl3">un autre placé en c</div> 
  <div id="empl4">et un autre là en d</div>
*</div>

Résultat :

Grid 2x2 "a b" "c d"
Grille avec emplacements nommés.

En enlevant la ligne 4 id="empl3" du HTML précédent, la case c sera vide (fond vert ici).

Si on donne un même nom à plusieurs emplacements (adjacents), par exemple grid : "a a" "c d", les deux emplacements "a a"  constitueront une zone qui contiendra un seul élément. Utile pour étaler des éléments sur plusieurs colonnes et/ou plusieurs lignes.

Exemple-5 : L'exemple suivant montre un conteneur structuré.

 CSS

 #conteneur {
   display : grid;
   grid-template-areas:  
         "e  e e e  e e"
         "n  m m m  a a"
         "b  b b b  b b";
  }

#entete { grid-area: e;} #nav { grid-area: n;} #contenu{ grid-area: m;} #aside { grid-area: a;} #bas { grid-area: b;}

 HTML (sans la décoration)

<tdiv id="conteneur"> 
<div id="entete">Agence Monguide</div>
<div id="nav"> Liens de navigation<br> textelien-1<br> ... </div>
<div id="contenu">
<p><strong>Volubilis</strong> est une ville ... ...</p> </div> <div id="aside">
<img src="volubilis.jpg"><br>
La ville de Volubilis </div> <div id="bas">
La dernière modification de cette page a été faite
... </div>

Cela donne :

Grid avec zones nommés selon le contenu
Grille avec zones adaptées pour accueillir un contenu structuré.

On voit ici l'utilité d'avoir des zones adaptées au contenu à présenter.

On peut aussi spécifier les zones avec plus de précision avec les tailles et cases couvertes, comme le montre l'exemple suivant.

Exemple-5-bis : On déclare l'élément conteneur comme grille

 #conteneur {
   display : grid;
        /* grille 3x6 remplissage par debut/fin/span etc... */   
 }

et dans chaque sélecteur de zone on spécifie un format indiquant où elle commence et combien de cases elle occupe, en utilisant toujours la propriété grid-area.

 #entete { grid-area: 1 / 1 / 2 / span 6;}
 #nav    { grid-area: 2 / 1 / span 3 / 2}
 #contenu  { grid-area: 2 / 2 / span 2 / span 3;}
 #aside  { grid-area: 2 / 5 / span 2 / span 2;}
 #bas    { grid-area: 4 / 2 / span 1 / span 5 ;}

La zone qui sera identifiée par entete 

Autrement dit, cette zone de l'entête occupera une seule ligne dans la grille, et toute la rangée. On en déduit aussi que la grille a 6 colonnes. La zone qui sera identifiée #contenue

Sur l'exemple précédent, cela donnera :

Grid avec zones nommés selon le contenu
Même que précédemment, mais zone bas de page réduite .

On aura noté qu'on a changé la spécification de la zone #bas, elle commence en colonne 2 (et ligne 4 ensuite elle occupe 1 seule rangée et 5 colonnes

Le Modèle de style Flex

C'est un style de boîtes flexibles, appelé flexbox. Par rapport au au modèle grid précédent qui contrôle à la fois les colonnes et les lignes. flexbox est un modèle de disposition unidimensionnel avec beaucoup de capacités d'alignement et de distribution d'espace entre les éléments qui s'ajustent automatiquement.

propriétés de base

Exemple 1 : conteneur flex  (fond vert) avec items (fonds colorés) en ligne.  (par défaut)

Flex défaut
Conteneur flex avec 4 éléments agencés en ligne
et allant de gauche à droite (par défaut)

  HTML correspondant

<section id="conteneur">
  <article>
      Un premier article à cet endroit
  </article>

  <article>
       Un deuxième article
  </article>

  <article>
 	Un 3e article ici
  </article>

  <article>
    Et un 4e article là
  </article>
</section>

  CSS (sans la décoration, couleurs et bordures, utile pour la présentation ici)

#conteneur {
  display: flex; 
flex-direction: row;

}

A noter :

Exemple 1-bis : Avec la propriété flex-wrap: wrap; dans le même exemple on obtient:

Flex wrap
Conteneur flex avec wrap. 4 éléments agencés en ligne
avec passage à la ligne suivante en cas de besoin.

Remarque : flex-flow: row wrap; et un raccourci pour  flex-direction: row; flex-wrap: wrap; On utilisera cela par la suite.

Exemple 1-ter : contenu 1er item sur deux lignes.

Flex wrap  et item hauteur différente
Même conteneur flex mais avec le 1er item
de hauteur différente

Ici, Le premier item est de hauteur plus grande (deux lignes de textes). L'item de la même ligne s'alignent avec. Les items de la ligne suivante ont gardé la hauteur initiale.

Dans une même lignes les items sont de même hauteur, celle de l'item le plus haut.

On peut aussi spécifier la hauteur du conteneur. Les items occupent la hauteur disponible du conteneur, indépendamment de leur contenu propre.

Exemple 2 : Reprenons l'exemple 1 précédent en simplifiant les items. On fixe la hauteur du conteneur (fond vert, propriété height:80px; spécifiée) . Les items s'alignent sur cette hauteur.

Flex haut
Item alignés sur hauteur
du conteneur.

Comparer par rapport à l'exemple 1-ter précédent, où les items d'une ligne  s'alignent avec l'item le plus haut.

Ici il y a risque de débordement au delà du conteneur, si les items ou leur contenu croissent.

Axes des items.

@@@ NB rajouter axe principale est horizontal (row défaut). Exemple 3 axe principale est column @@@

En fait, les éléments flex se présentent en ligne sur un axe dit axe principale. Par défaut horizontal (flex : row;). Les éléments wrappent en cas de besoin, mais s'enchaînent dans le sens horizontale.

Exemple 3: Ici, l'axe principale est verticale, les éléments s'agencent verticalement.

Flex défaut
Flex container avec 4 éléments agencés
en colonnes.

CSS correspondant :

#conteneur {
  display: flex;
flex-flow: column;
}

Ici, on a flex-direction : column . les items se suivent en colonne de haut en bas (ou l'inverse avec la valeur column-reverse).

Le style flex-flow : column; aurait eu le même effet.  

En résumé, les propriétés essentielles du conteneur (sans la décoration) et leurs valeurs :

Les éléments déclarés dans le conteneur seront disposés selon cette spécification donnée. Les valeurs row et nowrap sont prises par défaut sinon.

Il y a une troisième propriété flex-basic qui définit la base pour déterminer la taille initiale des éléments flexibles. Elle vaut auto par défaut, c'est à dire que les éléments auront la taille déterminées par leur contenu. (Voir paragraphe "Propriété flex & co" suivant.)

Axe principale vs. axe secondaire.

L'axe principal (main axe) d'un conteneur flexible est l'axe principal le long duquel les éléments flexibles sont disposés. Ces derniers s'étendent dans la dimension principale (row ou column) à partir du début (main-start) et allant vers l'autre extrémité (main-end). Dans les figures 9, 10 et 11, l'axe est horizontale (row) et les éléments progressent de gauche à droite. Avec row-reverse c'est de droite à gauche. Dans la figure 12, l'axe principale est verticale (column) et les items  progressent de haut en bas dans ce cas ou inversement avec column-reverse.

Il y a aussi un axe secondaire (cross axe) qui est l'axe transversal qui s'étend perpendiculairement à l'axe principal. Avec wrap, les éléments flexibles "passent à la ligne" (ou colonne) suivante le long de cet axe secondaire. (Sinon, ils dépasseront le conteneur).

Voilà pour ce qui concerne les caractéristiques de base du modèle. Le reste, mis à part la décoration CSS classique, concerne l'aspect flexibilité des éléments, c'est à dire l'ajustement des tailles et l'alignement de ces derniers dans leur conteneur. Cela est réalisé avec la propriété flex d'une part et la propriété justify-content d'autre part.(Le mot flex est utilisé ici comme nom de propriété.)

Autres Propriétés

Propriété flex & co.

Ce sont des propriétés qui permettent aux éléments flexibles d'ajuster leur taille (largeur/hauteur) afin de remplir l'espace disponible dans leur conteneur.

La propriété flex-basis fixe la taille d'un élément flexible en termes d'espace occupé. Les propriétés flex-grow et flex-shrink déterminent respectivement l'allongement et le rétrécissement des éléments sur l'axe principal. la propriété flex est un raccourci qui résume ces trois propriétés (voir plus bas).

taille d'après contenu, flex défaut
Espace disponible en vert. Conteneur taille 400px.
Eléments en ligne de taille par défaut.

Sur cette figure on a un conteneur de 400 px et des éléments flexibles de largeur déterminée par leur contenu. En vert un espace disponible.

 CSS (sans la décoration utilisée ici pour la présentation)

#conteneur { 
   display: flex;
   width: 400px;
}

 HTML

<section id="conteneur">  
  <article>art - 1</article>
  <article>art - 2</article>
  <article>art - 3</article>
</s*ection>

La taille des éléments a été déterminée par le contenu.

Sur la figure suivante, on a utilisé le style flex-grow : 1 pour le premier élément et flex-grow : 2 pour le second.

taille d'après contenu, flex défaut
Espace disponible réparti entre art-1 et art-2
selon flex-grow.

Sur cette figure l'espace disponible  a été reparti pour allonger ces deux éléments. Le second élément a été allongée d'un espace égale à 2 fois celui alloué au premier élément.  2 et 1 étant les valeurs respectives de la propriété flex-grow de ces éléments.

 HTML

<section id="conteneur">  
  <article id="article1">art - 1</article>
  <article id="article2">art - 2</article>
  <article>art - 3</article>
</section>

 CSS

#article1 {
 flex-grow: 1;
}
#article2 {
  flex-grow: 2;
}

Le troisième élément n'a pas été touché, c'est comme si on a mis flex-grow:0.

Voici d'ailleurs comment le navigateur a résolu les tailles de ces deux éléments flexibles.

taille d'après contenu, flex défaut taille rétrécie par flex-shrink  
"Inspect element" par le navigateur des deux éléments flexibles précédents.
En bleu taille flex-basis de l'élément (env. 60 px) et en rose la part d'espace rajoutée.
Pour le deuxième élément (flex-grow : 2) la part est double (100 px au lieu de 50)

Figures obtenues avec l'outil Web Developer d'un navigateur.

Les valeurs de flex-grow sont des entiers positifs. L'espace disponible est réparti en parts, et chaque élément est rallongée de n parts selon sa valeur de propriété flex-grow. (Exercice : Si l'on avait mis flex-grow:1 pour les trois éléments de la figure-13, quel serait le résultat ? Réponse : l'espace disponible sera réparti de façon égale entre les trois éléments qui seront allongés jusqu'à occuper tout le conteneur sur l'axe principal. L'espace vert disparaîtra).

Il est intéressant de voir la "flexibilité" en variant la taille du conteneur précédent (figure-14).

taille d'après contenu, flex défaut
même cas que la figure précédente. Conteneur
de taille 480px en haut et 320px en bas.

Le deuxième éléments croît deux fois plus vite que le premier.

Le rallongement d'un élément flexible se fait à partir de sa taille initiale, laquelle est donnée par flex-basis. Cette propriété peut prendre :

Noter enfin que si  flex-grow  vaut 1 pour tous les éléments d'un conteneur, ils s'étireront de façon égale pour occuper tout l'espace disponible dans l'axe principal.

Pour ce qui est du rétrécissement des éléments flexibles, la propriété flex-shrink agit de façon semblable. Elle prend pour valeur un entier positif qui indique le nombre de parts d'espace à ôter à chaque élément à rétrécir.

La figure suivante montre le même exemple que fig-14 (contenu texte changé pour le besoin), avec flex-shrink  valant 1 pour le premier élément de contenu abcd, 2 pour l'élément de milieu de contenu efgh et 3 pour le dernier élément de contenu ijkl. A gauche le conteneur est de taille suffisante pour contenir normalement les trois éléments flexibles, et à droite la taille du conteneur est réduite et les trois éléments réduits "progressivement".

taille d'après contenu,
      flex défaut    taille rétrécie par flex-shrink
A gauche éléments flexibles dans espace suffisant,
à droite  éléments rétrécis par diminution d'espace .

On voit que la diminution de taille a été plus forte pour les éléments flexibles ayant la propriété flex-shrink plus grande (de gauche à droite).

HTML

<section id="conteneur">  
  <article id="article1">a b c d</article>
  <article id="article2">e f g h</article>
  <article>i j k l</article>
</section>

CSS

#article1 {
 flex-shrink: 1;
}
#article2 {
  flex-shrink: 2;
}
#article3 { flex-shrink: 3; }

L'étirement ou le rétrécissement d'un élément flexible peut être cependant limité par les propriétés CSS  min-width/max-width ou min-height/max-height selon le cas. En plus, un élément flexible est totalement "inflexible" si ses valeurs flex-grow et flex-shrink sont nulles.

Cela dit, plutôt que d'utiliser ces propriétés d'étirement / rétrécissement directement, la spécification CSS encourage à contrôler la flexibilité des éléments flexibles en utilisant la propriété synthétique flex  qui couvre la majorité des cas et s'adapte très bien aux utilisations courantes.

La propriété raccourcie flex permet de définir en une seule fois les trois propriétés : flex-grow, flex-shrink et flex-basis dans cet ordre.

flex : 0 1 auto; par exemple, signifie l'élément ne s'étire pas lorsqu'il y a un espace libre positif, mais se rétrécit à sa taille minimale lorsqu'il n'y a pas suffisamment d'espace.

flex peut prendre les valeurs :

Ce dernier schéma est intéressant dans la mesure où si tous les éléments du conteneur l'utilisent, leur taille finale sera proportionnelle au facteur de flexibilité n spécifié.

Pour en savoir plus sur flex.

Propriété d'alignement des items dans un conteneur

Les propriété précédentes concernent la flexion et les dimensions des éléments flexibles dans un conteneur flexible. Ils peuvent maintenant être alignés dans ce conteneur.

1) La propriété justify-content du conteneur est utilisée pour répartir les éléments sur l'axe principal (horizontal ici).

Avec la propriété justify-content: space-around; dans le conteneur, les items sont répartis sur l'axe principal avec des espaces tout autour (effet quasi centré). En reprenant l'exemple simple de la fig-10 

items justifiés centrés
Eléments flexibles avec espaces autour

Si on réduit un peu la largeur du conteneur, on aura :

items justifiés centrés
Idem avec conteneur moins large

Avec la propriété justify-content: space-between; dans le conteneur. Les items sont répartis avec des espaces intercalaires (effet aligné à droite et à gauche) sur l'axe principal.

items justifiés écartés
Eléments flexibles avec espaces intercalaire

Si on réduit un peu la largeur du conteneur, on aura :

items justifiés écatés
Idem avec conteneur moins large

Autres valeurs justify-content: flex-start; items placés à partir du début du conteneur. flex-end, ce serait à partir de l'autre bout. justify-content: center; items centrés dans le conteneur (sans espaces intercalaire comme en 1 ci-dessus).

L'illustration suivante (Extraite de "CSS Flexible Box Layout Module Level 1") résume ces différents effets sur les éléments flexibles (colorés sur fond gris).

autres valeurs de justify
Différentes justifications des éléments flexibles.

@@  à voir aussi align-items et align-content ... @@

Voir l'ensemble des propriétés du modèle flex de CSS.

Références pour en savoir plus

That's all Folks 😉