Tutoriel HTML & CSS

Par Sébastien Laoût
Version 0.3

Nous venons de voir comment créer des pages HTML qui ne contiennent que le contenu.
Ce n'est pas très beau, et c'est normal : nous allons maintenant aborder le CSS, le format qui vous permettra de définir la forme. Mais avant de jouer avec, nous devons d'abord voir comment se forme le CSS : c'est la partie théorique.
Note : si la théorie ne vous dit rien, vous pouvez lire la page sur les Exemples CSS, où nous allons directement mettre en forme la ou les page(s) créées précédemment. Cependant, si vous ne comprenez pas certaines choses, n'hésitez pas à revenir sur cette page et à la lire !

La syntaxe

Un fichier CSS permet de changer radicalement l'affichage de plusieurs pages HTML.
La structure d'un fichier CSS est simple (plus que celle d'un fichier HTML).
Un fichier CSS est composé de plusieurs règles. Chaque règle permet de changer l'affichage de plusieurs balises HTML. Les règles ont la syntaxe suivante :

sélecteur {
  propriété-1: valeur-1;
  propriété-2: valeur-2;
  propriété-n: valeur-n;
}

Expliquons cette structure avec quelques définitions :

Pour illustrer ce que nous venons de voir, nous allons voir comment centrer le titre de niveau 1 de nos pages Web.
Vous savez que celui-ci s'écrit <h1>Mon titre de page</h1> en HTML. Il utilise la balise h1, donc nous devons appliquer un style à cette balise, le sélecteur sera tout simplement "h1". Nous voulons centrer le texte, il s'agit donc de la propriété "text-align" (ne vous inquiétez pas : je vous donnerez la liste des propriétés), et nous devons lui donner la valeur "center". Cela se traduit donc par :

h1 {
  text-align: center;
}

Si maintenant nous voulons une couleur bleue pour ce même titre, nous devons appliquer une seconde déclaration (couple "propriété: valeur") pour le même sélecteur h1 : il s'agit de la propriété "color", et nous lui donnons la valeur "blue". Ce qui donne :

h1 {
  text-align: center;
  color: blue;
}

Comme vous le voyez, c'est simple. De manière générale, le code CSS balise { propriété: valeur; } servira à relooker le contenu de la balise <balise></balise> du fichier HTML correspondant. Nous allons maintenant voir des sélecteurs plus complexes, mais plus intéressants.

Avant de commencer la lecture, et pour vous donner l'envie d'apprendre,
Découvrez Snaky 360, le jeu de serpent addictif réalisé par l'auteur de ce tutoriel...



Créé entièrement en HTML, CSS et JavaScript, sans Flash
(sauf pour les musiques et effets sonores, en attendant HTML 5)
Bientôt, vous pourrez en faire de même !

Lier le CSS au HTML

En règle générale, vous placerez toutes les règles CSS dans un fichier portant l'extenssion .css. En général, il se nommera style.css.
Le fichier contenant les instructions CSS (fichier .css, ou feuille de style CSS) doit être lié à toutes les pages HTML auxquelles on veut en changer l'affichage. Dans chaque page HTML, il faut utiliser la syntaxe suivante, à placer dans le <head> :

<link rel="stylesheet" type="text/css" href="style.css">

Remplacez bien entendu "style.css" par le nom de votre fichier CSS, ou son chemin relatif ou absolu, s'il se trouve dans un dossier différent du dossier contenant la page HTML.
À noter que le fichier style.css dans href est un chemin relatif à la page HTML actuelle.
Par contre, les images référencées à l'intérieur du fichier CSS sont relatives au dossier contenant le fichier CSS. Ceci permet ainsi d'inclure le fichier CSS dans des pages HTML d'origines différentes. Nous aurons l'occasion de revenir sur ce fait.


Voici un exemple où nous reprenons le squelette de page HTML vu dans l'onglet précédent, et nous lui ajoutons la ligne ci-dessus :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>Ma page</title>
    <link rel="stylesheet" type="text/css" href="style.css">
  </head>
  <body>
    <h1>Titre de page</h1>
    <h2>Titre</h2>
  </body>
</html>

Le fichier style.css, quand à lui, pourra ressembler à ceci :

h1 { color: navy; }
h2 { color: blue; }

Dans cet onglet, les bouts de code CSS devront être placées dans un fichier style.css, et les bouts de code HTML dans un fichier .html.


Il existe une seconde méthode, qui permet de placer le CSS directement dans le fichier HTML. Ici, on perd en flexibilité car le code CSS doit être copié dans chaque page HTML. À l'avenir, il faudra alors modifier toutes les pages HTML pour modifier le style. Ce mix du HTML et du CSS nous fait donc perdre en clarté et en maintenabilité. Mais cela peut être intéressant, pour envoyer une page seule par email, par exemple, sans avoir à s'assurer qu'un fichier style.css est toujours présent à ses côtés. Dans ce cas, le fichier HTML a l'allure suivante :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>Ma page</title>
    <style type="text/css">
      h1 { color: navy; }  
      h2 { color: blue; }  
    </style>               
  </head>
  <body>
    <h1>Titre de page</h1>
    <h2>Titre</h2>
  </body>
</html>

Un troisième et dernière façon différente d'appliquer du style aux balises est d'insérer des déclarations CSS directement sur les balises HTML concernées. Ici, on ne peut placer que des déclarations, c'est à dire des couples "propriété: valeur;" qu'il y aurait généralement entre les accolades. On y place pas de règles entières, car les balises HTML servent de sélecteurs. Cette solution est donc plus restrictive, encore moins flexible que la précédente, mais et rapide et peut servir ponctuellement pour des tests, par exemple.. Reprenons l'exemple précédent avec le code CSS inséré "en ligne" :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>Ma page</title>
  </head>
  <body>
    <h1 style="color: navy;">Titre de page</h1>
    <h2 style="color: blue;">Titre</h2>
  </body>
</html>

