Couvrez ce que je ne saurais voir. Où la boite ou case à cocher adaptative, avec la même bonne vielle passe CSS du sélecteur :checked
et du pseudo-élément :before
dit « Checkbox Hack ».
Ce n’est pas un gros tutoriel ni un secret de polichinelle, mais tellement utile. D’autant que nous sommes toujours laissés à nous même. Jouer avec l’élément « checkbox » nous ramène aux bonnes viles interfaces usager à la Netscape! À la merci du navigateur, ironiquement incapable d’adaptation. Et que dire de styliser cette surprenante case à cocher, dans un contexte adaptatif et d’accessibilité? Déjà marginal, ajoutons les marges, les bordures, les médias, les font-size, Alleluia, un petit reset avec ça?...
D’ailleurs, si ce fut aisé, Botstrap l’aurait déjà fait. Et à voir ce qu’il fit « checkboxes version beta 4 », a-t-on vraiment le choix?
Exemple Bootstrap
Personnalisé, y a de quoi, il y a le mot « custom » 4 fois pour un seul « checkbox »!
<label class="custom-control custom-checkbox"> <input type="checkbox" class="custom-control-input"> <span class="custom-control-indicator"></span> <span class="custom-control-description">Cochez cette case personnalisée</span> </label>
L’Interface utilisateur (UI en anglais)
Les puristes vous diront qu’il faut respecter l’Interface utilisateur, l’IU. Vaut mieux ne pas trop changer cet IU et les habitudes de l’utilisateur. Et j’en suis, particulièrement pour les volumineux formulaires. Tout webmestre sait à quel point un formulaire peut être intimidant. Il faut tout faire pour simplifier la vie à l’internaute et l’IU est un des meilleurs moyens. Tout comme un fond blanc avec un texte générique sans frivolité ni poésie en #555! Mais est-ce que le navigateur fait sa part? Si la case à cocher est véritablement un élément de l’IU, pourquoi la boite n’hérite pas de la couleur et de la grandeur du texte ou du parent? C’est bien du texte qui l’entour? Et peut-on aussi désirer un design plus élaboré, très coloré, avec des polices raffinées en gros caractères. Une présentation bien soignée avec un petit formulaire, pourquoi ne pas l’intégrer au visuel?
Comparaison
L’avantage de cette solution est bien sûr de normaliser la présentation des boites à cocher entre les versions des navigateurs. Mais aussi de profiter de l’aspect adaptatif d’une simple police de caractère.
Un exemple vaut mille mots, avec une police et un font-size: 1.5rem;
. À la limite c’est acceptable :
Mais que dire de l’exemple suivant, avec une couleur et une police à font-size: 2rem
. Je peux aussi vivre avec case à cocher qui n’est pas verte, mais pas avec une toute petite boite pour un gros texte :
Police : FontAwesome
Cesse de bavardage, la technique « Checkbox Hack » consiste à couvrir ce qu’on ne saurait voir. En l’occurrence l’élément « checkbox » :
input.cCocher {display:none;}
Une fois la boite cachée, on utilise son « label » associé pour simuler la case à cocher, dans cet exemple avec un pictogramme FontAwesome ajouté devant (:before) :
input.cCocher + label:before { font-family: FontAwesome; content: "\f096"; }
Et ajouter le second pictogramme quand l’élément est coché, avec le sélecteur :checked
.
input.cCocher:checked + label:before { content: "\f046"; }
Code complet avec effet réactif
/* Police font-awesome */ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"> <style> .gros {color:green;font-size: 3rem;} input.cCocher {display:none;} input.cCocher + label {cursor:pointer;margin-right:3rem} input.cCocher + label:before {font-family: FontAwesome;display: inline-block;content: "\f096";width:3rem;} input.cCocher + label:hover:before {content: "\f0fe";} input.cCocher:checked + label:before {content: "\f046";} input.cCocher:checked + label:hover:before {content: "\f146";} </style> <div class="gros"> <input class="cCocher" id="choix1" type="checkbox" /> <label for="choix1">Choix numéro 1</label> <input class="cCocher" id="choix2" type="checkbox" /> <label for="choix2">Choix numéro 2</label> <input class="cCocher" id="choix3" type="checkbox" /> <label for="choix3">Choix numéro 3</label> </div>
Outre l’effet réactif « over », on note une grandeur de texte à 3rem, idem pour la marge à droite du label ainsi que la largeur du pictogramme. Noter que James Barnett préfère utiliser letter-spacing: 10px;
sur CodePen au lieu de la largeur width:3rem;
.
Personnellement je préfère spécifier une classe (cCocher) que de devoir ajuster les éventuelles cases à cocher plus sobres comme un champ de recherche. Mais au lieu de cibler une classe particulière, on peut tout aussi bien cibler l’ensemble des boites à cocher du document. : input[type=checkbox]
.
/* Police font-awesome */ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"> .gros {color:green;font-size: 3rem;} input[type=checkbox] {display:none;} input[type=checkbox] + label {cursor:pointer;margin-right:3rem} input[type=checkbox] + label:before {font-family: FontAwesome;display: inline-block;content: "\f096";width:3rem;} input[type=checkbox]:checked + label:before {content: "\f046";} <div class="gros"> <input id="choix1" type="checkbox" /> <label for="choix1">Choix numéro 1</label> <input id="choix2" type="checkbox" /> <label for="choix2">Choix numéro 2</label> <input id="choix3" type="checkbox" /> <label for="choix3">Choix numéro 3</label> </div>
Résultat
Compatibilité
Ce n’est pas compatible Internet Explorer 8. L’accessibilité en prend pour son rhume, mais il s’agit essentiellement du style. On peut toujours régler le cas avec un « Selectivizr Polyfill pour IE6-8 » ou plus simplement contourner le problème en affichant l’élément « checkbox » par défaut pour les navigateurs Internet Explorer 9 et moins, du genre :
<!--[if lt IE 9]>
<style>
input.cCocher {display:inline-block;}
input.cCocher + label {font-size: 1rem;}
input.cCocher + label:before {font-family: inherit;display: inline-block;content: "";width:inherit}
input.cCocher:checked + label:before {content: "";}
</style>
<![endif]-->
Bouton à bascule (toggle)
Ça n’a absolument rien à voir, c’est exactement la même technique, mais complètement dénaturée. En fait on utilise la case à cocher comme une variable booléenne : ouvert ou fermé, vrais ou faux, 1 ou 0! C’est la méthode derrière la plupart des codes en pure CSS qui requiert l’usage d’une variable normalement géré en JavaScript, trop souvent par son monstrueux jQuery et la méthode « toggle ». Et bien évidemment en la cachant. Comme le simple bouton à bascule au bouton animé « hamburger » à deux états pour ouvrir un menu...
Exemple
/* Police font-awesome */ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"> <style> input.cBascule { display:none; position:absolute; appearance:none; left:-100%; top:-100%; } input.cBascule + label { cursor:pointer; -webkit-font-smoothing: antialiased; } input.cBascule + label:after { font-family: FontAwesome; content: "\f0a9"; } input.cBascule:checked + label:after { content:"\f0a8"; } input.cBascule + label:hover:after { content: "\f059"; } input.cBascule:checked + label:after { content:"\f0a8"; } input.cBascule:checked + label:hover:after { content:"\f059"; } </style> <input type="checkbox" class="cBascule" id="oBascule" /> <label for="oBascule"></label>
Le problème avec ce bouton, c’est qu’il faut souvent un traitement JavaScript en réaction. Aussi bien alors, tout faire en JavaScript.
À lire aussi
Sur le même sujet : « Boite à cocher (checkbox) et bouton « radio » personnalisé en pure CSS »