Ces derniers jours je passe un peu de temps sur la recherche autour des éléments de formulaire. Vous savez certainement que historiquement il n’est pas toujours possible de personnaliser l’aspect de contrôles de formulaire pour des raisons d’accessibilité (m’a-t-on dit). Cependant il est vrai que l’apparence très variable de ces éléments est sujet à controverse. Et ce n’est pas un mal.

Les codes et styles CSS que je vais vous proposer ici utilisent le niveau 3 de CSS, par conséquent les vieux navigateurs ne sont pas concernés.
Cependant nous tâcherons de travailler nos styles (notamment les sélecteurs CSS) pour faire en sorte que ces vieilleries continuent à afficher les contrôles classiques (nos bons vieux boutons radio et cases à cocher).

Pourquoi s’embêter à trouver une manière de styler des éléments de formulaires ?

Pour harmoniser les styles entre les navigateurs, mais également pour rendre (peut-être) plus affordants certains contrôles, dans un contexte bien précis.
Mon but n’est pas de vous expliquer précisément le contexte, mais de vous donner des solutions techniques.

Modifier légèrement l’aspect des checkboxes

Avec cet exemple, nous allons poser la base de notre CSS, cela me permettra de vous expliquer précisément les sélecteurs utilisés.
Voici ce que je souhaite obtenir.

Aperçu des styles attendus

Voir la démonstration

Mais commençons par notre code HTML, que je vais proposer uniquement sous forme de quelques paragraphes avec un label et un input dans chacun d’eux.

<p>
   <input type="checkbox" id="test1">
   <label for="test1">Rouge</label>
</p>
<p>
   <input type="checkbox" id="test2" checked="checked">
   <label for="test2">Jaune</label>
</p>
<p>
   <input type="checkbox" id="test3" disabled="disabled">
   <label for="test3">Vert</label>
</p>
<p>
   <input type="checkbox" id="test4" checked="checked" disabled="disabled">
   <label for="test4">Marron</label>
</p>

Ce code propose dans l’ordre une checkbox classique, une cochée, une désactivée, et une désactivée cochée.

Passons maintenant au code CSS.
Dans l’absolu, l’élément input:checkbox n’est pas stylable. Nous allons donc jouer sur les styles du label, notamment ses deux pseudo-éléments que nous allons créer et manipuler.

/* Cachons la case à cocher */
[type="checkbox"]:not(:checked),
[type="checkbox"]:checked {
  position: absolute;
  left: -9999px;
}
 
/* on prépare le label */
[type="checkbox"]:not(:checked) + label,
[type="checkbox"]:checked + label {
  position: relative; /* permet de positionner les pseudo-éléments */
  padding-left: 25px; /* fait un peu d'espace pour notre case à venir */
  cursor: pointer;    /* affiche un curseur adapté */
}

C’est dans ce début que réside l’astuce du « j’affiche du personnalisé pour les navigateurs récents, et du classique pour les navigateurs plus vieux ».

Ne cibler que les navigateurs récents

En effet, tous nos styles personnalisés vont commencer par : [type="checkbox"]:checked ou [type="checkbox"]:not(:checked), ce qui veut dire que si le navigateur ne reconnait pas le sélecteur, ces styles ne seront pas appliqués. C’est une sorte de détection de support du navigateur 🙂

Explication du code

La première déclaration permet de placer la checkbox en dehors de l’espace visible de l’écran, sur la gauche. La planquer visuellement sans utiliser de display:none;

La seconde déclaration permet de rendre le label plus « affordant » et de faire une petite place pour notre future checkbox.
La position relative nous est utile pour positionner précisément la checkbox (le label devient référant).

Création des checkboxes

Maintenant on va créer visuellement la checkbox grâce aux pseudo-éléments :after (on l’utilisera pour la coche) et :before (on l’utilisera pour la case à cocher).

