Niveau 2 — Sélecteurs

Les sélecteurs d'attributs

Cibler des éléments en fonction de la présence ou de la valeur de leurs attributs HTML.

1. Comprendre les sélecteurs d'attributs

En une phrase : Un sélecteur d'attribut cible un élément en fonction de la présence, de la valeur exacte ou d'un motif dans l'un de ses attributs HTML, le tout entre crochets [].

Les attributs sont une partie intégrante du HTML. Les sélecteurs d'attributs permettent de styler des éléments sans ajouter de classes, en exploitant directement les informations déjà présentes dans le markup.

/* Syntaxe générale */
sélecteur[attribut] { ... }            /* Présence */
sélecteur[attribut="valeur"] { ... }   /* Valeur exacte */
sélecteur[attribut^="début"] { ... }   /* Commence par */
sélecteur[attribut$="fin"] { ... }     /* Finit par */
sélecteur[attribut*="contenu"] { ... } /* Contient */
sélecteur[attribut~="mot"] { ... }     /* Mot exact (espace) */
sélecteur[attribut|="langue"] { ... }  /* Préfixe de langue */
Sélecteur Signification Exemple Cible
[href] Attribut présent a[href] Tous les liens avec href
[type="text"] Valeur exacte input[type="text"] Inputs de type texte
[class^="btn"] Commence par div[class^="col-"] Colonnes grid (col-1, col-2…)
[class$="primary"] Finit par button[class$="primary"] Boutons de type primary
[class*="card"] Contient div[class*="card"] Éléments avec "card" dans la classe
[lang~="fr"] Mot exact (espace) span[lang~="fr"] Éléments en français
[hreflang|="en"] Préfixe langue a[hreflang|="en"] Liens en anglais

2. Syntaxe détaillée

2.1 Correspondance exacte : [attr="value"]

Définition : Le sélecteur [attr="value"] cible les éléments dont l'attribut a exactement la valeur spécifiée. Correspondance sensible à la casse.
/* Tous les inputs de type texte */
input[type="text"] {
  border: 2px solid #2563eb;
  padding: 0.6rem 0.75rem;
  border-radius: 6px;
}

/* Tous les liens vers la page d'accueil */
a[href="https://exemple.com"] {
  font-weight: 700;
  color: #dc2626;
}

/* Tous les éléments avec un data-role spécifique */
[data-role="admin"] {
  border: 2px solid #f59e0b;
}

2.2 Présence de l'attribut : [attr]

Définition : Le sélecteur [attr] cible les éléments qui possèdent l'attribut, quelle que soit sa valeur. Utile pour détecter la présence d'un attribut optionnel.
/* Tous les liens qui ont un href (les liens actifs) */
a[href] {
  color: #2563eb;
  text-decoration: underline;
}

/* Tous les éléments avec un data-tooltip */
[data-tooltip] {
  position: relative;
  cursor: help;
}

/* Tous les images avec alt (accessibilité) */
img[alt] {
  border: 1px solid #e2e8f0;
}

2.3 Commence par : [attr^="value"]

Définition : Le sélecteur [attr^="value"] cible les éléments dont la valeur de l'attribut commence par la chaîne spécifiée. Le symbole ^ signifie « début ».
/* Tous les liens externes (commencent par http) */
a[href^="http"] {
  color: #2563eb;
}

/* Tous les boutons dont la classe commence par "btn" */
button[class^="btn"] {
  padding: 0.5rem 1rem;
  border-radius: 6px;
  font-weight: 600;
}

/* Emails */
a[href^="mailto:"] {
  color: #7c3aed;
}

2.4 Finit par : [attr$="value"]

Définition : Le sélecteur [attr$="value"] cible les éléments dont la valeur de l'attribut finit par la chaîne spécifiée. Le symbole $ signifie « fin ».
/* Liens vers des fichiers PDF */
a[href$=".pdf"] {
  color: #dc2626;
}

/* Liens vers des images */
a[href$=".jpg"],
a[href$=".png"],
a[href$=".webp"] {
  color: #16a34a;
}

/* Boutons de type "primary" */
button[class$="primary"] {
  background: #2563eb;
  color: white;
}

2.5 Contient : [attr*="value"]

Définition : Le sélecteur [attr*="value"] cible les éléments dont la valeur de l'attribut contient la chaîne spécifiée quelque part. Le symbole * signifie « n'importe quoi ».
/* Tous les éléments avec "card" dans leur classe */
[class*="card"] {
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 1rem;
}