Les éditeurs visuels et le CSS :
Certains éditeurs graphiques WYSIWYG vous permettent d'assigner du CSS à des éléments en utilisant la troisième méthode. L'utilisation de ces éditeurs peut être d'une aide utile, mais veillez à vérifier que le code résultant est propre et évolutif en mettant le code dans un fichier de feuille de styles à part. Si ce n'est pas possible, considérez de créer un fichier style.css et de le remplir à la main. Certes, cette démarche est plus compliquée mais sur le long terme, lorsque vous aurez plus d'assurance dans le CSS, ce sera plus bénéfique.

Les sélecteurs

Maintenant que nous avons vu la syntaxe générale des règles CSS, voyons plus en détails les sélecteurs disponibles, puis les propriétés disponibles.
Un sélecteur permet de définir à quelles balises un style donné doit être appliqué.
Concrètement, voici la liste des sélecteurs possibles accompagnés d'exemples.
Les sélecteurs suivants peuvent être combinés pour effectuer un "filtrage" plus précis des balises auxquelles appliquer le style que vous souhaitez.

Sélecteur universel : *

Permet de sélectionner toutes les balises, sans exception. Ce sélecteur peut sembler vide de sens, mais nous verrons plus bas qu'en le combinant à d'autres, il peut se montrer utile. Ainsi, la règle suivante s'appliquera à toute la page, pour définir la taille du texte de tous les éléments, en incluant les titres (qui ont une plus grande taille par défaut) :

* {
  font-size: 14px;
}

Sélecteur de types : balise

Nous l'avons vu plus haut, indiquer le nom d'une balise permet de restraindre la règle à un seul type de balise. Ainsi, pour colorer tous les liens de la page (balises "a") en bleu, vous pouvez suivre cet exemple :

a {
  color: blue;
}

Sélecteur de descendants : balise_mère balise_descendante

L'espace simple est en quelque sorte aussi un sélecteur. Pour restraindre le style aux balises contenues dans une certaine zone de la page, il est possible d'utiliser ce sélecteur. Il ne sélectionnera que les balises dont le nom est "balise_descendante", et dont elles sont contenues dans "balise_mère". Que ce soit des balises filles, des balises petites-filles, des balises petites-petites-filles, des balises... enfin je pense que vous avez compris ! Notez bien que le style s'appliquera aux balises "balise_descendante". Ainsi, le code CSS suivant ne sélectionnera que les balises <li> contenue dans d'autres balises <li>. Soit, comme vu dans le tutoriel HTML, uniquement les lignes de sous-listes, et non cettes de listes principales :

li li {
  font-size: 10px;
}

Ainsi, il est possible de styler les lignes d'une liste principale (avec le sélecteur "li") avec une grande taille de police, puis les lignes d'une sous-liste (avec le sélecteur "li li") avec une taille de police plus petite, et les lignes d'une sous-sous-liste (sélecteur "li li li") avec une taille de police encore plus petite. Voici un exemple de code HTML montrant quelles lignes sont impactées par le code CSS précédent :

<ul>
  <li>Cette ligne n'est pas concernée par le code CSS ci-dessus.</li>
  <li>
    <ul>
      <li>Cette ligne est concernée car elle est définie
        par une balise li, elle même contenue dans une balise li mère.</li>
    </ul>
    <ul>
      <li>Cette ligne est aussi concernée.
        <ul>
          <li>Ainsi que celle-ci.</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Mais pas cette ligne.</li>
</ul>

Sélecteur d'enfants : balise_mère > balise_fille

Si vous tenez à ce qu'une règle ne s'applique qu'à une balise directement fille, vous devez utiliser le sélecteur '>'. Par exemple, vous voulez styler une balise image à l'intérieur d'un paragraphe, mais pas si elle est à l'intérieur d'un lien. Le code d'exemple suivant déplacera toutes les images d'un paragraphe sur la droite de la page (comme des illustrations d'articles de magazines) mais laissera les images à l'intérieur des liens à leur place (comme des petites images représentant un fichier ZIP ou autre) :

p > img {
  float: right;
}

Voici un exemple de code HTML dont les images impactées sont surlignées en jaune. La deuxième image n'est pas concernée par la règle CSS, car elle est contenue dans une balise <a>, donc elle n'est pas une fille direct du paragraphe <p>. Notez que là encore, seule des balises <img> vont se voir transformées par le style, et pas la balise <p>, qui n'est présente que pour limiter le champs d'action de la règle :

<p>
  <img src="images/articles/test.jpg" width="300" height="200" alt="Illustration de l'article">
  Texte de l'article, suivit d'un
  <a href="telechargements/articles/test.zip">
    <img src="images/icones/fichier-zip.jpg" width="16" height="16" alt="">
    lien de téléchargement
  </a>
  Enfin, voici ceci :
  <img src="images/articles/test2.jpg" width="100" height="100" alt="Seconde illustration de l'article">
  une seconde illustration pour l'article.
</p>

Sélecteur d'adjacences : balise + balise_suivant_immediatement

Plus rarement, il vous arrivera de vouloir donner un style à une balise, mais uniquement si elle est précédée d'une autre balise. Ainsi, imaginons que vos pages Web sont composées d'un titre h1, suivit d'un paragraphe d'introduction, suivit du reste de la page (titres, paragraphes...). Vous voulez mettre la paragraphe d'introduction de la page en italique. Voici comment vous pouvez faire :

h1 + p {
  font-style: italic;
}
<h1>Titre de la page</h1>
<p>Paragraphe d'introduction concerné par le code CSS ci-dessus, car il est juste après le titre h1.</li>
<h2>Titre du premire chapitre</h1>
<p>Paragraphe non concerné par le code CSS ci-dessus, car il est précédé d'un élément h2.</li>

Regroupement de sélecteurs : sélecteur_1, sélecteur_2

Il arrive parfois que vous souhaitiez appliquer le même style à plusieurs balises ou plusieurs sélecteurs. Comme par exemple définir la couleur de fond de tous les titres comme devant être gris et la couleur du texte comme devant être bleu marrain. Au lieu de faire ceci :

