Chapitre 10. CSS

10.1. Principe

Le principe des feuilles de style CSS est de séparer le contenu de la forme. Elles sont beaucoup utilisées avec HTML et XHTML mais elles peuvent aussi l'être avec XML (cf. exemple avec la bibliographie).

Les rôles des XSLT et CSS sont différents et même complémentaires. Le rôle de XSLT est de transformer le document source en un autre document résultat, XHTML par exemple. Il s'agit donc d'agir sur le contenu et en particulier sur la structure de ce contenu. Au contraire, CSS ne permet pas (ou très peu) de changer le contenu. Il peut uniquement intervenir sur la présentation. Une bonne solution est d'utiliser XSLT et CSS de pair. XSLT produit un document XHTML dont la présentation est contrôlée par une feuille de style CSS.

10.2. Règles

Une feuille de style est formée de règles qui ont la forme suivante. Les espaces et les retours à la ligne jouent uniquement un rôle de séparateurs. L'indentation de la feuille de style est donc libre.

selector { 
    property1: value1;
    property2: value2; 
    ...
    propertyN: valueN; 
}

Le sélecteur selector détermine quels sont les éléments auxquels s'applique la règle. Les propriétés property1, property2, …, propertyN de tous ces éléments prendront les valeurs respectives value1, value2, …, valueN. Chaque valeur est séparée du nom de la propriété par le caractère ':'. Le caractère ';' sépare les couples propriété/valeur de la règle. Il n'est donc pas indispensable après le dernier couple de la règle.

Des commentaires peuvent être mis dans les feuilles de styles en dehors ou dans les règles en utilisant une syntaxe identique à celle du langage C. Ils commencent par les deux caractères '/*' et se terminent par les deux caractères '*/'.

L'exemple ci-dessous est la feuille de style utilisée pour la présentation de cet ouvrage au format HTML.

/* Fond blanc */
body { 
    background-color: white; 
}

/* Equations et figures centrées */
p.equation, p.figure {
    text-align: center;
}

/* Zone de code : fond jaune clair, bordure noire et marges */
pre {
    background-color: #ffffcc;
    border: 1px solid black;
    margin: 10px;
    padding: 5px;
}

10.2.1. Média

Les règles d'une feuille de style peuvent dépendre du média utilisé pour rendre le document. Par média, on entend le support physique servant à matérialiser le document. Il peut s'agir d'un écran d'ordinateur, d'un projecteur, de papier. La syntaxe est la suivante.

@media medium {
    /* Règles pour le média */
    ...
}

Les principales valeurs possibles pour medium sont screen pour un écran d'ordinateur, print pour du papier et projection pour un projecteur.

10.2.2. Sélecteurs

Un sélecteur prend la forme générale suivante. Il est constitué par une suite de sélecteurs séparés par des virgules. Il sélectionne alors tous les éléments sélectionnés par chacun des sélecteurs individuels.

 selector1, selector1, ..., selectorN

La forme la plus simple d'un sélecteur est le nom name d'un élément comme h1, p ou encore pre. Tous les éléments de nom name sont alors sélectionnés. Dans l'exemple suivant, le fond de l'élément body, c'est-à-dire de tout le document, est blanc.

body { 
    background-color: white; 
}

Tous les éléments dont l'attribut class contient la chaîne classname peuvent être sélectionnés par le sélecteur .classname où la valeur de l'attribut est précédée d'un point '.'.

L'attribut class d'un élément peut contenir plusieurs chaînes séparées par des espaces comme dans l'exemple suivant. Un sélecteur de forme .classname sélectionne un élément si la chaîne classname est une des chaînes de la valeur de l'attribut class.

<p class="numbered equation"> ... </p>

Cette forme de sélecteur peut être combinée avec le nom name d'un élément pour former un sélecteur name.classname qui sélectionne tous les éléments de nom name dont l'attribut class contient la chaîne classname. Dans l'exemple suivant, tous les éléments p de classe equation ou figure auront leur texte centré.

p.equation, p.figure {
    text-align: center;
}

L'élément unique dont l'attribut id a la valeur name peut être sélectionné par le sélecteur #name où la valeur de l'attribut est précédée d'un dièse '#'. Dans l'exemple suivant, le contenu de l'élément h1 dont l'attribut id vaut title sera de couleur rouge.

h1#title { color: red }

Le sélecteur '*' sélectionne tous les éléments. Dans l'exemple suivant, tous les éléments (c'est-à-dire le texte) seront de couleur bleue à l'exception des éléments p qui seront de couleur grise.

