Accueil

Traduction

Tutoriel CSS3 - sommaire

Tutoriel CSS3 - recherche

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

CSS : nouveaux sélecteurs introduits par CSS3

Pour produire des interfaces dynamique sans devoir recourir à JavaScript mais grâce au CSS, il faut pouvoir cibler de façon très précise un ou plusieurs éléments de la page.
Pour cibler un seul élément du DOM c'est simple, il suffit de lui affecter un ID avec une valeur unique mais pour cibler plusieurs éléments il faut créer des sélecteurs plus ou moins sophistiqués.
Dans ce présent chapitre je rappelle les anciens sélecteurs mais je présente aussi ceux introduits par la version 3 de CSS.

Rappels des sélecteurs simples

Rappelons les sélecteurs basiques via des exemples :
h1 : cible toutes les éléments H1
*: cible tous les éléments ; * est le sélecteur universel !
h1, h2, h3 : cible les éléments H1,H2 et H3 donc des balises titres
article p : cible les éléments P inclus dans le conteneur ARTICLE. On dit que article p est un sélecteur de descendants.
.info: cible tous les éléments ayant l'attribut class ="info" ; il s'agit d'un sélecteur de classe générique.
p.remarque: cible les éléments P affectés de la classe "remarque" ; il s'agit d'un sélecteur de classe spécifique.
#entete : cible l'élément unique (en principe) de la page ayant l'attribut ID ="entete". On parle de sélecteur d'identifiant.

Sélecteurs basés sur de opérateurs (ou combinateur)

Ci-dessous je vous présente de sélecteurs moins connues qui peuvent s'avérer très utiles : éviter la multiplication des classes, éviter la règle de style en ligne : attribut style dans l'instruction HTML.

Sélecteur de voisinage général

Le combinateur '~' permet de cibler les balises qui suivent un élément donné mais pas directement.
Exemple : le sélecteur p ~ img permet de styliser une image qui suit un paragraphe.

Sélecteur de voisinage direct

L'opérateur "+" permet de cibler la balise qui suit immédiatement un élément donné.
Exemple : le sélecteur img + p permet de styliser le paragraphe qui suit immédiatement une image.

Les sélecteurs d'éléments enfants

Le combinateur '>' permet de cibler les balises qui sont des enfants directs d'un élément donné.
Exemple : ol.gras > li cible tous les éléments LI qui sont directement situés sous une balise OL affectée de la classe "gras".
Ce sélecteur doit être utilisé conjointement avec la pseudo classe :has ; voir la fin de ce chapitre.

Sélecteurs d'attributs

Exemples !

L'intérêt des sélecteurs de voisinage

Grâce à deux exemples je vous montre que les sélecteurs de voisinage peuvent être particulièrement utiles.

Sélecteur de voisinage pour économiser des classes

En utilisant des sélecteurs de voisinage (direct et général) j'évite le recours à des classes.

Le code HTML

Le CSS

* {font-size : 18px ; }
body {width : 600px ; margin : 10px auto ; }
h2+img {box-shadow : 10px 10px 10px gray ; display : block ; 
			width :30% ;  margin : 10px auto ; }
h2~img {display : block ; width :30% ;  margin : 10px auto ; }
img+p {color : red ; font-style : italic;  text-align : center ; }
h2 {text-align : center ; font-weight : bold; }

h2+img : voisinage immédiat
h2~img : voisinage proche
Ces deux sélecteurs évitent de créer deux classes pour les images.

Le rendu

Les trois premières images sont dimensionnées, centrées et ombrées : voisinage immédiat d'un titre H2.
La dernière image n'est pas ombrée mais elle est centrée et redimensionnée : voisinage d'un titre H2.

Sélecteur de voisinage et ciblage indirect

Grâce à un sélecteur de voisinage il est possible de cibler un élément en survolant ou en cliquant sur un autre élément.

Le code HTML

Le CSS

body {width : 100% ; height : 100vh; margin : 10px auto; 
	display : flex; justify-content : center ; align-items : flex-start;
	gap : 50px; width : 100vw; 	height : 80vh; border : 2px solid black ; }

.slide {width : 25vw;  height : auto; background : skyblue; }
.slide img{display : block ; width : 60%; margin :10px auto; }
p, span {font-size : 1.5em ; text-align : center; }
span {display : none ;}
p:active + img {box-shadow : -10px -10px 10px yellow; filter :sepia(1); }
p:active ~span {display : block;}

Le rendu

En cliquant sur le paragraphe l'image proche est stylisée et la légende est affichée.