/* Aspect des checkboxes */
/* :before sert à créer la case à cocher */
[type="checkbox"]:not(:checked) + label:before,
[type="checkbox"]:checked + label:before {
  content: '';
  position: absolute;
  left:0; top: 2px;
  width: 17px; height: 17px; /* dim. de la case */
  border: 1px solid #aaa;
  background: #f8f8f8;
  border-radius: 3px; /* angles arrondis */
  box-shadow: inset 0 1px 3px rgba(0,0,0,.3) /* légère ombre interne */
}
 
/* Aspect général de la coche */
[type="checkbox"]:not(:checked) + label:after,
[type="checkbox"]:checked + label:after {
  content: '✔';
  position: absolute;
  top: 0; left: 4px;
  font-size: 14px;
  color: #09ad7e;
  transition: all .2s; /* on prévoit une animation */
}
/* Aspect si "pas cochée" */
[type="checkbox"]:not(:checked) + label:after {
  opacity: 0; /* coche invisible */
  transform: scale(0); /* mise à l'échelle à 0 */
}
/* Aspect si "cochée" */
[type="checkbox"]:checked + label:after {
  opacity: 1; /* coche opaque */
  transform: scale(1); /* mise à l'échelle 1:1 */
}

La première déclaration ici permet de régler la taille de la coche, sa position, sa couleur, etc.

Les deux suivantes permettent de définir leur forme : non cochée est transparent et réduit, cochée est opaque et à l’échelle. Ces valeurs vont subir une transition de 0 vers 1 (ou inversement), puisqu’on a prévu une animation avec la propriété transition.

Styler les différents états

Nos styles de base sont en place, maintenant si vous souhaitez régler les autres états (désactivée, désactivée et cochée, qui a le focus) voici quelques proposition de style, principalement des modifications sur l’aspect des bordures ou de la coche (couleur, forme).

/* aspect désactivée */
[type="checkbox"]:disabled:not(:checked) + label:before,
[type="checkbox"]:disabled:checked + label:before {
  box-shadow: none;
  border-color: #bbb;
  background-color: #ddd;
}
/* styles de la coche (si cochée/désactivée) */
[type="checkbox"]:disabled:checked + label:after {
  color: #999;
}
/* on style aussi le label quand désactivé */
[type="checkbox"]:disabled + label {
  color: #aaa;
}
 
/* aspect au focus de l'élément */
[type="checkbox"]:checked:focus + label:before,
[type="checkbox"]:not(:checked):focus + label:before {
  border: 1px dotted blue;
}

Voilà pour quelques idées de styles personnalisés.

N’oubliez pas de préfixer les propriétés CSS3 pour les navigateurs concernés.

Poussons le délire un peu plus loin – Styles avancés

Je ne vais pas faire le détail de cette démonstration pour la simple et bonne raison que tout le principe reste le même.
Il est possible ensuite de composer autant d’éléments visuels en ajoutant éventuellement des éléments HTML dans le label (essayez de ne pas en abuser quand même).
Voici donc ce qu’il est possible de faire avec un élément supplémentaire dans le label.

checkbox-flat-ui
Voir la démonstration

Ces deux exemples de styles personnalisés utilisent l’unité pixel (px) pour plus d’aisance à leur compréhension. Pour faire les choses correctement et de manière plus flexible, essayez d’utiliser l’unité em, % ou rem suivant votre besoin et expérience.

À la recherche d’idées

Une fois que j’avais réussi à faire ça, tout content de moi je suis allez voir ce que font les copains.
Voici quelques idées, plus graphiques que techniques, car la plupart des démonstrations que j’ai vu ne sont pas accessibles.

Checkbox animée
Checkboxes Animées

checkbox-lightsaber
Checkboxes sabres laser

checkbox-styles
Diverses checkboxes

Et ceux qui ont bien compris le principe, j’imagine que vous comprenez aussi que l’on peut produire ce genre de styles avec des boutons radio ?

Bon, ben c’est à vous maintenant !

This post is also avalaible in : Anglais