/* Liens vers Twitter */
a[href*="twitter.com"] {
  color: #1da1f2;
}

/* Liens vers GitHub */
a[href*="github.com"] {
  color: #333;
}

2.6 Mot exact (espace) : [attr~="word"]

Définition : Le sélecteur [attr~="word"] cible les éléments dont la valeur de l'attribut est une liste de mots séparés par des espaces et qui contient le mot spécifié exactement.
/* Le mot "français" dans une liste de langues */
span[lang~="fr"] {
  font-weight: 700;
}

/* HTML : <span lang="fr be"> — le mot "fr" est présent ✓ */
/* HTML : <span lang="français"> — le mot "fr" n'est pas un mot isolé ✗ */

2.7 Préfixe de langue : [attr|="prefix"]

Définition : Le sélecteur [attr|="prefix"] cible les éléments dont la valeur est exactement le préfixe ou commence par le préfixe suivi d'un tiret -. Utilisé principalement avec les codes de langue (ex: hreflang).
/* Liens en anglais (toutes variantes) */
a[hreflang|="en"] {
  color: #2563eb;
}

/* Cible : hreflang="en", hreflang="en-US", hreflang="en-GB" */
/* Ne cible PAS : hreflang="fr", hreflang="français" */

/* Liens en français */
a[hreflang|="fr"] {
  color: #dc2626;
}

3. Visualisation

┌──────────────────────────────────────────────────────────┐
│           SÉLECTEURS D'ATTRIBUTS EN SCHÉMA              │
├──────────────────────────────────────────────────────────┤
│                                                          │
│  [attr]          →  Présent ?       Oui/Non              │
│  [attr="val"]    →  Exact ?         "val" == "val"       │
│  [attr^="val"]   →  Commence par ?  "val..."             │
│  [attr$="val"]   →  Finit par ?     "...val"             │
│  [attr*="val"]   →  Contient ?     "...val..."           │
│  [attr~="val"]   →  Mot exact ?    "mot val mot"        │
│  [attr|="val"]   →  Préfixe langue? "val" ou "val-xx"   │
│                                                          │
│  Exemples avec un attribut href :                        │
│  ┌────────────────────────────────────────────────────┐  │
│  │ [href]         → tout lien avec href               │  │
│  │ [href="https://exemple.com"] → lien exact           │  │
│  │ [href^="http"] → lien externe                       │  │
│  │ [href$=".pdf"] → fichier PDF                        │  │
│  │ [href*="blog"] → lien contenant "blog"              │  │
│  └────────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────────┘

Résumé visuel des 7 sélecteurs d'attributs

4. Exemples progressifs

4.1 Inputs avec type

Démonstration : Style par type d'input

/* Sélecteur exact : [type="text"] */
input[type="text"] {
  border: 2px solid #2563eb;
  border-radius: 6px;
  padding: 0.6rem 0.75rem;
  display: block;
  width: 100%;
  max-width: 350px;
  margin-bottom: 0.5rem;
}

4.2 Liens avec href

Démonstration : Tous les liens avec href

/* Présence : [href] */
a[href] {
  display: block;
  padding: 0.5rem 0.75rem;
  color: #2563eb;
  border-left: 3px solid #2563eb;
  background: #f8fafc;
  border-radius: 0 4px 4px 0;
}
Lien avec href Lien mailto Lien ancre Texte sans lien (pas de bordure)

4.3 Commence par : classes btn-*

Démonstration : Boutons avec [class^="btn"]

/* Commence par : [class^="btn"] */
button[class^="btn"] {
  padding: 0.6rem 1.2rem;
  border: none;
  border-radius: 6px;
  font-weight: 600;
  margin-right: 0.5rem;
}

button[class^="btn"]:first-child {
  background: #2563eb;
  color: white;
}

/* Note : ceci cible aussi les liens avec class="btn-text" */
Ceci est un lien avec "btn-text" — pas ciblé par le sélecteur de bouton

4.4 Finit par : cartes primaires

Démonstration : Cartes avec [class$="primary"]

/* Finit par : [class$="primary"] */
[class$="primary"] {
  border: 2px solid #2563eb;
  border-radius: 8px;
  padding: 1rem;
  margin-bottom: 0.75rem;
  background: #eff6ff;
}
Carte Primaire