Pseudo-éléments et pseudo-classes

Le sélecteur complexe peut être composé à partir d'une pseudo-classe OU d'un pseudo-élément.

Les pseudo-éléments

Un pseudo-élément est un mot-clé ajouté à un sélecteur qui permet de mettre en forme une partie de l'élément ciblé par le sélecteur.
Ainsi le pseudo-élément ::firt-letter ne s'applique qu'à la première lettre du texte ciblé.

Non vous ne voyez pas double, il faut désormais insérer deux fois le double point lorsqu'il s'agit d'un pseudo-élément. Mais rassurez vous, les navigateurs tolèrent toujours l'ancienne syntaxe avec un seul ":"/

Je rappelle que le pseudo-élément ::before est à la base de la numérotation automatique des titres.
Numéroter automatiquement les titres

Les pseudo-classes

Les pseudo-classes sont utilisées afin de mettre en forme un élément en fonction de son état.

Quelques pseudo-classes

Cette liste est loin d'être exhaustive. Il existe d'autres pseudo-classes utilisées principalement dans le cadre des tableaux et d'autres dédiées plutôt aux formulaires ; je vais les présenter dans la suite de ce chapitre.

Les pseudo classes :hover & :active permettent de réaliser une gestion évènementielle en CSS sans recourir à un script JS.

De nouvelles pseudo-classes intéressantes pour les tableaux

Il devient désormais très facile de cibler une ligne ou un groupe de ligne d'un tableau pour le styliser.

Exemples

Une page comprend deux tableaux.

Le code HTLM

Il est identique pour les deux tableaux sauf en ce qui concerne la valeur de l'ID.

Les règles de style communes aux deux tableaux

table{width : 90%; margin : 10px auto ; border : 2px solid navy}
tr{height : 50px ;}
td,th { border : 1px solid black ; }
td {padding-left : 10px ; }
td:empty {background : white;}

La pseudo-classe :empty permet de cibler les éléments vides ; ici des cellules de tableau.

Les règles de style pour le tableau identifié "tableau1"

#tableau1 {border-spacing : 10px ;}
#tableau1 tr {background : aqua ;}
#tableau1 tr:first-child {background: yellow; }
#tableau1 tr:last-child {background: pink; }

Les règles de style pour le deuxième tableau (identifié "tableau2")

#tableau2 {border-collapse : collapse ;}
#tableau2 tr:nth-child(even) {background: grey; color : white ;  }
#tableau2 tr:nth-child(odd) {background: aqua ;color : navy ;}

Le paramètre de :nth-child peut être un nombre. Par exemple tr:nth-child(3) désigne la troisième ligne du tableau.

Le rendu

Aperçu du document HTML dans un iframe :

De nouveaux pseudo-élément et pseudo-classes utiles pour les formulaires HTML

Exemple de code HTML5 d'un formulaire

Il s'agit d'un formulaire de soumission (avec envoi des données dans la même page).
Notez les attributs pattern avec pour valeur une expression régulière.
Notez l'attribut required : saisie obligatoire.

Nouveautés HTML5 & JavaScript

Concernant les nouveautés HTML : les nouveaux types pour le champ INPUT et les nouveaux attributs de l'élément INPUT, je vous invite à lire le chapitre ad hoc dans mon tuto sur HTML5.
HTML5 & les formulaires

Le code CSS du formulaire

	form {width : 80%; margin : 10px auto; color : navy}
	input, label, button{display : inline-block ; 
		width : 40% ; height : 30px ; margin : 1% ; 
		vertical-align : top ;}
	input:valid {color : green ; }
	input:invalid {color : red ;} 
	input:required {font-weight : bold; }
	input:optionnal {font-style : italic;}	
	input:focus {background : pink }
	input::placeholder {color: purple;}
	
	input[type =number] {width : 10%;}
	input[type = radio], input[type = checkbox],
		input[type = radio]+label, 	input[type = checkbox]+label, 
		input[type =number]+label {width : 50px ; }

On a aussi une règle de style basée sur un pseudo élément : input::placeholder {color: purple;}
Donc le texte dans un INPUT avant saisie est en violet.

On retrouve aussi des sélecteurs d'attributs : input[type = radio] & input[type = checkbox],
Donc les boutons radio et les cases à cocher n'auront une largeur de 40% (voir première règle) mais de 5% (voir dernière règle) puisqu'en cas de conflit entre deux règles de style de même niveau hiérarchique c'est la dernière qui est prise en compte.

Aperçu du formulaire dans un iframe