h1 {
  background-color: gray;
  color: navy;
}

h2 {
  background-color: gray;
  color: navy;
}

h3 {
  background-color: gray;
  color: navy;
}

Vous pouvez plutôt séparer le nom des balises (ou des sélecteurs, en général) par des virgules afin de regrouper la définition du style, ce qui évitera une duplication du code. Ainsi, lorsqu'à l'avenir vous voudrez modifier le code CSS, vous n'aurez qu'à le modifier en un seul endroit, sans risque d'oublier de changer l'une des règles :

h1, h2, h3 {
  background-color: gray;
  color: navy;
}

Sélecteur de classe : .classe

Vous êtes maintenant capable d'assigner un style à certaines balises HTML en fonction de leur significaiton. Mais souvent, vous aurez besoin d'avoir plus de contrôle, de sélectionner plus finement les balises. Vous aurez en outre besoin de définir de nouvelles significations à certaines balises, et bien sûr de les styler différemment. Chaque balise HTML peut recevoir un attribut "class", dans lequel vous mettez un nom de votre choix. Il n'aura de signification que pour vous et vous permettra de faire le lien avec la feuille de style CSS. Voici quelques exemples de balises avec des classes :

<p      class="introduction"> ... </p>      <!-- C'est un paragraphe spécial : il sert d'introduction à la page -->
<div    class="encadre">      ... </div>    <!-- Ce bloc sert d'encadré visuel afin d'offrir des informations complémentaires à ce tutoriel -->
<code   class="css">          ... </code>   <!-- Ce bloc de code devra avoir la coloration syntaxique du CSS -->
<strong class="important">    ... </strong> <!-- Ce texte est doublement important -->
<a      class="bouton">       ... </a>      <!-- Ce lien doit être affiché comme un bouton -->
<a      class="onglet">       ... </a>      <!-- Ce lien doit être affiché comme un onglet -->
<a      class="complement">   ... </a>      <!-- Ce lien complémentaire doit être encadré et affiché sur la droite de la page -->
<div    class="img-legende">  ... </div>    <!-- Bloc contenant une image et sa légende, à placer séparément sur la droite de l'article -->

Ne cherchez pas : les noms de classe "introduction", "encadre", "css", ... "img-legende" ne sont définit dans aucun standard du Web. Ce sont bien des noms décidés par l'auteur du site internet pour rajouter de la signification au code. Il est à noter que les balises ci-dessus peuvent apparaître plusieurs fois dans la page. En effet, il peut y avoir deux ou trois paragraphes d'introduction (contrairement à la méthode utilisée avec l'opérateur "+" plus haut), plusieurs légendes, etc.

Notez qu'en écrivant les commentaires tels que "Ce lien doit être affiché comme un bouton", c'est à vous de produire le code CSS nécessaire pour que cela ressemble effectivement à un bouton, en utilisant des propriétés CSS pour assigner une couleur ou image de fond, des bordures... jusqu'à ce que le lien ressemble à un bouton. Idem pour "Ce bloc de code devra avoir la coloration syntaxique du CSS" : la coloration syntaxique n'est pas automatiquement faite par le navigateur, mais ce sera à vous de produire les règles CSS pour que cela se produise. Le nom de classe permettra juste de limiter la coloration syntaxique au code à l'intérieur des blocs ayant la classe "css". Les blocs <div class="encadre"> sont par exemple les encadrés "Note :" ou "Attention :" que vous avez déjà vu dans ce tutoriel. Et en parlant d'encadrés, en voici quelques uns :

Nom des classes :
Le nom d'une classe représente sa signification, et pas sa forme. Ainsi, il vaut mieux nommer une classe "important" plutôt que "rouge" si vous souhaitez colorer en rouge du texte important. En effet, plus tard vous voudrez peut-être changer le style pour utiliser une police grasse plutôt que rouge, par exemple. Et pour les visiteurs utilisant un logiciel de synthèse vocal, vous pourrez commander la voix de l'ordinateur pour qu'elle soit plus insistante. Le nom "rouge" ne signifierait alors pas grand chose dans ce contexte.

Classe ou balise ?
Avant de créer une classe, assurez-vous qu'il n'existe pas déjà une balise HTML ayant la même signification que votre futur-classe. Ainsi, dans l'exemple de l'encadré ci-dessus, il peut être plus judicieux d'utiliser des balises <strong> ou même <em> à la place d'un bête <span class="important">. Vous pourrez toujours colorer cette balise en rouge, et même retirer le gras ou l'italique si vous n'en voulez pas. Nous verrons d'ailleur cet exemple dans l'onglet suivant, Exemples CSS : Les balises em et strong.

Revenons au CSS, qui est quand même le sujet de cette page. Une fois que vous avez assigné une classe aux balises HTML, rien de plus simple pour les mettre en forme. Il suffit d'utiliser le sélecteur "." suivit du nom de la classe. Ainsi, voici comment styler très rapidement les classes que nous venons de voir plus haut :

.introduction { font-style: italic;                                                                    }
.encadre      { border: 1px solid black; background: cyan;                                             }
.css          { background: lightgray;                                                                 }
.important    { color: red;                                                                            }
.bouton       { border: 1px solid gray; background: lightgray;                                         }
.onglet       { border-top: 1px solid gray; border-left: 1px solid gray; border-right: 1px solid gray; }
.complement   { float: right;                                                                          }
.img-legende  { float: right; border: 1px solid black;                                                 }

Avec quelques connaissances d'anglais on devine rapidement le résultat que cela va donner. Je ne vous le monterai pas car il s'agit bien là d'un style très rapide, donc qui manque cruellement de goût. Le principal étant que l'on a stylé des "balises virtuelles" que nous avons fabriquées.

Vous voyez que ce sélecteur est assez important et vous en aurez besoin souvent. Il y a également une seconde chose à savoir sur les classes, et qui est relativement peu connu des développeurs CSS. Il est possible d'assigner plusieurs classes CSS. Dans le code HTML, il suffit d'espacer les classes par un espace. Dans le code CSS, il est possible d'appliquer un style indiférement à chacune des classes d'un élément. Ainsi, reprenons l'exemple de la classe "encadre". Nous voulons maintenant deux sortes d'encadrés : un encadré de simple information et un encadré de mise en garde. Chaque encadré gardera la classe "encadre", mais se vera en plus assigner une seconde classe pour préciser la nature de l'encadré : "information" ou "attention" :

<div class="encadre information">
  Information :<br>
  Voici un texte d'information, faites-en ce que vous voulez !
</div>

<div class="encadre attention">
  Information :<br>
  Voici un texte d'information, faites-en ce que vous voulez !
</div>

Visuellement, tous les encadrés auront une bordure noire. Mais là où les deux encadrés d'information et de mise en garde se distingue, c'est par leur couleur de fond : bleu clair pour l'information, et rouge clair pour une mise en garde :

.encadre {
  border: 1px solid black;
}

.information {
  background: cyan;
}

.attention {
  background: pink;
}

Le premier cadre utilisera le style des deux premières règles, et le second cadre utilisera les première et dernière règles.

Sélecteur d'ID : #id

Les IDs sont quasiment la même chose que des classes, sauf qu'un ID ne peut être assigné qu'à un et un seul élément. Et un élément ne peut avoir qu'un seul ID (pas de liste d'IDs séparés par des espaces). C'est le cas par exemple pour l'entête ou le pied d'une page : il ne peut en avoir qu'un seul par page HTML. Idem pour le menu d'une page...