Cette carte a une classe finissant par "primary"

Carte Secondaire

Cette carte a une classe finissant par "secondary"

Carte Succès

Cette carte a une classe finissant par "success"

4.5 Contient : éléments "card"

Démonstration : Tout ce qui contient "card"

/* Contient : [class*="card"] */
[class*="card"] {
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 1rem;
  margin-bottom: 0.75rem;
}

[class*="card"]:hover {
  box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
}
item-card — contient "card"
item-card-highlight — contient "card"
item-card-header — contient "card"
Élément sans "card" — pas ciblé

4.6 Mot exact : langues

Démonstration : Éléments avec attribut lang

/* Mot exact : [lang~="fr"] */
span[lang~="fr"] {
  background: #dbeafe;
  color: #1e40af;
  padding: 0.3rem 0.6rem;
  border-radius: 4px;
  font-weight: 600;
}

span[lang~="en"] {
  background: #fef3c7;
  color: #92400e;
  padding: 0.3rem 0.6rem;
  border-radius: 4px;
  font-weight: 600;
}
Bonjour Hello Belgique United States Hallo Hola France United Kingdom

4.7 Préfixe de langue : hreflang

Démonstration : Liens avec hreflang

/* Préfixe langue : [hreflang|="en"] */
a[hreflang|="en"] {
  background: #fef3c7;
  color: #92400e;
  padding: 0.3rem 0.6rem;
  border-radius: 4px;
  text-decoration: none;
  font-weight: 600;
  margin-right: 0.5rem;
}

a[hreflang|="fr"] {
  background: #dbeafe;
  color: #1e40af;
  padding: 0.3rem 0.6rem;
  border-radius: 4px;
  text-decoration: none;
  font-weight: 600;
  margin-right: 0.5rem;
}

5. Erreurs fréquentes

Erreur 1 : Confondre ^ et *
/* FAUX — cible les éléments dont le début du class est "btn" */
[class^="btn-primary"] { ... }

/* CORRECT — si tu veux cibler les classes contenant "btn-primary" */
[class*="btn-primary"] { ... }

/* OU — si tu veux cibler les classes finissant par "primary" */
[class$="primary"] { ... }
Erreur 2 : Trop large avec *
/* FAUX — trop large, cible TOUT ce qui contient "a" dans un attribut */
[href*="a"] { ... }

/* CORRECT — cibler plus précisément */
[href*="twitter.com"] { ... }
Erreur 3 : Confondre ~ et |
/* ~ = mot exact dans une liste d'espaces */
span[lang~="fr"] { ... }    /* "fr" dans "fr be" ✓ */

