CSS : Motivations et principes
Motivations
Comme nous l'avons vu à la fin du cours sur le langage HTML, les éléments de mise en page (comme FONT par exemple) sont exclus du langage html5.
Il s'agit d'un paradigme général consistant à dissocier le contenu d'un document de sa forme. Dans le cas d'un document Web, le langage HTML est destiné à décrire sémantiquement et à structurer le contenu. Les feuilles de style CSS, dont nous allons discuter dans la suite, servent elles à décrire la forme du document.
Les intérêts de cette séparation sont multiples :
- un style, appliqué à toutes les pages d'un site, assure la cohérence graphique de ce site ;
- la maintenance d'un site en est facilitée, un changement de charte graphique ne portera que sur la feuille de style et la modification sera naturellement propagée à toutes les pages ;
- plusieurs mises en forme différentes peuvent être proposées pour un même document sans que celui-ci ne soit répliqué en autant d'exemplaires ;
- le code HTML est lisible et facilement modifiable, sans que l'on ait à penser en même temps au contenu et à son apparence ;
- les pages, dégagées des balises de mise en forme, sont plus légères, donc plus rapides à circuler sur un réseau (la feuille de style est, le plus souvent, très légère et ne sera chargée qu'une seule fois pour l'ensemble des documents qui l'utilisent) ;
- les balises donnent une indication sur la nature du contenu et cette indication pourra être utilisée par un moteur de recherche ou, plus généralement, par tout outil d'extraction d'information.
La solution retenue pour décrire des mises en forme se nomme donc feuilles de style ou, en anglais, Cascading Style Sheets (CSS). « En cascade » signifie que sont prises en compte les feuilles du navigateur, de l'utilisateur, puis de l'auteur du document. Les CSS peuvent être rapprochées des styles et des modèles de document des traitements de texte.
Enfin, précisons que les CSS que nous allons associer à des documents HTML, peuvent aussi être liées à des documents XML. Ces derniers deviennent alors visualisables sur des navigateurs web. C'est une raison supplémentaire pour maîtriser le langage CSS.
Application d'un style à un code HTML
Dans une balise ouvrante, avec l'attribut STYLE
<EM style="color:silver;">texte en argenté</EM>
Le style ne vaut alors que pour le contenu balisé.
Dans l'en-tête du document HTML
<STYLE> ici des définitions de style </STYLE>
Les styles définis à cet endroit sont valables pour tout le contenu du document.
Fichier CSS externe
Les styles sont définis dans un fichier texte avec l'extension .css, sans utiliser de balise STYLE (ce fichier ne contient pas de HTML).
Puis dans l'en-tête du document HTML, on fait le lien avec ce fichier CSS :
Cette fois, les styles sont communs à tous les documents HTML qui incluront ce fichier CSS. Si les deux méthodes précédentes peuvent être utiles, c'est bien cette troisième qu'il faut privilégier sur un site Web.
Notion de boîte
La mise en page à l'aide de CSS repose sur la notion de boîte : il faut imaginer que tout contenu entre une balise ouvrante et une balise fermante est en fait dans une boîte. À l'aide des feuilles de style, on va pouvoir spécifier l'apparence du contenu de la boîte (color, font, background, etc.), les espackbdents à l'extérieur de la boîte (margin), les espackbdents à l'intérieur (padding), les bords (border), etc.
Naturellement, l'imbrication des balises implique une imbrication des boîtes. Ainsi, les éléments <LI> sont vus comme des boîtes contenus dans une boîte représentant la balise <UL>. Et tout le document est constitué de boîtes imbriquées dans la boîte <BODY>.
Il y a deux natures majeures et distinctes pour ces « boîtes » : block et inline. Les boîtes de type block prennent toute la largeur disponible et se placent les unes sous les autres. Les boîtes de type inline ne prennent que la largeur nécessaire et se placent l'une à côté de l'autre. Le type d'une boîte peut être changée à travers la propriété display. Nous verrons d'autres valeurs possibles et comportement associés en temps utile.
Unités de mesure
Différentes propriétés, comme les marges par exemple, nécessitent de donner une mesure. Pour exprimer une mesure, plusieurs unités sont disponibles en CSS.
Il y a des mesures absolues et habituelles comme : px, pt, pc, mm, cm, in.
Sont également disponibles des mesures relatives à la police actuellement utilisée : em (hauteur des majuscules de la police en cours), et en (hauteur des minuscules de la police en cours). Ou à la largeur disponible dans la boîte actuelle : %.
Enfin, des unités de mesure sont relatives au matériel utilisé par le visiteur, on parle d'unités viewport. viewport désigne la partie du navigateur qui affiche le document. vw et vh s'expriment en pourcentage des dimensions de cette surface, largeur et hauteur.
L'objectif à poursuivre est de s'adapter aux préférences de l'utilisateur et à son matériel. L'utilisation des unités relatives participe à cet objectif en garantissant une mise en forme fluide, adaptative, du document.
Parfois, on ne spécifiera pas de dimensions, mais on demandera à un objet de s'adapter, par exemple avec la propriété object-fit.
Notons enfin que le langage CSS nous permet de faire des calculs avec la fonction calc, en particulier au moment de spécifier une mesure.
calc(50% - 2em)
syntaxe générale
Le stylage CSS opère en deux temps :
- désigner/repérer l'élément du document que l'on veut styler,
- associer des propriétés de mise en forme à cet élément.
La combinaison sélection et propriétés prend la forme suivante en CSS :
sélecteur {
propriété_1: valeur_1;
propriété_2: valeur_2;
/* commentaire : ici suite éventuelle des propriétés */
}
Si les lignes propriété/valeur sont assez simple, l'expression des sélecteurs est lui sophistiqué.
Sélection/repérage des éléments
Le langage de requêtes utilisé participe à la puissance de CSS (on pourra penser à XPath par exemple).
Sélecteurs de types
C'est le cas le plus simple : on ne précise que le nom de l'élément concerné par la définition du style. Il est possible de faire partager le style par plusieurs balises (on sépare les noms des éléments par des virgules).
BODY { margin: 0.5cm; } H1 { font-family: Wide Latin; } H1, H2, H3 { font-family: Wide Latin, Arial Black, Helvetica, sans-serif; color: red; } P { color: blue; }
premiers exemples mettant en œuvre les mesures relatives vues à la section précédente
/* au moins toute la hauteur, ou plus si nécessaire */ body { min-height: 100vh; } /* on interdit aux images de déborder de la boîte parente */ img { max-width: 100%; } /* taille des images avec object-fit */ img { object-fit: cover; } /* calcul */ section { width: calc(50% - 2em); }
Sélecteurs de classe ou d'identifiant
Il est également possible de proposer des apparences différentes pour un même élément. Nous avons précédemment décrit le style associé de manière générale aux balises P et nous allons maintenant définir un autre style pour certains paragraphes dits ecolo. Cela passe par une distinction dans le code HTML, on précise la classe des paragraphes concernés.
<P CLASS="ecolo"> un paragraphe... </P>
Puis, on utilisera la syntaxe suivante pour décrire les caractéristiques de ces paragraphes particuliers :
P.ecolo { color: green; }
Plus généralement, on peut spécifier l'apparence d'une classe sans préciser d'élément :
.ecolo { color: green; }
Le style vaut alors pour les éléments portant cette classe. Ici cela aura pour effet de faire apparaître en vert toutes les textes contenus dans balises de classe ecolo :
<H1 CLASS="ecolo">Titre militant</H1> <P CLASS="ecolo"> un paragraphe qui parle d'écologie... </P>
Enfin, il est possible de ne donner un style que pour une apparition unique d'un élément donné. Pour cela, il faut repérer la balise ouvrante correspondant en lui donnant un identifiant unique :
<P ID="intro"> bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla introductif </P>
Puis de définir le style du paragraphe nommé intro en utilisant l'une des syntaxes suivantes :
P#intro { color: blue; } #intro { color: blue; }
L'unicité d'un identifiant ne vaut que dans un même document. Ainsi, chaque document de notre site Web peut avoir (ou non) une intro, mais pas plus d'une, et toutes apparaîtront de la même manière.
Sélecteurs d'attributs
à rédiger : href, lang, title
Par contexte
Stylage d'un descendant :
relation de parenté dans l'arbre html
UL LI { font-size: small}
UL LI LI { font-size: x_small} /* stylage des items li descendants eux-mêmes d'un item li */
Stylage d'un descendant direct :
section > h1 { color: red; } /* stylage des titres h1 fils directs d'une section */
Stylage du frère suivant (next sibling) : avec le symbole +.
Par pseudo-classes
Les pseudo-classes permettent de repérer et de styler certains contenus déjà balisés, comme si l'on leur rajoutait une classe :
A:link A:hover /* passage de la souris sur le lien */ A:active A:visited :hover /* passage de la souris sur un élément quelconque */ :focus :lang p.ecolo:link {color: lime } p.ecolo:visited {color: olive } :not() /* négation */ tr:nth-child(even) / tr:nth-child(odd) li:first-child / li:last-child
Par pseudo-éléments
Les pseudo-éléments permettent de repérer et de styler certains contenus qui ne sont pas balisés, comme si l'on leur rajoutait des balises autour :
P::first-line P::first-letter ::before ::after
Stylage d'éléments html en CSS
Nous regardons maintenant ce qu'il est possible de spécifier dans l'apparence des éléments sélectionnés.
Propriétés de police
- font-family : suite de noms de polices (si l'une manque sur la machine du client, on essayera
la suivante), terminée par le nom d'une famille de polices (si aucune police n'a été trouvée,
on prendra une police dans la famille spécifiée) ; cinq familles sont distinguées :
- serif (Times, etc.)
- sans-serif (Arial, Helvetica, etc.)
- cursive
- monospace (machine à écrire comme Courrier)
- fantasy
- font-size : taille de la police avec l'unité précisée
- font-style : normal, italic, oblique
- font-variant : normal, small-caps
- font-weight : de 100 à 900, normal, bold
h3 { font-family: Arial, Helvetica, sans-serif; font-size: 120%; font-variant: small-caps; font-weight: bold; }
Mise en forme du texte
- white-space : (normal, pre, nowrap)
- word-spacing : l'espace entre les mots
- letter-spacing : l'espace entre deux lettres au sein d'un même mot
- text-decoration : (none, underline, overline, line-through, blink)
- text-transform (none, uppercase, lowercase, capitalize)
- text-shadow : affiche l'ombre projetée du texte.
Pour faire disparaître le soulignement des liens :
A:hover { text-decoration: none; }
Agencement du texte
- text-align : left, center, right, justify
- text-indent : taille du retrait de première ligne
- line-height : hauteur de ligne
- vertical-align : baseline, super, top, text-top, middle, text-bottom, bottom, sub
Mise en forme de listes
- list-style-type : type de numérotation ou de puce (none, decimal, lower-alpha, upper-alpha, lower-roman, upper-roman, disc, circle, square)
- list-style-image permet de spécifier une image servant de puce pour les listes (none ou url(nom de fichier image))
- list-style-positionposition de la liste par rapport au reste du texte, décalage vers la droite ou pas inside, outside
- list-style
Couleurs et arrière-plans
- color : couleur du texte
- background-color : couleur du fond
- background-image : image de fond (nom ou url)
- background-repeat : mode de réplication de l'image de fond (repeat, repeat-x, repeat-y, no-repeat)
- background-attachement : défilement ou non de l'image de fond (scroll, fixed)
- background-position : position d'ancrage du coin supérieur gauche de l'image de fond dans l'élément stylé
Exemple couleur du texte + couleur de fond.
background-position avec des valeurs négatives et en jouant sur hauteur et largeur de l'élément, on fait des sprites.
Retraits extérieurs et intérieurs
- margin, margin-top, margin-bottom, margin-left, margin-right : retraits extérieurs ;
- padding, padding-top, padding-bottom, padding-left, padding-right : retraits intérieurs.
Encadrements
- border, border-top, border-bottom, border-left, border-right
- border-style, border-style-top, border-style-bottom, border-style-left, border-style-right : solid, double, groove, ridge, inset, outset, dotted, dashed
- border-width
- border-color.
Nature/apparence de la boîte
ici ou à la section suivante ? ou ailleurs ?
- display (block, inline, etc.), visibility...
- width, height, max et min
- overflow
Mises en page avec CSS
Accessibilité : l'ordre html doit rester optimal pour une personne malvoyante.
Colonnage
affichage d'un contenu en colonnes : on précise le nombre de colonnes ou leurs tailles
column-count: 2; /* column-width: 400px; */ /* columns */ column-gap: 5em; /* column-rule-style: solid; column-rule-width: 3px; column-rule-color: #add8e6; */ column-rule: solid 3px white;
Tableaux
on reprend la notion html de table
display: table|table-cell|table-row + list-item
Positionnement éléments-boîtes
- float
- position : fixed, static, absolute, relative
- top
- left
- width
- height
- visibility : visible, hidden
- z-index : indique dans quel ordre doivent apparaître des éléments superposés (uniquement pour des éléments positionnés de manière absolue).
flexbox
flex box : « flexible box »... pour des boîtes flexibles !
conteneur/contenant et items
dans le container
display: flex; /* => block */ display: inline-flex; /* => inline-block mais enfants en ligne */ flex-direction: row | row-reverse, column, column-reverse flex-wrap: nowrap | wrap | wrap-reverse /* gestion dépassements horizontal/vertical */ flow: flex-direction + flex-wrap /* justification des enfants dans la direction choisie */ justify-content: flex-start | flex-end |center | space-between | space-around /* alignement sur l'axe secondaire */ align-items: stretch | flex-start | flex-end | center | baseline /* gestion des passages à la lignes (provoqués par flex-wrap:wrap) sur l'axe secondaire vertical */ align-content: stretch | flex-start | flex-end | center | space-between | space-around
dans les items
order align-self : écrase localement align-items (mêmes valeurs possibles) /* proportion de la place disponible à occuper */ flex-grow : 0 | 1 | 2 | ... /* autoriser ou non le rétrecissement */ flex-shrink : 1 | 0 /* largeur */ flex-basis : auto par défaut, ou valeur numérique il est parfois utile d'indiquer 0% flex : flex-grow + flex-shrink + flex-basis attention les valeurs « initiales » ne sont pas les valeurs défaut si l'on omet de les préciser
grid
principe : on définit un quadrillage. on place les éléments dans les cases ainsi définies, ou dans des zones de plusieurs cases contigües.
à nouveau conteneur et enfants-items
pour l'élément conteneur
display: grid | inline-grid; on définit des traits horizontaux et verticaux, lesquels définissent des lignes et des colonnes (*tracks*), des cellules, des zones de plusieurs cellules et espaces entre lignes et colonnes (*gaps). grid-template-columns : la largeur donnée à chaque colonne grid-template-rows : la largeur donnée à chaque ligne grid-template: grid-template-rows / grid-template-columns (unité fr pour fraction) (possibilité de nommer les traits initiaux) possibilité de nommer les zones : grid-template-areas row-gap: dimension column-gap: dimension gap: row-gap column-gap /* gestion des dépassements */ grid-auto-flow: row | column /* largeur des colonnes et lignes supplémentaires */ grid-auto-columns grid-auto-rows /* justification horizontale des enfants */ justify-content: flex-start | flex-end |center | space-between | space-around /* gestion des passages à la lignes */ align-content: stretch | flex-start | flex-end | center | space-between | space-around align-items /* ... */
pour l'éléments enfants-items
numéros des colonnes (début et fin) sur lesquelles s'étend l'élément grid-column-start grid-column-end grid-column: start / end grid-area: le nom d'une zone définie dans le parent-conteneur align-self /* ... */
Diffusion vers différents médias
Nous avons vu que nous pouvions adapter certaines mises en forme aux préférences de l'utilisateur, en utilisant systématiquement des unités de mesure relatives. C'est une bonne pratique mais elle est insuffisante pour prétendre s'adapter à tous les appareils. Dans cette section, nous verrons comment cibler certains appareils spécifiques, et même comment s'adapter aux caractéristiques de chaque appareil.
Association de styles à un média particulier
Il est possible de préciser le média auquel est dédié une feuille de style. Les médias possibles sont : all, aural, braille, embossed, handheld, print, projection, screen, tty, tv.
La précision du média visé peut se faire dans l'en-tête de la page HTML :
<LINK REL="stylesheet" HREF="site.css" MEDIA="screen"> <LINK REL="stylesheet" HREF="print.css" MEDIA="print">
ou au sein d'une même feuille de style :
@media print { BODY { font-size: 10pt } } @media screen { BODY { font-size: 12pt } }
Aujourd'hui les objets connectés permettant de visualiser des pages web sont devenus très divers et ce mécanisme n'est plus suffisant pour traiter toutes les possibilités. En particulier, handheld ne peut pas permettre de spécifier un affichage qui conviendrait à tous les smartphones, tablettes et ordinateurs portables !
Media queries et responsive web design
initial-scale
Obtenir des informations sur l'appareil utilisé par le visiteur de notre site Web : taille de l'écran, orientation, mode clair ou sombre, etc.
@media screen and (max-width: 640px) { body { color : red; background-color: black; } } @media screen and (min-width: 640px) and (max-width: 1280px) { body { color : black; background-color: red; } }
Un principe : mobile first plutôt que responsive degradation.
orientation...
@media screen and (orientation:portrait) { div.menu { display: none; visibility: hidden; } }
Préférence sombre/clair
@media (prefers-color-scheme: light) { body { color: black; background-color: white; } } @media (prefers-color-scheme: dark) { body { color: white; background-color: black; } }
Le média print
On a vu que l'attribut media pouvait accueillir la valeur print. Nous regardons les pratiques CSS propres à ce média.
- faire disparaître certains éléments : display: none;
- écrire noir sur blanc pour faciliter la lisibilité économiser la cartouche d'encre couleurs
- réduire les marges pour économiser le papier
- choix classiques pour faciliter l'impression et la lecture : format (a4), police (serif) et taille (12pt)
- justification du texte
saut de page
page-break-|before|inside|after: auto|always|avoid
liens ? montrer l'url du lien avec la propriété content et la fonction attr() ?
content: attr(href)
limiter veuves et orphelines : widows et orphans par défaut : 2 (au moins 1 lignes en fin et début de page, jamais 1) dans une règle @page