En HTML, on attribue un ID à une balise via l'attribut "id". Et en CSS, on utilise le signe dièse suivit du nom de l'ID afin de lui donner un style.

Voici un exemple de code HTML et CSS utilisant des IDs. Il ressemble au code utilisant des classes ("id=..." remplace "class=..." dans le HTML et le "#" remplace le "." dans le CSS) :

<div id="entete">
  Voici l'entête visuel de la page, composé d'un titre et d'un menu, par exemple.
</div>

<div id="pied">
  Voici le pied de page, où seront placés les liens peu importants et une ligne de copyrights, par exemple.
</div>
#entete {
  border-bottom: 1px solid black;
}

#pied {
  border-top: 1px solid black;
}

Sélecteur d'attribut : balise[attribut]

Ce sélecteur permet de filtrer les balises qui possèdent un attribut particulier. En guise d'exemple, rappelez-vous de la balise <a>. Elle a deux rôles en fonction de la façon dont elle est utilisée :

<a href="#article">Aller à l'article</a> <-- Lien vers une autre page ou fichier -->
<h2><a name="article">Article</a></h2> <-- Ancre -->

Ici, si vous voulez appliquer un style aux liens, comme un soulignement, une couleur bleue, et un effet au survol de la souris... vous stylerez la balise <a>. Mais les ancres seront aussi mises en formes comme des liens, alors qu'elles ne sont pas cliquables. C'est pour cela que sur la page Le HTML, je vous ai conseillé de laisser vide le contenu d'une balise d'ancre. Dans l'exemple ci-dessus, je vous conseillerais de déplacer le texte "Article" juste après la balise de fermeture </a>.

Néanmoins, en utilisant le sélecteur d'attribut, il est possible de garder le code HTML comme ci-dessus et de pouvoir styler les liens et les ancres différemment :

a[href] { color: blue; text-decoration: underline; }
a[name] { /* Aucun style particulier */ }

Remarquez que nous verrons un peu plus tard que ce cas étant assez courant, il existe la pseudo-classe :link.
Notez également que la partie "balise" du sélecteur peut être omise. Ainsi, en utilisant le sélecteur "[name]", vous sélectionnerez n'importe quelle balise ayant un attribut "name", et non seulement les liens (balises "a"). Dans notre exemple, je ne vous conseille pas de faire ceci, car les champs de formulaire ont aussi un attribut name, le style s'y appliquerait alors également.

Sélecteur de valeur exacte d'attribut : balise[attribut="valeur"]

Permet de sélectionner les balises dont l'attribut "attribut" a exactement la valeur "valeur".
Afin de montrer un exemple d'utilisation de ce sélecteur, utilisons l'attribut dir. Cet attribut a la valeur par défaut "ltr", signifiant "Texte lisible de gauche à droite" (Left To Right). Il est possible d'utiliser l'attribut dir avec la valeur "rtl" pour introduire un texte dans une langue se lisant de droite à gauche ("rtl" pour "Right To Left").
Il est alors possible d'afficher différemment ces textes grâce à ce sélecteur en CSS :

<p>Les mots "<span dir="rtl">&#1502;&#1494;&#1500; &#1496;&#1493;&#1489;</span>" veulent dirent "Félicitations !".</p>
span[dir="rtl"] {
  background-color: yellow;
}

Les mots "מזל טוב" veulent dirent "Félicitations !".

Vous pouvez sélectionner le texte d'exemple lentement de la gauche vers la droite pour vous rendre compte que la partie jaune est bien écrite, et donc sélectionnée, de la droite vers la gauche.

Il est ici aussi possible d'omettre la partie "balise" du sélecteur. Ainsi, pour mettre en jaune aussi bien les passages (span) que les paragraphes entiers (p), les lignes de listes (li), etc. vous pouvez écrire la règle précédente comme suit, en enlevant "span" :

[dir="rtl"] {
  background-color: yellow;
}

Sélecteur d'attribut contenant une valeur : balise[attribut~="valeur"]

Permet de sélectionner les balises dont l'attribut "attribut" contient une liste séparée par des caractères blancs (espaces, tabulations...), et dont l'un des éléments est égual à "valeur".
Ceci permet de simuler le fonctionnement des classes avec n'importe quel attribut autre que "class".
En effet, souvenez-vous qu'un élément HTML peut avoir plusieurs classes, séparées par des espaces, comme "cadre attention", "cadre information"... Ainsi, les deux lignes suivantes sont équivalentes :

.cadre           { ... }
[class~="cadre"] { ... }