/* | = préfixe de langue (spécifique aux codes de langue) */
a[hreflang|="fr"] { ... }   /* "fr" ou "fr-CA" ✓, "français" ✗ */
Erreur 4 : Oublier la valeur entre guillemets
/* FAUX — pas de guillemets */
a[href=http://example.com] { ... }

/* CORRECT */
a[href="http://example.com"] { ... }

6. Bonnes pratiques

Règles d'or :
  • Combiner avec des classes : .btn[class^="btn-"] est plus précis que [class^="btn-"].
  • Utiliser ^ et $ pour des correspondances précises (début/fin).
  • Préférer * avec parcimonie — trop large = effets de bord.
  • Exploiter les data-attributes pour le styling sans classes supplémentaires.
  • Tester les sélecteurs d'attributs avec DevTools avant de les appliquer.
  • Utiliser | uniquement pour les attributs de langue (lang, hreflang).
/* ✅ Bonne pratique : ciblage précis */
.nav-link[href^="https://"]::after {
  content: " ↗";
  font-size: 0.8em;
}

/* ✅ Bonne pratique : data-attributes pour le styling */
[data-status="active"] {
  border-left: 3px solid #16a34a;
}

[data-status="pending"] {
  border-left: 3px solid #f59e0b;
}

[data-status="error"] {
  border-left: 3px solid #dc2626;
}

/* ✅ Bonne pratique : combinaison avec pseudo-classe */
input[type="email"]:valid {
  border-color: #16a34a;
}

input[type="email"]:invalid:not(:placeholder-shown) {
  border-color: #dc2626;
}

/* ✅ Bonne pratique : ciblage par extension de fichier */
a[href$=".pdf"]::before {
  content: "📄 ";
}

a[href$=".zip"]::before {
  content: "📦 ";
}

7. Mini-défi

Exercice 1 : Inputs par type

Écris un sélecteur pour cibler tous les <input> de type email et appliquer :

  • border: 2px solid #7c3aed
  • border-radius: 6px
  • padding: 0.6rem

Solution :

input[type="email"] {
  border: 2px solid #7c3aed;
  border-radius: 6px;
  padding: 0.6rem;
}

Exercice 2 : Liens externes

Écris un sélecteur pour cibler tous les liens dont le href commence par https:// et ajouter :

  • color: #2563eb
  • text-decoration: underline

Solution :

a[href^="https://"] {
  color: #2563eb;
  text-decoration: underline;
}

Exercice 3 : Fichiers PDF

Écris un sélecteur pour cibler tous les liens vers des fichiers .pdf et :

  • Ajouter l'icône 📄 avant avec ::before
  • color: #dc2626
  • font-weight: 600

Solution :

a[href$=".pdf"]::before {
  content: "📄 ";
}

a[href$=".pdf"] {
  color: #dc2626;
  font-weight: 600;
}

Exercice 4 : Data attributes

Crée des badges avec data-priorite et applique des styles différents :

  • [data-priorite="haute"] : fond rouge, texte blanc
  • [data-priorite="moyenne"] : fond orange, texte brun
  • [data-priorite="basse"] : fond gris, texte foncé

Solution :

[data-priorite="haute"] {
  background: #dc2626;
  color: white;
  padding: 0.3rem 0.75rem;
  border-radius: 999px;
  font-weight: 600;
}

[data-priorite="moyenne"] {
  background: #f59e0b;
  color: #78350f;
  padding: 0.3rem 0.75rem;
  border-radius: 999px;
  font-weight: 600;
}

[data-priorite="basse"] {
  background: #e2e8f0;
  color: #1e293b;
  padding: 0.3rem 0.75rem;
  border-radius: 999px;
  font-weight: 600;
}

8. Projet d'application

Projet : Page de ressources avec sélecteurs d'attributs

Crée un fichier index.html et style.css avec :

HTML requis :

  • Un formulaire avec input[type="text"], type="email", type="password", type="url"
  • Des liens vers différents types de fichiers (PDF, ZIP, JPG, MP4)
  • Des liens externes (https://) et internes (ancre #)
  • Des éléments avec data-status (active, pending, error)
  • Des éléments avec data-priorite (haute, moyenne, basse)

CSS requis :

  • input[type="text"] : bordure bleue
  • input[type="email"] : bordure violette
  • input[type="password"] : bordure rouge
  • a[href$=".pdf"] : icône PDF
  • a[href^="https://"] : icône lien externe
  • [data-status] : bordure colorée selon le status
  • [data-priorite] : badge coloré selon la priorité

9. Révision

Quiz rapide

  1. Quel sélecteur cible un élément avec l'attribut href présent ?
  2. Quel symbole signifie « commence par » dans un sélecteur d'attribut ?
  3. a[href$=".pdf"] cible quel type de liens ?
  4. Quelle est la différence entre [class*="btn"] et [class^="btn"] ?
  5. [lang~="fr"] cible <span lang="français"></span> ? Oui / Non
  6. Quel sélecteur cible les liens vers tous les fichiers PDF ?
  7. Quelle est la différence entre ~ et | dans les sélecteurs d'attributs ?
  8. Pourquoi préférer ^ ou $ à * quand c'est possible ?
  9. Donne un cas d'usage des data-attributes pour le styling.
  10. Peut-on combiner un sélecteur d'attribut avec une pseudo-classe ?
Réponses :
  1. a[href]
  2. ^
  3. Les liens vers des fichiers PDF (finit par ".pdf")
  4. * cible les classes contenant "btn" n'importe où ; ^ cible uniquement celles commençant par "btn"
  5. Non — "français" n'est pas un mot isolé dans une liste d'espaces
  6. a[href$=".pdf"]
  7. ~ = mot exact dans une liste d'espaces ; | = préfixe de langue (spécifique aux codes langues)
  8. Parce que * peut correspondre à des sous-chaînes non désirées et créer des effets de bord
  9. [data-status="active"] pour cibler les éléments actifs, [data-priorite="haute"] pour les éléments urgents
  10. Oui : input[type="email"]:valid combine sélecteur d'attribut et pseudo-classe