Vous pouvez me contacter via Facebook pour questions & suggestions :
Page Facebook relative à mon site
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.
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.
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.
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.
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.
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.
Exemples !
Grâce à deux exemples je vous montre que les sélecteurs de voisinage peuvent être particulièrement utiles.
En utilisant des sélecteurs de voisinage (direct et général) j'évite le recours à des classes.
* {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.
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.
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.
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;}
En cliquant sur le paragraphe l'image proche est stylisée et la légende est affichée.
Le sélecteur complexe peut être composé à partir d'une pseudo-classe OU d'un pseudo-élément.
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 sont utilisées afin de mettre en forme un élément en fonction de son état.
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.
Il devient désormais très facile de cibler une ligne ou un groupe de ligne d'un tableau pour le styliser.
Une page comprend deux tableaux.
Il est identique pour les deux tableaux sauf en ce qui concerne la valeur de l'ID.
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.
#tableau1 {border-spacing : 10px ;}
#tableau1 tr {background : aqua ;}
#tableau1 tr:first-child {background: yellow; }
#tableau1 tr:last-child {background: pink; }
#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.
Aperçu du document HTML dans un iframe :
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.
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
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.
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.
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
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.
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.
La pseudo-classe de négation est une nouveauté CSS3 qui devrait être fort pratique car elle peut simplifier sensiblement les feuilles de style.
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.
On n'utilise dans ce document que les éléments BODY, H1,h2,P & IMG.
* {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 ; )
:has() est une pseudo‑classe qui permet de cibler un élément parent en fonction de ses enfants.
Le label associé à un bouton radio change de couleur si ce dernier est coché.
Notez le sélecteur : label:has(>input:checked)
Cochez successivement les boutons radio.
Un DIV incluant une image est plus haut qu'un DIV ne contenant que du texte.
Notez le sélecteur : div:has(>img)
Donc à chaque fois il faut combiner la pseudo classe :has avec le ">" (sélecteur d'enfant).
les conteneurs DIV avec une image sont plus hauts.
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.
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.
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.
Cochez le premier bouton radio et observez.
Cliquez sur la dernière boite et observez.