Bien entendu, vous pouvez placer un nom de balise devant ces deux sélecteurs pour restraindre encore plus les balises sélectionnées. Par exemple : div.cadre et div[class~="cadre"] sont équivalents et restreignent le sélecteur aux balises "div" ayant la classe "cadre".

Sélecteur d'attribut commencant par une valeur : balise[attribut|="valeur"]

Permet de sélectionner les balises dont l'attribut "attribut" contient une liste séparée par des tirets, et dont le premier élément vaut "valeur".
Ceci est utile pour l'attribut lang, qui peut contenir un code comme en-US (anglais américain), en-GB (anglais britanique), fr-FR (français parlé en France), fr-CA (français parlé au Canada), fr-BE (français parlé en Belgique)... Les langues commençant par les mêmes lettres se ressemblent, donc peuvent être stylées de la même manière. Exemples, pour styler les langues anglaises et françaises différemment, peut importe le pays :

[lang|="en"] { ... }
[lang|="fr"] { ... }

Combinaisons de sélecteurs

ARRIVÉ ICI

Nous avons vu tous les sélecteurs du CSS 2. Sachez qu'il est possible, et même souvent indispensable, de les combiner. Certains sélecteurs, comme le sélecteur universel, prennent alors tout leur sens. Pour sélectionner toutes les balises directement filles du corps mais pas les sous-balises, vous en aurez besoin et écrirez alors ceci :

body > *

Attention aux espaces !! span.important est différent de span .important


Un apport non négligeable en CSS est la possibilité de créer des classes et cela va nous permettre, entre autre, d'avoir un style différent pour les liens normaux (dans le texte) des liens pour le ou les menu(s) !
Il faut pour cela avoir plusieurs divisions dans votre code HTML : tout ce qui se rapporte au menu doit être placé dans <div class="menu"> ... </div> par exemple. Le reste peut être placé ou non dans une division de classe "contenu" par exemple. Nous opterons pour ne pas le faire. Le principe réside donc à styler les liens comme déjà fait, et à simplement rajouter des règles pour styler différemment les liens dans le menu. Un exemple :

a {
  color: #458EFF;
}
a:hover {
  text-decoration: none;
}
.menu {
  background-color: #458EFF;
}
.menu a {
  text-decoration: none;
  color: white;
}
.menu a:hover {
  text-decoration: underline;
}
<ul class="menu">
  <li><a href="index.html">Accueil</a></li>
  <li><a href="news.html">News</a></li>
</ul>
<p>Ceci est un paragraphe normal avec un <a href="adresse.html">lien</a> !</p>