* { color: blue }
p { color: gray }

Certaines parties d'un document qui ne correspondent pas à un élément peuvent être sélectionnées par des pseudo-éléments. La première ligne et le premier caractère du contenu d'un élément name peuvent être désignés par name:first-line et name:first-letter.

p:first-line {
    text-indent: 15pt;
}

Le pseudo-élément :first-child permet en outre de sélectionner le premier enfant d'un élément. Dans l'exemple suivant, la règle s'applique uniquement à la première entrée d'une liste.

li:first-child {
    color: blue;
}

Les pseudo-éléments :before et :after et la propriété content permettent d'ajouter du contenu avant et après un élément.

li:before {
    content: "[" counter(c) "]";
    counter-increment: c;
}

Les pseudo-classes :link, :visited, :hover et :active s'appliquent à l'élément a et permettent de sélectionner les liens, les liens déjà traversés, les liens sous le curseur et les liens activés.

a:link    { color: blue; }
a:visited { color: magenta; }
a:hover   { color: red; }
a:active  { color: red; }

La pseudo-classe :focus permet de sélectionner l'entrée d'un formulaire qui a le focus.

Un sélecteur peut aussi prendre en compte la présence d'attributs et leurs valeurs. Un ou plusieurs prédicats portant sur les attributs sont ajoutés à un sélecteur élémentaire. Chacun des prédicats est ajouté après le sélecteur entre crochet '[' et ']'. Les différents prédicats possibles sont les suivants.

[att]

L'élément est sélectionné s'il a un attribut att quelque soit sa valeur.

[att=value]

L'élément est sélectionné s'il a un attribut att dont la valeur est exactement la chaîne value.

[att~=value]

L'élément est sélectionné s'il a un attribut att dont la valeur est une suite de chaînes séparées par des espaces dont l'une est exactement la chaîne value. Le sélecteur .classname est donc une abréviation de [class~="classname"].

[att|=value]

L'élément est sélectionné s'il a un attribut att dont la valeur est une suite de chaînes de caractères séparées par des tirets '-' dont la première chaîne est égale à la chaîne value.

Dans l'exemple suivant, la règle s'applique aux éléments p dont l'attribut lang commence par en- comme en-GB ou en-US mais pas fr. La propriété quote définit quels caractères doivent entourer les citations.

p[lang|="en"] {
    quotes: '"' '"' "'" "'";
}

Il est possible de mettre plusieurs prédicats portant sur les attributs comme dans l'exemple suivant. Le sélecteur suivant sélectionne les éléments p ayant un attribut lang de valeur fr et un attribut type de valeur center.

p[lang="fr"][type="center"] { 
    ...
}

Il est possible de composer des sélecteurs avec les trois opérateurs ' ' (espace), '>' et '+' pour former des nouveaux sélecteurs.

Le sélecteur selector1 selector2 sélectionne tous les éléments sélectionnés par selector2 qui sont en outre descendants dans l'arbre du document (c'est-à-dire inclus) d'un élément sélectionné par selector1. Dans l'exemple suivant, seuls les éléments em contenus directement ou non dans un élément p auront leur texte en gras.

p em { 
    font-weight: bold;
}

Cet opérateur peut aussi combiner plusieurs sélecteurs. Dans l'exemple suivant, sont sélectionnés les éléments de classe sc contenus dans un élément em lui même contenu dans un élément p. Il y a bien un espace entre em et .sc. Le sélecteur p em.sc est bien sûr différent.

p em .sc { 
    font-variant: small-caps;
}

