CSS3

Au cours précédent, nous définissions la structure des pages Web grâce à HTML. Il nous faut désormais définir l'affichage de notre page Web.

Pour cela, nous utiliserons des fichier CSS (Cascading Style Sheets), des feuilles de styles à appliquer à notre page Web, qui permettent de définir :

Les règles CSS

Inclure des règles CSS à une page Web

L'ajout d'une feuille de style CSS à la page web se fait via un élément HTML :

💡 L'attribut permet de bloquer l'affichage de la page tant que la feuille de style n'a pas été chargée. Cela évite un effet de scintillement au chargement de la page.

⚠ S'il est techniquement possible d'ajouter des règles CSS via un élément HTML ou un attribut HTML , il convient d'éviter cela autant que possible.

Déclarer une règle CSS

Un fichier CSS est composé de règles CSS, elles-même composée :

Par exemple, pour aligner le texte des paragraphes à droite :

Les sélecteurs CSS (déplacer CM1)

[TODO: rappel des selecteurs du CM précédent ?] [+~* :root] + pseudo-élément/classes [& nested rules] [slot/hosts]

Valeur par défaut et héritage

Chaque propriété CSS a une valeur par défaut. Lorsque cette dernière est , par défaut, sa valeur sera celle de l'élément parent. On dit alors que la propriété CSS est héritée :

ne définissant pas de valeurs pour , il héritera de son père, i.e. sera affiché en gras.

CSS défini d'autres valeurs spéciales :

💡 Il est possible de changer toutes les propriétés CSS en une seule déclaration :

Propriétés CSS personnalisées

Motivation : la gestion des couleurs

En CSS, il est possible de définir les couleurs d'un élément pour :

Pour des raisons de lisibilité, il est recommandé de limiter le nombre de couleurs différentes utilisées sur une même page Web (généralement 3 maximum). Il convient donc de définir un jeu de couleurs (color scheme) qui sera utilisé dans la page web, généralement composée de :

💡 Il y a toute une théorie sur la manière de bien choisir les couleurs (règle des 60-30-10, roue de couleurs, contrastes, complémentarité, nuances, etc), mais ce n'est pas l'objet ici.

On souhaiterait alors définir ces couleurs à un seul endroit, et ainsi éviter d'avoir à les copier-coller de partout, ce qui complexifierait toutes modifications futures (i.e. avec le risque d'en oublier un).

D'autant plus que les couleurs ne sont pas toujours simples à définir :

💡 Les designers utilisent de nombreuses autres manières de définir les couleurs : , , , , , , etc.

Si cela ne suffisait pas, il faut généralement définir plusieurs jeux de couleurs, e.g. :