Ici, les liens normaux sont bleus clairs et ont supprime le soulignement lors de leur survol (ça fait déjà un bel effet). Par contre, le menu étant bleu (pour le remarquer), les liens seront blancs et non soulignés : ils seront re-soulignés au passage de la souris (l'inverse des liens normaux).
Il faut faire attention au fait de ne pas souligner les liens normaux : en effet, il n'y a alors plus que la couleur qui les différencie du texte normal. Mais pensez aux personnes ayant des difficultés à discerner les contrastes et couleurs (il en existe plus qu'on ne le croit, je n'ai plus les chiffres malheureusement) : pour eux, il sera difficile de différencier les liens autrement qu'en baladant le curseur de la souris et en voyant les réactions. Si vous décidez de ne pas souligner les liens, alors mettez-les en gras ou en italique... quelque chose qui les différencie du texte normal (attention : les liens sont quasiment toujours soulignés : un texte gras ne fait pas tout de suite penser à un lien et il faudra un moment pour que les visiteurs s'habituent).
Par contre, il est clair que le menu ne contient que des liens : l'effet de dé-soulignement peut alors être utilisé, à condition qu'on repère bien le menu !

Pseudo-classes et pseudo-éléments

Pseudo-classes (effets spéciaux pour changer l'apparence d'un élément en fonction de son état) :
:link, :visited, :hover, :focus, :active, ((:first-child, :lang(fr) ??))...
Pseudo-éléments (ce sont des pseudo-classes pour changer l'apparence d'une partie d'un élément) :
:first-letter, :first-line (indent), :before (cadre attention, content: texte/url), :after...

Priorité des sélecteurs

Il arrivera souvent que plusieurs règles s'appliquent à une balise particulière. Par exemple, pour le code HTML suivant :

<div>
  <p class="important">
    De quelle couleur sera ce texte ?
  </p>
</div>

Vous pouvez avoir définit trois règles CSS :

p          { font-weight: bold;   color: red;   }
.important { font-size:   16px;   color: green; }
div > p    { font-style:  italic; color: blue;  }

Dans ce cas, toutes les règles s'appliquent au paragraphe : le texte du paragraphe sera en gras (font-weight: bold), il aura une taille de 16 pixels (font-size: 16px) et sera en italique (font-style: italic). Par contre, la propriété color est définie dans chacune des trois règles, et le texte ne peut être que d'une seule couleur : rouge (color: red), vert (color: green) ou bleu (color: blue). Mais laquelle ?

Pour cela, le CSS définit un système de priorités. Les règles qui sont les plus précises l'emportent sur les règles plus générales, ce qui est assez intuitif. Ainsi, la première règle a un sélecteur "p", ce qui est assez général. Les deux autres règles s'efforcent de restraindre le plus possible leur champs d'action, c'est donc l'une des deux dernières qui sera appliquée. Mais là encore, laquelle ?

Et bien il y a un calcul qui permet d'être toujours certain de connaître la spécificité d'un sélecteur :

La spécificité est obtenue en assemblant les quatre nombres a-b-c-d. Exemples :

/* Règles dans un fichier CSS : */
*              { ... } /* a=0 b=0 c=0 d=0 -> spécificité =    0 */
li             { ... } /* a=0 b=0 c=0 d=1 -> spécificité =    1 */
ul li          { ... } /* a=0 b=0 c=0 d=2 -> spécificité =    2 */
ul ol+li       { ... } /* a=0 b=0 c=0 d=3 -> spécificité =    3 */
h1 + *[rel=up] { ... } /* a=0 b=0 c=1 d=1 -> spécificité =   11 */
ul ol li.red   { ... } /* a=0 b=0 c=1 d=3 -> spécificité =   13 */
li.red.level   { ... } /* a=0 b=0 c=2 d=1 -> spécificité =   21 */
#x34y          { ... } /* a=0 b=1 c=0 d=0 -> spécificité =  100 */
<!-- Attribut style à une balise dans un fichier HTML : -->
style="..."            /* a=1 b=0 c=0 d=0 -> spécificité = 1000 */

Si deux règles CSS ont la même spécificité, alors la dernière l'emporte. Il est ainsi possible d'écraser ou de redéfinir une règle plus bas dans le fichier CSS, voir même dans un second fichier CSS. En effet, il est possible de lier deux fichiers CSS dans une page HTML, en utilisant deux balises <link> vues au début de cet onglet. Par exemple, un site peut avoir une feuille style.css et une feuille noel.css. Cette dernière ne contiendra que quelques lignes pour redéfinir la couleur de certains éléments en rouge et vert.

Comme on peut s'y attendre, si on définit une couleur de texte pour une balise, les balises filles hériteront aussi de cette propriété (sauf si une règle plus prioritaire dit le contraire). Par contre, et c'est logique, si on définit un cadre autour d'un bloc (un paragraphe, par exemple), les balises filles (des liens, des listes... par exemple) n'hériterons pas de cette propriété : cela donnerait des cadres dans des cadres, et ferait du plus mauvais effet. En règle général, les propriétés qui peuvent être héritées ou pas sont assez intuitives.

Pour terminer cette section sur les priorité des sélecteurs, répondont à la question existentielle posée un peu plus haut : de quelle couleur sera le paragraphe vert ? Faisons le calcul :

p          { font-weight: bold;   color: red;   } /* a=0 b=0 c=0 d=1 -> spécificité =    1 */
.important { font-size:   16px;   color: green; } /* a=0 b=0 c=1 d=0 -> spécificité =   10 */
div > p    { font-style:  italic; color: blue;  } /* a=0 b=0 c=0 d=2 -> spécificité =    2 */

Et oui, le texte sera vert. Le sélecteur ".important" étant plus précis que les deux autres. Bravo aux personnes l'ayant deviné. Malheureusement, la cagnotte était vide, vous ne gagnez pas d'argent.

Au final, pour ce paragraphe, et uniquement dans ce cas, les trois règles fusionnent pour donner ceci, comme si nous n'avions écrit que cette règle :

div > p.important {
  font-weight: bold;
  font-size: 16px;
  font-style: italic;
  color: green;
}

Notez enfin que si vous avez plusieurs sélecteurs séparés par des virgules, vous devez calculer la priorité de chacun de ces sélecteurs individuellement, comme s'ils avaient été définis séparément. Vous ne devez pas cumuler les priorités des sélecteurs séparés par des virgules.

Types de valeurs

Longueurs et pourcentages

Préférez des unités relatives, car elles peuvent être adaptées au visisteur (mal voyant ou pas) et au périphérique (écran ou imprimé), et banissez les unités absolues (sauf si les relations sont directements définies pour un seul périphérique, par exemple). Ces valeurs peuvent être positives comme négatives (+/-), la valeur 0 ne requérant pas de spécifier d'unité.

px, %, em... relatives/absolues faux.

La valeur 0 :
La valeur 0 est la seule valeur vous permettant d'omettre l'unité. En effet, les chiffres "0%", "0px", "0pt"... sont touts égaux. Dans le cas d'une valeur non nulle par contre, l'unité est toujours obligatoire. Son omission peut poser quelques problèmes d'interpretations différentes par les navigateurs.

Les couleurs

Pour définir une couleur de fond, de texte, de bordure... il est possible d'utiliser plusieurs format afin de la décrire :

Il existe une grande variété d'outils permettant de sélectionner une couleur et d'en obtenir le code hexadécimal.
Voici un outil que vous pouvez utiliser :

TODO : afficher la couleur du sélecteur dans les formats suivants :
- mot clef
- #rrggbb
- #rgb
- rgb(x,x,x)
- rgb(y%,y%,y%)
TODO : sous IE : onclick{return false;} pour éviter sélection
TODO : double-bordure blanche
TODO : version hors-ligne !
TODO : remercier http://ecritters.biz/colorselector/

Références vers des fichiers

Tout comme avec le HTML, les images des feuilles CSS sont stoqués dans des fichiers à part. Il est alors nécessaire d'y faire référence via un chemin relatif ou absolu. Pour revoir la différence entre ces deux types de chemins, revoyez la partie Les adresses de l'onglet Le HTML du tutoriel.

Une URL (adresse Web) est définie par url('l-adresse') (entre guillemets simples), url("l-adresse") (entre guillemets doubles) ou url(l-adresse) (sans guillemets).
Les parenthèses, virgules, espaces et guillemets dans l'adresse doivent être échappés avec un antislash (\, pour une virgule, \" pour un guillement). Si une adresse relative est donnée, elle est relative à la feuille de style (le fichier .css) et non à la page Web qui inclut la feuille de style (.html) !

Les images référencées à l'intérieur du fichier CSS via la notation url() sont relatives au dossier contenant le fichier CSS. Ceci permet ainsi d'inclure le fichier CSS dans des pages HTML d'origines différentes. Illustration :

Site/
  images/
    test/
      fond.png
      vacances.jpg
  themes/
    style.css        image fond.png
    noel.css
  telechargements/
    liste.html       <html ... lien vers style.css      img vacances.jpg...
  index.html         <html ... lien vers style.css      img vacances.jpg...
   

Modèle de boîtes

Chaque balise de la page HTML est visuellement représentée par un bloc. Les propriétés de ce bloc sont manipulables en CSS.
Voici par exemple une balise bloc (un paragraphe, un div... mais pas une balise en ligne) quelconque contenant le texte "Contenu du bloc<br>(texte, images, liens, sous-blocs...)" :

Explication des différentes parties d'une boîte : marge, bordure, espacement intérieur et largeur et hauteur du contenu

À l'affichage, cette balise est représentée par un bloc. Voici une description des composants d'un bloc :

Le contenu

Le contenu est visuellement représenté par un cadre en pointillets au centre de l'illustration. Ces pointillés ne sont pas visible à l'écran. Ici, il n'y a que du texte, mais il aurait également très bien pu y avoir des images, etc. comme l'indique le texte de l'illustration. Par défaut, la largeur du bloc utilise toute la largeur disponible, et la hauteur du bloc est adaptée à la hauteur du contenu. Si vous souhaitez restreindre la largeur ou étendre la hauteur du contenu du bloc, vous pouvez utiliser ces deux propriétés :

Débordement du contenu :
À noter que si la taille du bloc est insufisante pour afficher tout le contenu, le contenu dépassera du bloc visuel. Le texte dépassera de la bordure, de l'image de fond, etc. que nous verrons plus bas.

La bordure

Le contenu peut être entouré par une bordure. Sur l'illustration, c'est le gros cadre noir. Les bordures sont définies par une combinaison de ces propriétés :

Mais il existe aussi ces propriétés courtes :

Propriétés courtes (ou propriétés raccourcies) :
La propriété "border", tout comme les propriétés "padding", "margin" et "background" que nous allons voir plus bas, sont appelées des propriétés courtes. Elles permettent de réduire la quantité de code CSS en regroupant plusieurs propriétés en une. Elles sont très pratiques.

L'espacement intérieur et le fond

Par défaut, le texte est collé à la bordure. C'est assez disgracieux. L'espacement intérieur permet, comme son l'indique, d'espacer le contenu de sa bordure. Mais ce n'est pas tout. Il est possible d'assigner une couleur de fond au bloc, ainsi qu'une image de fond. Dans l'illustration, le bloc a une image de fond représentant des grandes rayures bleues inclinées. Vous voyez que ce fond occupe les zones de l'espacement intérieur et du contenu. Ainsi, si un bloc n'a pas de bordure, l'espacement intérieur sert dans ce cas à espacer le contenu des bords de l'image ou de la couleur de fond. Voici les propriétés CSS permettant de jouer sur l'espacement intérieur d'un bloc :

Ordre des côtés pour les propriétés courtes :
Les propriétés courtes "border-width", "padding" et "margin" (nous allons voir cette dernière plus bas) acceptent de prendre jusqu'à quatre dimensions, correspondantes aux quatre côtés du bloc. Un moyen mnémotechnique de se souvenir de leur ordre est de savoir qu'ils sont définis dans l'ordre des aiguilles d'une montre, en partant de minuit : top, right, bottom, left :

Les côtés d'un bloc sont définis dans le sens des aiguilles d'une montre

Et voici les propriétés permettant de jouer sur le fond (ou arrière-plan) d'un bloc :

La marge

Enfin, le dernier moyen de contrôler l'apparance des blocs est de leur assigner une marge. Elle est dessinées comme un cadre en pointillets sur l'illustration. Les pointillets sont bien entendu invisibles. Les marges permettent d'espacer les blocs les uns par rapport aux autres :

Il est à noter que les marges verticales, et uniquement les marges verticales (mages hautes et basses), représentent la distance minimale à laisser entre deux blocs. En effet, si deux blocs avec une marge de dix pixels se suivent, il n'y aura pas vingt pixels entre ces deux blocs, mais bien dix. Si le premier bloc a maintenant une marge de trente pixels et le second toujours une marge de dix pixels, la marge resultante entre ces deux blocs sera de trente pixels. Les marges sont en effet fusionnées, comme le montre ce schéma :

Illustration de la fusion des marges de trois blocs

Imaginons que les blocs du schéma ci-dessus soient des paragraphes. Sans ce mécanisme de fusion des marges verticales, l'espace entre deux paragraphes (le bloc 1 et le bloc 2) serait le double de l'espace au dessus du premier paragraphe (le bloc 1), ce qui est très rarement voulu.

De manière similaire, les marges des blocs enfants se confondent dans les marges des parents. Imaginons ce code HTML :

<div>
  <div>
    Contenu du bloc fils
  </div>
  Contenu du parent
</div>

La marge haute du bloc fils (le second rectangle en pointillés gris en partant du haut du schéma) se fond dans celle de son parent (le plus grand rectangle en pointillés gris). Cela est conforme à la définition de la marge verticale comme étant "l'espace minimum à laisser autour du bloc". Par contre, le contenu du bloc parent est bien poussé vers le bas, comme on pouvait s'y attendre :

Fusion des marges d'une boîte fille avec celles de sa boîte mère

Si vous ne souhaitez pas de ce comportement, vous pouvez définir une bordure au bloc parent. Grâce à la bordure, la marge du bloc enfant ne fusionnera pas avec celle du parent, mais permettra d'éloigner le bloc enfant de la bordure du bloc parent. Cette bordure peut être invisible en utilisant le mot-clef "transparent" pour la propriété "background-color", mais elle doit avoir une largeur minimum d'un pixel. Le même comportement peut être obtenu en définissant un espacement intérieur au bloc parent, à la place de la bordure (un padding d'au moins un pixel). Voici le même exemple que précédemment, mais en assignant une bordure noire de un pixel au bloc parent. Il n'y a plus de fusion des marges, la marge du bloc enfant est contenu à l'intérieur du bloc parent :

Utilisation d'une bordure sur la boîte mère pour éviter la fusion des marges avec celles d'une boîte fille

Enfin, il est à noter que si un bloc est vide, ses marges haute et basses fusionnent alors ensemble pour former une seule marge. Cette marge fusionnera également avec la marge basse du bloc du dessus, s'il y a, et la marge haute du bloc du dessous.

Les marges négatives :
Les marges des blocs peuvent être négatives. Dans ce cas, le contenu s'étends dans le sens opposé. Il est alors possible que deux blocs se chevauchent car l'un des deux ou les deux ont une marge négative. Cette fonctionnalité est parfois utilisée de façon ingénieuse dans certaines techniques avancées en CSS. À noter que seules les marges peuvent être négatives. L'espacement intérieur ne peut pas être négatif.

Pour explorer le modèle de boîtes en CSS, nous avons parlé des balises blocs. Ce méchanisme fonctionne de manière similaire avec les balises en ligne, à l'exception près que les balises en ligne ne peuvent se voir attribuer une hauteur. Ainsi, les marges verticales n'ont aucun effet sur les blocs en ligne, contrairement aux marges horizontales. Les bordures sont bien appliquées, mais si elles sont trop hautes, elles risquent de déborder sur les lignes de texte adjascentes. L'espacement intérieur est également pris en compte mais les espacements intérieurs verticaux n'augmentent pas la hauteur des lignes. Ils servent uniquement à appliquer la couleur ou l'image de fond sur une plus grande hauteur. Et parce qu'un exemple vaut mieux que mille mots, en voici un. Il est aussi à noter qu'il est impossible d'appliquer une largeur aux blocs en ligne via la propriété width. En effet, de tels blocs pouvant être coupés pour être disposés sur plusieurs lignes, la taille du bloc pourrait alors signifier beaucoup de choses différentes, comme la taille totale, ou la taille des blocs individuels, ou du premier, etc. :

span {
  margin: 30px;
  border: 10px solid blue;
  padding: 20px;
  background: cyan url('images/fond.png');
  color: navy;
}

Ceci est la première ligne de l'exemple.
Cette ligne est illisible car la balise en ligne ci-dessous a trop d'espacement intérieur et de bordure.
Suivit d'une troisième ligne illisible.
Voici maintenant une balise en ligne assez bien décorée.
Une ligne intermédiaire pour séparer légèrement les deux balises bien garnies.
Et une seconde ligne intermédiaire.
Puis une seconde balise en ligne pour démontrer que les marges, bordures et espacements verticaux n'ont aucune incidence sur la hauteur des lignes.
Cette ligne est affichée par dessus la balise en ligne précédente, car chaque ligne est dessinée dans l'ordre, l'une par dessus l'autre si nécessaire.
Celle-ci aussi.
Dernière ligne, visible.

Positionnement

Le flux normal d'une page

Jusqu'ici nous avons vu que les balises blocs étaient affichées les unes en dessous des autres. On appel cela le flux du document. Mais vous aurez souvent besoin d'avoir plus de contrôle sur ce flux pour positionner un menu à gauche du contenu, ou positionner un pied de page toujours en bas de la page...

Commençons par le plus simple : transformer des boîtes blocs en boîtes en ligne, et inversement.
Pour cela, vous utiliserez la propriété display, qui peut prendre ces valeurs :

Nous verrons dans l'onglet Maquette que la propriété display est très utile, notamment pour transformer les liens d'un menu en balises bloc afin qu'ils soient cliquables sur toute la longeur. Ou encore pour cacher des éléments lorsqu'une page est imprimée (display: none). Il est aussi possible, dans certains cas, de faire afficher une balise en ligne comme une balise bloc, afin de lui assigner une largeur ou une hauteur. Nous y reviendrons dans l'onglet Maquette.

Rappelez-vous aussi que pour des balises blocs, il était possible de restreindre la taille de ceux-ci. Et si le contenu (texte, sous-balises...) était trop grand, il dépassait de la boîte. En CSS, il est possible de spécifier un comportement pour ce genre de situations.
Ceci est fait grâce à la propriété overflow, qui peut prendre les valeurs suivantes :

Voici un exemple mettant en œuvre ces valeurs :

overflow: visible
Petit contenu

overflow: hidden
Petit contenu

overflow: scroll
Petit contenu

overflow: auto
Petit contenu

overflow: visible
Grand contenu
Grand contenu
Grand contenu
Grand contenu
Grand contenu
Grand contenu

overflow: hidden
Grand contenu
Grand contenu
Grand contenu
Grand contenu
Grand contenu
Grand contenu

overflow: scroll
Grand contenu
Grand contenu
Grand contenu
Grand contenu
Grand contenu
Grand contenu

overflow: auto
Grand contenu
Grand contenu
Grand contenu
Grand contenu
Grand contenu
Grand contenu

Une dernière propriété permettant de modifier légèrement le flux normal d'une page est la propriété visibility :

Voici un petit exemple rapide montrant la différence entre la propriété display et la propriété visibility :

<p>
  [ Voici du texte visible ]
  [ <span> style="display: none;">ce texte est retiré du flux</span> ]
  [ <span> style="visibility: hidden;">ce texte est toujours dans le flux, mais il est invisible</span> ]
  [ et ce texte est bien sûr visible ]
</p>

[ Voici du texte visible ] [ ce texte est retiré du flux ] [ ce texte est toujours dans le flux, mais il est invisible ] [ et ce texte est bien sûr visible ]

Blocs flotants

Voyons maintenant comment s'affranchir du flux normal d'une page. Les blocs flotants sont une technique courament utilisée en CSS.

TODO: float/clear

Positionnement absolu, relatif et fixe

TODO:
- position
- top, left, right, bottom
- z-index [position: relative; z-index: 1000; : permet également de positionner un bloc au dessus d'un autre même s'il vient avant dans le code HTML]

Autres propriétés CSS

Propriétés des textes

TODO

Propriétés des listes

TODO

Propriétés des tableaux

TODO

Autres propriétés diverses

cursor, scrollbar-*


Je vous propose de visiter la page des propriétés CSS sur SelfHTML.org.

Faites une pause, vous l'avez bien mérité :
Découvrez Snaky 360, le jeu de serpent addictif réalisé par l'auteur de ce tutoriel...



Créé entièrement en HTML, CSS et JavaScript, sans Flash
(sauf pour les musiques et effets sonores, en attendant HTML 5)
Bientôt, vous pourrez en faire de même !