Le sélecteur selector1 > selector2 sélectionne tous les éléments sélectionnés par selector2 qui sont en outre enfant (c'est-à-dire directement inclus) d'un élément sélectionné par selector1.

Le sélecteur selector1 + selector2 sélectionne tous les éléments sélectionnés par selector2 qui sont en outre frère droit (c'est-à-dire qui suivent directement) d'un élément sélectionné par selector1.

10.2.3. Propriétés

Les propriétés qui peuvent être modifiées par une règle dépendent des éléments sélectionnés. Pour chaque élément de XHTML, il y a une liste des propriétés qui peuvent être modifiées.

10.2.4. Valeurs

Les valeurs possibles dépendent de la propriété. Certaines propriétés acceptent comme display uniquement un nombre déterminé de valeurs. D'autres encore prennent une couleur, un entier, un pourcentage, un nombre décimal ou une dimension avec une unité.

Pour les dimensions, il est nécessaire de faire suivre le nombre d'une unité parmi les unités suivantes.

SymboleUnité
pxpixel
ptpoint = 1/72 in
pcpica = 12 pt
emlargeur du M dans la police
exhauteur du x dans la police
inpouce
mmmillimètre
cmcentimètre

Tableau 10.1. Unités des dimensions en CSS


10.3. Héritage et cascade

Certaines propriétés sont automatiquement héritées comme color. Cela signifie qu'un élément hérite de la valeur de cette propriété de son père sauf si une règle donne une autre valeur à cette propriété. D'autres propriétés comme background-color ne sont pas héritées. On peut donner la valeur inherit à n'importe quelle propriété pour forcer l'héritage de la valeur du père.

Comme la propriété color est héritée, la règle suivante impose que le texte de tout élément est noir à l'exception des éléments pour lesquels cette propriété est modifiée.

body {
    color: black;
}

10.3.1. Provenance de la valeur

La valeur d'une propriété pour un élément peut avoir les trois provenances suivantes par ordre de priorité décroissante.

  1. La propriété est modifiée par au moins une règle qui sélectionne l'élément. La valeur de la propriété est alors donnée par la règle de plus grande priorité (cf. ci-dessous).

  2. Si aucune règle ne donne la valeur de la propriété et si la propriété est héritée, la valeur est égale à la valeur de la propriété pour le père.

  3. Si la propriété n'est pas héritée ou si l'élément est la racine du document, la valeur de la propriété est alors une valeur par défaut appelée valeur initiale.

10.3.2. Cascade

Plusieurs règles peuvent s'appliquer à un même élément. Il y a souvent plusieurs feuilles de style pour le même document : une feuille de style par défaut pour l'application, une autre fournie par l'auteur du document et éventuellement une feuille donnée par l'utilisateur. De plus, une même feuille peut contenir plusieurs règles qui sélectionnent le même élément.

La priorité d'une règle est d'abord déterminée par sa provenance. La feuille de style de l'auteur a priorité sur celle de l'utilisateur qui a elle-même priorité sur celle de l'application.

Pour les règles provenant de la même feuille de style, on applique l'algorithme suivant pour déterminer leur priorité. On calcule une spécificité de chaque sélecteur qui est un triplet (a,b,c) d'entiers. L'entier a est le nombre d'occurrences de prédicats sur l'attribut id de forme #ident. L'entier b est le nombre de prédicats sur les autres attributs y compris les attributs class de forme classname. Le nombre c est finalement le nombre de noms d'éléments apparaissant dans le sélecteur. Les spécificités (a,b,c) et (a',b',c') des sélecteurs des deux règles sont alors comparées par ordre lexicographique. Ceci signifie qu'on compare d'abord a et a', puis b et b' si a est égal à a', puis finalement c et c' si (a,b) est égal à (a',b').

Pour des règles dont les sélecteurs ont même spécificité, c'est l'ordre d'apparition dans la feuille de style qui détermine la priorité. La dernière règle apparue a une priorité supérieure.

10.4. Modèle de boîtes

Chaque élément (au sens usuel ou au sens XML) est mis dans une boîte au moment de la mise en page. Cette boîte englobe le contenu de l'élément. Elle a aussi un espacement intérieur (padding en anglais), une bordure (border) et une marge (margin) (cf. figure ci-dessous).

Modèle de boîte

Figure 10.1. Modèle de boîte


Chaque boîte est positionnée à l'intérieur de la boîte englobante de son père. Le positionnement des éléments dans une boîte englobante est d'abord déterminé par le type de la boîte englobante. Les types principaux possibles pour une boîte sont bloc (block) ou en ligne (inline), table, entrée de liste (list-item). Les éléments d'une boîte de type bloc sont assemblés verticalement alors que ceux d'une boîte de type en ligne sont assemblés horizontalement.

Le type de la boîte est contrôlée par la propriété display de l'élément. Les principales valeurs que peut prendre cette propriété sont block, inline, list-item et none. Cette dernière valeur permet de ne pas afficher certains éléments. Il est ainsi possible de créer des pages dynamiques en modifiant avec des scripts la valeur de cette propriété.

La propriété position détermine comment l'élément est positionné dans la boîte englobante de l'élément père. La valeur static signifie que l'élément est positionné automatiquement par l'application dans le flux d'éléments. La valeur relative signifie que les valeurs des propriétés top, right, bottom et left donnent un déplacement par rapport à la position normale. Pour les valeurs absolute et fixed, les propriétés top, right, bottom et left fixent la position par rapport à la page ou par rapport à la fenêtre de l'application.

10.5. Style et XML

On reprend le document bibliography.xml avec la feuille de style CSS suivante attachée.

/* Feuille de style pour la bibliographie */

bibliography {
    display: block;
    border: 1px solid black;
    margin: 30px;
    padding: 20px;
}

/* Mode liste sans marque */
book { 
    display: list-item;
    list-style: none;
}

/* Calcul de la marque */
book:before {
    content: "[" counter(c) "]";
    counter-increment: c;
}

/* Titre en italique */
title {
    font-style: italic;
}

/* Virgule après chaque champ */
title:after,  author:after,  year:after, publisher:after {
 content: ", ";
}

/* Fonte sans-serif pour l'url */
url {
    font-family: sans-serif;
}

/* Virgule avant l'URL si elle est présente */
url:before {
    content: ", ";
}

10.6. Attachement de règles de style

Les règles de style concernant un document peuvent être placées à différents endroits. Elles peuvent d'abord être mises dans un fichier externe dont l'extension est généralement .css. Le document fait alors référence à cette feuille de style. Les règles de style peuvent aussi être incluses directement dans le document. Pour un document XHTML, elles peuvent se placer dans un élément style de l'entête. Elles peuvent aussi être ajoutées dans un attribut style de n'importe quel élément.

10.6.1. Référence à un document externe

La façon de référencer une feuille de style externe dépend du format du document. Pour un document XML, il faut utiliser une instruction de traitement xml-stylesheet. Pour un document XHTML, il faut utiliser un élément link dans l'entête.

<?xml-stylesheet type="text/css" href="bibliography.css" ?>
<head>
  <title>Titre de la page</title>
  <link href="style.css" rel="stylesheet" type="text/css" />
</head>

10.6.2. Inclusion dans l'entête du fichier XHTML

Les règles de style peuvent être directement incluses dans un élément style de l'entête, c'est-à-dire contenues dans l'élément head. Il est préférable de protéger ces règles par des balises '<!--' et '-->' de commentaires.

<head>
 <title>Titre de la page</title>
 <style type="text/css"><!--
   /* Contenu de la feuille de style inclus dans un commentaire XML */
   body { background-color: white; }
 --></style>
</head>

10.6.3. Inclusion dans un attribut d'un élément

Chaque élément peut aussi avoir un attribut style qui contient uniquement des couples propriété/valeur séparés par des virgules. Les sélecteurs sont inutiles puisque ces règles s'appliquent implicitement à cet élément.

<span style="text-decoration: overline">A</span>

10.7. Principales propriétés

10.7.1. Polices de caractères et texte

PropriétéValeur
colorcouleur
fontcombinaison des propriétés font-*
font-familynom de police, serif, sans-serif, cursive, fantasy ou monospace
font-style normal, italic, oblique
font-variant normal, small-caps
font-weight normal, bold, bolder ou lighter
font-sizedimension
text-decoration none, underline, overline, line-through ou blink
text-transform none, capitalize, uppercase ou lowercase
word-spacingnormal ou dimension
letter-spacingnormal ou dimension
vertical-align baseline, sub, super, top, text-top, middle, bottom, text-bottom ou pourcentage
text-align left, right, center ou justify
text-indentdimension ou pourcentage
line-height normal, facteur, dimension ou pourcentage
white-space normal, pre, nowrap, pre-wrap ou pre-line
contentchaîne de caractères

10.7.2. Fond

PropriétéValeur
backgroundcombinaison des propriétés background-*
background-attachement scroll ou fixed
background-colorcouleur
background-imageimage
background-positionpourcentage, dimension ou (top, center ou bottom) et (left, right ou center)
background-repeat no-repeat, repeat-x, repeat-y ou repeat

10.7.3. Boîtes et positionnement

PropriétéValeur
width height auto, dimension ou pourcentage
padding padding-top padding-right padding-bottom padding-left dimension ou pourcentage
border-style none, dotted, dashed, solid, double, groove, ridge, inset ou outset
border-width medium, thin, thick ou une dimension
border-color couleur
margin margin-top margin-right margin-bottom margin-left auto, dimension ou pourcentage
position static, relative, absolute ou fixed
top right bottom left auto, dimension ou pourcentage
float none, left ou right
clear none, left, right ou both
overflow visible, hidden, scroll ou auto
visibility visible ou hidden

10.7.4. Listes

PropriétéValeur
list-styleCombinaison des trois propriétés list-style-*
list-style-imageimage
list-style-position outside ou inside
list-style-type none, disc, circle, square, decimal, upper-Roman, lower-Roman, upper-alpha ou lower-alpha