💡 Pour indiquer les modes de couleurs supportés (l'ordre indique la préférence) :

💡 Pour indiquer les couleurs de thème (modifie la couleur de la fenêtre) :

💡 Pour définir une couleur en fonction du mode :

💡 Pour définir le mode de couleur à utiliser :

💡 Pour définir des règles CSS spécifiques à un mode de couleur :

Si permet de réutiliser la couleur définie par pour les autres propriétés CSS, cela n'est pas suffisant. Il nous faut ainsi un moyen de créer une variable contenant la couleur que nous pourrons ensuite utiliser dans les règles CSS.

Définir une propriété personnalisée

Pour cela on défini des propriétés CSS personnalisées (aussi appelées variables CSS) :

Il sera ensuite possible d'utiliser sa valeur grâce à , e.g. :

Définition et héritage

Une fois la propriété déclarée, nous pouvons aussi la (re)définir sur un élément :

💡 Si la propriété est définie avec , elle est alors héritable.

💡 Si aucune valeur n'est définie, alors la valeur de est utilisée.

💡 Il est d'usage de définir les valeurs globale sur .

💡 Les propriétés personnalisées traversent les shadow root (cf plus tard).

Indiquer le type de la valeur

décrit le type de valeurs acceptées par la propriété CSS personnalisée, e.g. :

Positionnement et dimensionnement des éléments

L'une des fonctions premières de CSS est de positionner et de dimensionner les éléments sur la page Web.

Cependant, il convient de garder à l'esprit que la fenêtre dans laquelle s'affiche la page web est de taille variable. Notamment du fait e.g. de la taille variable de l'écran, ou du redimensionnement de la fenêtre (e.g. en demi-écran).

Le flux

Par défaut, les éléments sont affichés les uns à la suite des autres :

Ils correspondent en réalité aux propriétés CSS suivantes :

⚠ Un bloc ne peut être contenu dans un élément .
⚠ Par défaut, les composants Web sont .
⚠ Certaines propriétés CSS sont ignorés sur les éléments .

Il existe cependant d'autres modes d'affichages :

💡 Il existe d'autres modes d'affichages liées aux tables et aux listes.
💡 permet d'afficher l'élément mais de manière invisible.

Propriétés CSS de flex

configure la liste : configure la manière dont la taille d'un élément de la liste est calculée :

Par défaut, l'élément a la taille indiquée par . L'espace restant est redistribué à l'ensemble des éléments de manière pondérée par . S'il au contraire il manque de l'espace, les éléments sont réduits de manière pondérée par . Cela dans les limites indiquées par (cf suite).

💡 En pratique :

💡 On utilise ainsi généralement :

💡 CSS permet de fixer ces différentes propriétés de manière indépendante avec :

Vous pourrez trouver plus de détails sur flex sur la documentation MDN, ainsi que sur le lien suivant : https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Propriétés CSS de grid

configure la grille : et définissent respectivement les dimensions des lignes et des colonnes. Il peuvent être définis soit par :

💡 correspond à une fraction de la dimension. Par exemple découpe la dimension en 3, la première ligne (ou colonne) est 2x plus grande que la suivante.
💡 est une manière plus concise d'écrire .

permet d'indiquer la position et dimension d'un élément de la grille :

💡 Il est possible de définir un élément comme étant une sous-grille (réutilise les lignes et/ou les colonnes de la grille principale) :

💡 Il est possible de nommer des lignes, colonnes, ou région pour placer les éléments de la grille plus explicitement, cependant, nous n'étudierons pas cela ici.

💡 CSS permet de fixer ces différentes propriétés de manière indépendante avec :

Vous pourrez trouver plus de détails sur grid sur la documentation MDN, ainsi que sur le lien suivant : https://css-tricks.com/snippets/css/complete-guide-grid/

Propriétés CSS de flex et grid

CSS offre deux moyens de définir l'alignement d'un élément :

Elles acceptent généralement comme valeur :

💡 De manière analogue permet d'aligner le contenu de la liste/grille si cette dernière ne la remplit pas.

💡 Flex supporte aussi .

💡 permet de définir un espace minimal entre les différentes lignes/colonnes :

💡 Il est possible de définir l'ordre des éléments de la liste/grille grâce à .

💡 CSS permet de fixer ces différentes propriétés de manière indépendante avec :

Dimensionnement d'un élément

Unités

CSS fourni de multiples unités pour indiquer une taille :

⚠ Vous pourrez trouver d'autres unités pour le viewport, cependant, et permettent de mieux gérer les téléphones portables.

💡 Pour une impression, il est possible d'indiquer des tailles en , , , .

⚠ Pour effectuer des calculs, vous devez utiliser :

💡 CSS fourni d'autres fonctions pour vous aider :

Le cadre d'un élément

Un élément est composé :

et s'utilisent de la même manière :

💡 Les marges d'éléments adjacents peuvent être fusionnée. On peut voir les marges comme la distance minimale entre la bordure de l'élément et la bordure de tout autre élément.

et s'utilisent de la même manière :

Contrairement à , peut se dessiner par dessus des éléments existants. Il est ainsi très utile pour dessiner des bordure sur des contenu sans modifier la hauteur de la ligne.

Les styles de lignes sont généralement :

💡 permet de d'arrondir les angles de la bordure (border/outline).

💡 CSS permet de fixer ces différentes propriétés de manière indépendante avec :

La taille d'un élément

La taille d'un élément est calculée à partir :

💡 Il est possible d'utiliser pour que la hauteur (ou largeur) s'adapter à sa largeur (ou hauteur).

💡 Les valeurs adaptent les tailles à celles de son contenu.

⚠ Par défaut la taille de l'élément n'inclue pas la bordure et marge intérieur.
Pour les inclure, il convient d'utiliser .

Dépassements

Lorsque le contenu est plus grand que le contenant, il y a dépassement (overflow).

Il est alors nécessaire d'indiquer le comportement à adopter via :

Les options possibles sont les suivantes :

Responsive

Comme nous l'avons indiqué en début de section, les pages Web s'affichent dans des fenêtres de tailles différentes.

Il est alors important de concevoir nos pages Web de sorte à ce qu'elle s'affiche du mieux possible sur des écrans de tailles différentes.

Lorsque la page Web s'adapte à la taille de la fenêtre, on dit alors qu'elle est responsive.

[todo: outil]

Par défaut

Les pages Web s'adaptent déjà à la taille de la fenêtre si vous utilisez :

💡 Bien évidemment, , , , , , peuvent aussi vous aider.

⚠ Pour des raisons historiques, les navigateurs sur mobile dézooment automatiquement les pages Web afin de s'adapter à la largeur de l'écran.

Pour éviter ceci, devez alors inclure la balise suivante dans l'en-tête de la page web :

Des règles CSS différentes

Malheureusement, le comportement par défaut n'est pas toujours suffisant pour gérer toutes les dimensions de fenêtres.

Il est alors nécessaire de réorganiser les éléments en fonction de l'espace disponible, et donc d'utiliser des règles CSS différentes.

Pour cela il y a deux moyens de procéder :

💡 Il est bien souvent préférable de privilégier à .

s'utilise ainsi :
  1. Définir un conteneur parmis les ancêtres de l'élément avec :
    • ;
    • : ne servira que pour la largeur ;
  2. Définir un container query pour l'élément ciblé, e.g. :

💡 Les conteneurs permettent aussi d'utiliser les unités suivantes :

💡 Il existe d'autres conditions que , e.g. , , etc.

Impression (bonus)

⚠ la fonction première d'une page Web est d'être affichée sur écran, il est ainsi inutile de se prendre la tête dessus.

Les pages peuvent aussi être imprimée, pour cela on peut définir des règles CSS spécifique via les media queries :

⚠ Pour une impression, pensez à potentiellement masquer les en-têtes/pieds de pages, surtout s'ils sont fixed.

⚠ L'impression ne défilera la barre de défilement que si elle est sur l'élément racine.

⚠ Lors de l'impression, il est généralement préférable de cocher l'option "ajuster à la largeur de la page".

⚠ Pour une impression PDF, il est préférable d'utiliser Chromium pour un PDF de taille raisonnable.

💡 Vous pouvez indiquez où effectuer les coupures de pages avec , avoir des options en fonction de si la page est pair ou impair, etc

💡 permet d'insérer un retour à la ligne facultatif.

Sortir des éléments du flux

CSS permet de sortir des éléments du flux, i.e. de les afficher à une position différente de celle à laquelle ils devraient normalement être.

Par défauts, les éléments sont , i.e. dans le flux.
Les éléments qui ont une valeur différente de sont dits positionnés.
Les éléments positionnés acceptent les propriétés CSS , , , .

⚠ Il convient d'éviter autant que possible les éléments positionnés, et d'utiliser à la place, lorsque possible, des flex, grid, margin, etc.

⚠ Les éléments positionnés, bien que sortis du flot, sont assujettis à .

déplace un élément relativement à sa position initiale.

Lorsque possible, il est préférable d'utiliser des marges à la place.
💡 En pratique il est surtout utilisé pour rendre un élément positionné.

positionne un élément de manière absolue, par rapport au premier ancêtre positionné.

⚠ Les éléments absolus ne sont pas considérés dans le calcul de la taille de leur père.
⚠ Les éléments absolus peuvent en chevaucher (overlap) d'autres :

positionne l'élément par rapport à la fenêtre.

⚠ Il est préférable de privilégier flex/grid, ou

s'affiche normalement, mais reste aux frontière de son père lorsque l'élément est défilé.

⚠ Il faut définir au moins l'une des propriétés , , , .
⚠ Utiliser lorsque l'élément sticky prend toute la largeur/hauteur.
💡 Il est notamment très utile pour :

Transformations, animations et interactions (PW ou PWV ou CM5 ?)

=> filter / opacity (e.g. on hover) => filter + rotation (dark mode)

=> pointer-events / user-select

=> transform-box.

=> animation & interactions => JS / worklet+paint() => CSS + rapide JS. => interactions : cursor + events. => HTML inert => :hover -> e.g. menu / scale on hover / opacity on hover / hidden. => spoiler => multi-page or use CSS (+ JS). => animation => carroussel => visibility hidden

=> worklet

=> resize/contenteditable

Limite de HTML/CSS: => interactions (que faire ?)

=> mise à l'échelle... vs zoom...

Quelle règle CSS est appliquée ?

Spécificité

Il arrive que des règles CSS soient contradictoires. Dans l'exemple suivant, le texte doit-il s'afficher en gris ou en noir ?

Par défaut, CSS applique la règle la plus spécifique. Pour rester simple, CSS compte le nombre d'identifiant, de classe, de nom de balise, et des autres éléments dans un tableau :

RègleIDClassesBaliseAutres
0100
0010

CSS compare alors la spécificité colonne par colonne, de gauche à droite, en s'arrêtant à la première colonne différente. En cas de spécificité identique, elle appliquera la dernière règle déclarée.

Importance et couches

Il est possible de rendre une déclaration CSS prioritaire via :

Néanmoins, cela pose très vite problème lorsqu'on souhaite ajouter une autre règle CSS encore plus prioritaire. Si son usage peut se justifier dans certains contextes particuliers, il convient cependant de les éviter autant que possible.

Une alternative est d'utiliser les couches CSS (CSS layers). Le principe est très simple : on regroupe des règles CSS ensembles dans une "couche", et on établi l'ordre de priorité de ces différentes couches entre elles.

Cela est notamment très utile lorsqu'on souhaite utiliser des bibliothèques CSS :

L'avantage des composants Web

Les composants Web permettent de regrouper, dans un ensemble cohérent, les fichiers définissant le composant (HTML, CSS, JS/Brython, etc), améliorant ainsi la lisibilité du code.

Cependant, une règle CSS s'applique à tous les éléments correspondant à son sélecteur. Ainsi, sur de larges projets, il est très aisé d'écrire une règle CSS pour un élément donné qui, involontairement, s'appliquera à d'autres éléments. Ce genre d'effets de bord peut très vite devenir infernal à gérer.

Heureusement, les composants Web ont généralement une racine cachée (shadow root) qui isole les éléments qu'il contient, les rendant alors indépendant du reste du document et des autres composants Web.

Ainsi, les règles CSS du composant Web ne s'appliquent qu'à ses propres éléments,et ses éléments ne sont impactés que par ses propres règles CSS. Il est alors possible de réutiliser un composant Web dans différentes pages Web, sans qu'une règle CSS déclarée globalement (ou dans un autre composant) ne vienne l'impacter.

CSS ou HTML ?

Certains éléments HTML peuvent se substituer à des règles CSS, e.g. :

HTMLCSS
A
A
A
A
A

[TODO: cheat sheet text-*]

Cependant, la séparation entre structure et affichage fait qu'il est souvent préférable d'utiliser des règles CSS, plutôt que des éléments HTML :

Sémantique et affichage.

Il arrive cependant qu'on souhaite afficher de manière différente deux éléments HTML. Dès lors, il est nécessaire d'avoir un moyen de les distinguer afin de leur appliquer des règles CSS différentes :

Cependant, la classe est un attribut HTML, il doivent donc autant que possible décrire la sémantique (le sens) de l'élément HTML, plus que la manière de l'afficher.

💡 Pour distinguer les colonnes d'une table, on utilise les balises et :

Les préprocesseurs CSS

Cependant, cette séparation entre structure (HTML) et affichage (CSS) n'est pas toujours entièrement respectée. Par facilité, il est en effet courant d'utiliser des classes, non pas pour ajouter une sémantique ou désigner un type d'élément, mais pour appliquer des règles CSS sur un ensemble d'éléments HTML, e.g. :

Sur de gros projets, cela permet d'éviter la duplication de règles CSS, ainsi que de les normaliser. C'est par exemple ce que proposent plusieurs bibliothèques CSS comme Tailwind ou Bootstrap.

En réalité, cela est surtout une solution de contournement aux limites de CSS, qui ne permet pas de réutiliser des règles existantes dans une nouvelle règle, e.g. :

Pour combler les limites de CSS, des pré-processeurs CSS (e.g. LESS, SASS) permettent d'ajouter plus de fonctionnalités à CSS :

X

=> outil (inspecteur)

=> astuces https://developer.mozilla.org/fr/docs/Web/CSS/Pseudo-elements (comme un élément) https://developer.mozilla.org/fr/docs/Web/CSS/Pseudo-classes (comme une classe) + évoquer pseudo-classes/pseudo-éléments.

=> ::before/::after + other pseudo-element/class => attr()

=> :scope (CM3?)

=> limitation => code avec pre ou white-space + font-family (monospace) + coloration syntaxique (limitation).

=> contain : pour opti (CM5 ?)