Les tableaux et les pseudo-classes CSS Introduction : Pendant longtemps, la mise en page des sites reposait sur l utilisation de tableau. En effet, face à l absence ou l interprétation parfois fantaisiste de la CSS, ils permettaient de s assurer une disposition harmonieuse. Ce temps est révolu et les tableaux retrouvent leur première fonction, la présentation de données tabulaires. Quant à la CSS, la version 3 concernant les tableaux n est pas encore définie, mais la version 2.1 est toujours valide. Balises HTML : Le tableau <table> et son titre ou sa légende <caption> Un tableau est défini entre les balises <table> et </table>. Il possède l attribut spécifique optionnel border, qui spécifie l usage d une grille. Cet attribut peut cependant être omis et les bordures seront créées avec la CSS. L ancien attribut summary (équivalent de l alt des images) est désormais prohibé. La première balise à l intérieur du tableau est son titre (ou sa légende), encadré(e) par les balises <caption> et </caption>. Elle peut contenir d autres balises à l instar d un bloc <div>. Si le tableau contient des bordures, le titre se trouvera forcément à l extérieur. Les sections d un tableau : <thead> <tbody> <tfoot> Il est possible de subdiviser le tableau en plusieurs sections horizontales de manière similaire à une page standard ou un article, avec un entête <thead>, un corps <tbody> et un pied-de-page <tfoot>. Chacune de ces sections peut contenir une ou plusieurs lignes. Il est également possible de créer plusieurs sections de corps <tbody> à la suite. Contrairement à toute logique, l ordre de déclaration de ces balises est <thead> puis <tfoot>, et finalement le(s) <tbody>. L élément <tfoot> sera de toute façon affiché en bas du tableau, même s il est déclaré en seconde position, et peut servir à reproduire l entête en bas des tables les plus grandes. Les groupes de colonnes : <colgroup> et <col> A l instar des sections précédentes, il est possible de grouper des colonnes en section verticale. Il faut inscrire celles-ci avant de déclarer les sections horizontales. On indique le nombre de colonne dans l attribut span d une balise orpheline <colgroup />. Lorsqu on veut être plus précis (en attribuant une classe à toute une colonne p.ex), il faut alors placer des balises orphelines <col /> entre les balises <colgroup> et </colgroup>. A nouveau, il est possible de regrouper certaines colonnes à l aide de l attribut span d une balise <col />. Les lignes : <tr> Chaque ligne commence par <tr> et s achève par </tr>. Une ligne comporte une ou plusieurs cellules. Des cellules d entête <th> ou de donnée <td> Il existe deux types de cellules : celles d entête <th> et celles de donnée <td>. Les cellules doivent être situées au sein d une ligne (<tr> </tr>). Toutes les cellules du tableau doivent être déclarées, même si celles-ci sont vides. 1
Il est possible de fusionner des cellules, en utilisant l attribut colspan (fusion sur plusieurs colonnes) ou rowspan (fusion sur plusieurs lignes) et en indiquant le nombre de colonnes/lignes (respectivement) fusionnées. Les cellules fusionnées sur plusieurs lignes ne doivent plus être déclarées dans les lignes suivantes. Les cellules peuvent être rattachées (sémantiquement) à leurs entêtes grâce à l attribut headers. Il reçoit comme paramètre les identifiants (id) des entêtes, séparées par un espace. Alternativement, les cellules d entête peuvent être rattachées (toujours sémantiquement) aux cellules de données, à l aide de l attribut scope, qui prend l une des valeurs suivante : row (ligne), col (colonne), rowgroup (groupe de lignes), colgroup (groupe de colonnes), auto (par défaut). Ces deux attributs n ont aucun intérêt visuel, mais servent à restituer le tableau par des moyens non-visuels (pour les malvoyants par exemple), nous ne les utiliserons donc pas dans ce cours. REMARQUE : il est possible (mais non recommandé) d imbriquer des tableaux dans d autres tableaux. Propriétés CSS : La position du titre ou de la légende : caption-side Le contenu de la balise <caption> peut se trouver au-dessus du tableau, comme un titre, ou endessous, comme une légende. Ce choix dépend de la propriété caption-side, qui peut prendre l une des deux valeurs suivantes : top (en haut, par défaut) ou bottom (en bas). Espacement des cellules (!) : border-collapse et border-spacing Les balises <table> et <tr> peuvent recevoir la propriété border-collapse qui définit l espacement des cellules. Celle-ci peut donc prendre les valeurs : separate (séparées, par défaut) ou collapse (collées). Si les cellules sont séparées, il est possible de spécifier la distance entre celles-ci à l aide de la propriété border-spacing. Celle-ci peut recevoir une ou deux valeurs séparées par un espace. Si deux valeurs sont indiquées, la première correspond à l espacement horizontal et la seconde pour le vertical. Ce choix est très important car il détermine certaines possibilités des propriétés suivantes. Les cellules vides : empty-cells Les cellules qui ne contiennent aucune donnée peuvent être cachées (p.ex pour ne pas afficher de bordure) à l aide de la valeur hide de la propriété empty-cells attribuée à la balise <table>. La valeur par défaut de cette propriété est show. Cette propriété ne fonctionne toutefois que si la propriété border-collapse prend la valeur separate. Les dimensions : width (largeur) et height (hauteur) Si les dimensions du tableau ne sont pas précisées, le navigateur créera automatiquement les dimensions des cellules en fonction du contenu le plus grand de chaque colonne et de chaque ligne. Il est toutefois possible de fixer les dimensions du tableau à l aide des propriétés width et height qui peuvent recevoir des valeurs en unités absolues ou relatives. En tant qu élément similaire au type bloc, la table peut être dimensionnée. Cependant, certains éléments contenus à l intérieur sont similaires au type en ligne. Ainsi si une hauteur est imposée au tableau, seul l élément tbody sera étiré. 2
Chaque cellule peut également recevoir des dimensions particulières, mais le tableau gardera ses lignes et ses colonnes alignées. Donc si plusieurs dimensions contradictoires sont indiquées, seule la plus grande sera conservée. Type d affichage : display Habituellement, les éléments peuvent être rangés en deux catégories : les éléments de type bloc et ceux de type en ligne (inline). La principale différence est qu un élément bloc peut contenir des éléments en ligne alors que l inverse n est pas vrai. Une autre différence est qu un élément de type bloc peut recevoir des dimensions, tandis qu un élément en ligne ne le peut pas. Pour modifier cela, il faut changer l affichage (display) de l élément. Les valeurs possibles sont none (non affiché), block, inline, inline-block (un élément en ligne avec des dimensions personnalisables), list-item (liste à puce), flex (un nouveau type de boîte), inherit (identique à son parent). A cela s ajoute les valeurs qui sont habituellement attribuées aux éléments des tables : table (correspondant à <table>), inline-table (<table> mais en ligne), table-caption (<caption>), table-cell (<td> ou <th>), table-column (<col>), table-column-group (<colgroup>), table-row (<tr>), table-row-group (<tbody>), table-headergroup (<thead>), table-footer-group (<tfoot>). Comme annoncé précédemment, on peut assigner des dimensions à certains types d affichage mais pas à d autres, le faire quand même ne sert donc à rien. Alignement du contenu des celules : text-align et vertical-align Il est rare que chaque contenu de chaque cellule fasse exactement la même dimension. De fait, il peut être intéressant de fixer les alignements horizontaux et verticaux des contenus des cellules. Horizontalement, c est la propriété text-align, que nous avons déjà vu, qui le détermine. Verticalement, cela est déterminé par la propriété vertical-align qui peut prendre une des valeurs suivantes : baseline (idem au parent, par défaut), top (en haut), middle (au milieu), bottom (en bas). Espacement entre bordure et contenu : padding Si le contenu est collé aux bordures, cela n est pas très joli ni très lisible. Pour résoudre ce problème, il suffit d utiliser la propriété padding qui comme la propriété border que nous avons déjà vu, peut se voir attribuer de 1 à 4 valeurs (en unités absolues ou relatives). Bordures : border Nous avons déjà vu la propriété border, elle peut être appliquée à la table (<table>) et aux cellules (<th> et <td>). Cependant, si la propriété border-collapse est réglée sur collapse, on peut alors attribuer des bordures à tous les éléments de la table. Dans ce dernier cas, comme il ne peut y avoir qu une seule bordure entre deux éléments, un conflit entre les bordures choisies peut apparaitre. De fait, une nouvelle valeur vient s ajouter au style de bordure, hidden (caché), qui permet de supprimer toute bordure de cellule, cette valeur est prioritaire sur toutes les autres. La priorité est ensuite donnée à la bordure la plus large, puis en cas d égalité à celle qui a le style le plus important (double > solid > dashed > dotted > ridge > outset > groove > inset). S il y a toujours égalité, l ordre est alors donné en priorité aux cellules puis aux lignes, au groupe de lignes, aux colonnes, au groupe de colonnes, à la table ou finalement en cas d égalité à la colonne de gauche. Couleur de fond : background-color Finalement la couleur de fond est déterminée par la propriété background-color que nous avons également déjà vu. Comme chaque élément d un tableau peur recevoir ce type de couleur, voici 3
l occasion d introduire la couleur transparent, qui indique l absence de fond. Pour rappel, nous avons déjà vu les couleurs transparentes de la fonction rgba(r,v,b,a). En cas de conflit entre les éléments du tableau, un ordre est respecté. Je vous laisse chercher lequel. Les pseudo-classes et autres sélecteurs précis : Il existe plusieurs façons d attribuer des styles aux cellules d un tableau. On peut passer par une identité (id) ou une classe (class) comme nous l avons déjà vu. Cela requiert cependant que le code HTML contienne ces indications. Pour des tables simples, il peut être plus rapide de n utiliser que la CSS. Mais alors, comment sélectionner uniquement certaines cellules ou groupes de cellules? Premièrement, il est possible de sélectionner certaines balises répondant à certains critères. Voici la liste des sélecteurs, cette fois complète : * { } Applique la déclaration à toutes les balises du document. A, B { } Applique la déclaration aux balises A et aux balises B. A B { } A > B { } A ~ B { } A + B { } A[attrib] { } A[attrib="val"] { } A[attrib~="val"] { } A[attrib^="val"] { } A[attrib$="val"] { } A[attrib*="val"] { } A[attrib ="val"] { } A.cla { } Applique la déclaration aux balises B incluses (directement ou indirectement) dans entre des balises A. Applique la déclaration aux balises B incluses directement dans entre des balises A (ou «B est fille de A»). Applique la déclaration aux balises B suivant une balise A se situant au même niveau (A et B sont donc sœurs). Applique la déclaration aux balises B suivant immédiatement une balise A et se situant au même niveau (A et B sont donc sœurs). Applique la déclaration aux balises A contenant l attribut attrib. Applique la déclaration aux balises A contenant l attribut attrib avec la valeur exacte val. Applique la déclaration aux balises A contenant l attribut attrib avec la valeur val incluse dans une liste séparée par des espaces. Applique la déclaration aux balises A contenant l attribut attrib dont la valeur commence par val. Applique la déclaration aux balises A contenant l attribut attrib dont la valeur se termine par val. Applique la déclaration aux balises A contenant l attribut attrib avec la valeur val comme suite de caractères partielle (ou totale). Applique la déclaration aux balises A contenant l attribut attrib commençant par la valeur val au sein d une liste séparée par des tirets. Applique la déclaration aux balises A qui sont de la classe cla. 4
Deuxièmement, les pseudo-classes sont une façon de sélectionner certaines balises sans recourir aux classes. Pour utiliser une pseudo-classe, il suffit d ajouter :nom_pseudoclass à la suite du sélecteur. Il est évidemment possible de les combiner avec les sélecteurs précédents. Les pseudo-classes existantes sont : A:root { } A:first-child { } A:last-child { } A:only-child { } A:nth-child(n) { } Applique la déclaration à la balise A qui est la racine du document. En HTML, cette déclaration est sans intérêt puisque l élément racine est toujours <html>. Applique la déclaration à la balise A qui est la première de son parent. Applique la déclaration à la balise A qui est la dernière de son parent. Applique la déclaration à la balise A s il est le seul enfant de son parent. Applique la déclaration à la balise A qui est le n ème enfant de son parent (toute balise confondue). Alternativement, on peut utiliser les termes odd (impaire) ou even (paire), pour l appliquer à toutes les balises impaires ou paires. Finalement, on peut également utiliser une formule mathématique de type Pn+Q, ou P ( ) représente la périodicité et Q ( ) le décalage. P.ex : 4n+1, correspondrait à tous les multiples de 4 éléments en commençant par le premier, alors que n+3 représente les 3 premiers éléments. A:nth-last-child(n) { } Similairement au précédent mais en comptant par la fin. A:nth-of-type(n) { } Similairement à nth-child mais en ne comptant que les éléments d un même type. A:nth-last-of-type(n) { } Idem mais en comptant par la fin. A:first-of-type { } A:last-of-type { } A:only-of-type { } A:empty { } A:not(X) { } A:link { } A:visited { } A:hover { } A:active { } Idem mais uniquement le premier. Idem mais uniquement le dernier. Applique la déclaration si l élément A est le seul enfant de ce type dans son parent. Applique la déclaration uniquement si l élément est vide : <A></A>. Applique la déclaration aux balises A qui ne répondent pas à la condition X. Il existe de nombreuses conditions possibles. P.ex : *:not(h1) sélectionnera toutes les balises du document à l exception des titres 1. Applique la déclaration aux balises A dont la cible du lien n a pas encore été visitée. Idem au précédent mais la cible du lien a été visitée. Applique la déclaration aux balises A lorsque celles-ci sont survolées par la souris. Idem mais l utilisateur effectue actuellement une action (p.ex clic) sur la balise. 5
A:focus { } A:target { } Idem mais la cible est actuellement sélectionnée par l utilisateur. Applique la déclaration à la balise A lorsque celle-ci vient de servir d ancre (càd que l utilisateur a cliqué sur un lien l amenant à cette balise). A:lang(C) { } Applique la déclaration aux balises A dont l attribut lang possède la valeur C. Finalement, il est encore possible de sélectionner une partie de contenu de balise ou d ajouter du contenu à une balise. Ce sont les pseudo-éléments, qui sont déclarés par ::pseudoelement : A::first-line { } Applique la déclaration à la première ligne contenue dans la balise A. A::first-letter { } Applique la déclaration à la première lettre contenue dans la balise A. Cela permet de faire facilement des lettrines. A::before { } Permet d ajouter du contenu avant les balises A. A::after { } Permet d ajouter du contenu après les balises A. REMARQUES : Vous l aurez probablement constaté, il existe plusieurs façons de toucher les mêmes balises. Alors quelle différence existe-t-il entre ces sélecteurs? Parfois il n y en a pas (et du coup la dernière déclaration prend le pas sur les autres), parfois c est une question de poids accordé à chacun. Je vous laisse chercher la logique qui se cache là-derrière et comme indice, je vous rappelle que le C de CSS signifie «en Cascade». Exercices : 1. Réalisez une grille de Sudoku. 2. Réalisez un nuancier sur 2 composantes (p.ex Rouge et Vert) en utilisant background-color. 3. Réalisez un graphique de type histogramme avec une table. Cela ne se fait normalement pas, mais c est juste un exercice. Principales références : Site du W3C : http://www.w3.org en particulier : http://www.w3.org/tr/css2/tables.html DÉVELOPPER VOTRE SITE WEB, F. Basmaison et coll., MicroApplication 2012 APPRENEZ À CRÉER VOTRE SITE WEB AVEC HTML5 ET CSS3, M. Nebra, Site du Zéro 2011 6