Essayez de renseigner ce formulaire.
Constatez que la légende d'un champ est "purple" ; qu'une saisie invalide est "red" puis "green" dès qu'elle est valide.

Des pseudo-classes pour les champs de type number

Dans le document HTML ci-dessous, j'utilise des pseudo-classes pour visualiser la validité (ou invalidité) de la saisie.

À chaque saisie dans le formulaire un script JS est appelé qui remplit l'output nommé "resultat".
Je vous conseille de lire le chapitre en lien : JavaScript pour les formulaires

La feuille de style

input[type ="number"]:in-range {color : green; }
input[type ="number"]:out-of-range {color : red; }

Chaque sélecteur est composite comprenant un sélecteur d'attribut + une pseudo-classe.
La pseudo-classe :in-range permet de cibler les input dont la valeur est comprise entre les attributs min et max.
La pseudo-classe :out-of-range cible les input dont la valeur est en dehors des limites définies par les attributs min et max.

Le code du formulaire (extrait)

La note doit être comprise entre 1 et 19. Si elle est contenue dans cet intervalle elle sera affichée en vert, sinon en rouge.
En effet si via la molette il est impossible de saisir une note en dehors de cet intervalle, c'est possible via le clavier ...

Notez l'emploi de l'événement de formulaire oninput qui survient à chaque saisie dans le formulaire.

Le rendu de ce formulaire dans un Iframe

La pseudo- classe de négation

La pseudo-classe de négation est une nouveauté CSS3 qui devrait être fort pratique car elle peut simplifier sensiblement les feuilles de style.

Rendu d'un document HTML dans un Iframe

Tous le texte est en italique gras et centré sauf le contenu des éléments P.
Toutes les images sont centrées, de grande taille et ombrées sauf la première.

Le code de la page

Code HTML

On n'utilise dans ce document que les éléments BODY, H1,h2,P & IMG.

La feuille de style

* {font-size : 18px ; }
body {width : 600px ; margin : 10px auto ; }
body *:not(p) {font-style : italic; font-weight : bold ; text-align : center; }
img.miniature {width : 10% ; float : left ; margin : 1%; }
img:not(.miniature) {box-shadow : 10px 10px 10px gray ; display : block ; 
	width :40% ;  margin : 20px auto ; ) 

La pseudo classe :has

:has() est une pseudo‑classe qui permet de cibler un élément parent en fonction de ses enfants.

Exemple 1

Le label associé à un bouton radio change de couleur si ce dernier est coché.

Le code correspondant

Notez le sélecteur : label:has(>input:checked)

Le rendu

Cochez successivement les boutons radio.

Exemple 2

Un DIV incluant une image est plus haut qu'un DIV ne contenant que du texte.

Le code

Notez le sélecteur : div:has(>img)
Donc à chaque fois il faut combiner la pseudo classe :has avec le ">" (sélecteur d'enfant).

Le rendu

les conteneurs DIV avec une image sont plus hauts.

Ciblage via le HTML

L'attribut for de la balise label associe l'étiquette à un contrôle de formulaire permettant de passer le focus à cet élément lorsque l'étiquette est cliquée.
Vous savez qu'avec la norme HTML5 les contrôles de formulaire peuvent désormais être utilisés en dehors du conteneur FORM.
Vous savez transformer un élément "inline" (tel label) en bloc.

Exemple

Le code HTML

Tous les boutons radio ont le même nom ("choix") afin de créer un groupe ; on ne peut alors cocher qu'un seul bouton radio.

Le CSS

input[type =radio]{margin : 5px; }
span {margin :15px 5px 0px 5px; }
label {display : inline-block ; width : 30vw ; border : 1px solid black; vertical-align : top; margin : 10px; }
img{display : block ; width : 50%; margin : 10px auto }
h3{font-size : 1.5em ; text-align : center; }

#r1:checked ~ label #img1 {width : 90%; filter : invert(1); }
#r2:checked ~ label #img2 {width : 90%; filter : invert(1);}
#r3:checked ~ label #img3{width : 90%; filter : invert(1);}
#r4:checked ~ label #img4 {width : 90%; filter : invert(1); }
#r5:checked ~ label #img5{width : 90%; filter : invert(1);}

label {display : inline-block ; ... : L'élément LABEL devient un bloc (mais sans saut de ligne)
#r1:checked ~ label #img1 {width : 90%; filter : invert(1); } : en cochant le premier bouton radio on cible l'image identifiée "img1" pour l'agrandir et la mettre en négatif.

Le rendu

Cochez le premier bouton radio et observez.
Cliquez sur la dernière boite et observez.