
Customiser un input checkbox sans label
Avant de commencer
Première fois que vous vous attaquez à la personnalisation d'un input de type checkbox
? Je vous conseille de d'abord aller lire mon autre article :
Comme dans mon article précédant, le but de celui-ci sera de réussir à déveloper un input checkbox sans label visible avec seulement de l'HTML
et du CSS
tout en restant 100% accessible.
Voici le résultat final:
See the Pen
Checkbox without label by Laura Durieux (@Lauwed)
on CodePen.
Ce tutoriel se résume à :
- Côté HTML et accessibilité
- Casser l'apparence par défaut de l'input checkbox
- Personnaliser l'état checked de l'input checkbox
N'attendons plus et plongeons tête la première.
Côté HTML et accessibilité
La balise form
Commençons par créer notre HTML de base. Tout d'abord, qui dit balise input
, dit balise form
. Peu importe l'utilité de votre input, si vous en avez un, c'est qu'il y a une notion de formulaire. Même lorsque vous faites du shopping en ligne et que vous triez les articles en fonction de leur couleurs, c'est un formulaire.
Je vais donc commencer par créer mon formulaire.
<form action="/" method="GET" class="form">
</form>
Je spécifie les deux attributs action
et method
qui sont importants de connaître. Vous pouvez vous réferrer à la documentation MDN pour en savoir plus. J'ajoute également une classe form
pour se mettre en situation le plus possible.
Création de l'input
Ok, première étape pour une bonne accessibilité. Maintenant, nous allons ajouter l'input
et son label
.
<form action="/" method="GET" class="form">
<input type="checkbox" name="todo" value="Manger un ramen" id="ramen">
<label for="ramen"><span>Manger un ramen</span></label>
</form>
Première chose ; Arrêtez de mettre la balise input
dans la balise label
. C'est un bon exemple de vouloir faire un effort niveau accessibilité, mais de ne pas correctement utiliser ses outils. Vous avez également remarqué que j'ai mis le label après l'input. Heureusement, grâce à lattribut value
, le screen reader ira lire directement cette information. Du coup, que le label soit avant ou après la checkbox, la personne aura l'information lorsque il arrivera sur l'input checkbox.
Mais du coup, si je ne mets pas l'input dans le label, comment je fais pour les "lier" ? C'est ici que l'attribut for
rentre en jeu. Vous pouvez remarquer que l'attribut id
de l'input et l'attribut for
du label on la même valeur. L'attribut for
du label permet d'indiquer par l'ID à quel input il appartient. Maintenant, vous pouvez cibler un input même en cliquant sur son label.
Petit plus
Pour finir l'HTML, nous allons anticiper nos besoins pour le CSS en regroupant l'input et le label dans une div
et lui donner une classe en respectant la convention de nommage BEM. Ici, le block
, c'est le form
et l'element
, c'est l'item
.
<form action="/" method="GET" class="form">
<div class="form__item">
<input type="checkbox" value="Manger un ramen" name="ramen" id="ramen">
<label for="ramen"><span>Manger un ramen</span></label>
</div>
</form>
Casser l'apparence par défaut de l'input checkbox
Le style par défaut et utilisation de appearance: none;
Par défault, l'apparence et l'état checked
des inputs sont assez simples.
La propriété de base qui donne justement ce style par défaut, c'est appearance: auto;
inclus dans la user agent stylesheet
. Notre première étape sera donc de supprimer ce style par défault en enlevant l'apparence automatique en utilisant appearance: none;
.
input {
appearance: none;
}
Ajouter du style à l'input
Le résultat c'est... Rien ! Cette propriété enlève tous les styles par défault, ce qui veut dire que la checkbox n'est plus visible, car elle n'a plus de largueur, hauteur, bord, .. définis !
Très bien, maintenant nous allons parler stratégie. Le but ici, c'est de seulement avoir le visuel d'un input checkbox
et ne même plus avoir de texte. La première pensée logique serait de faire dispiraître le labele et de ne changer l'apparence que de l'input
. Or, ce n'est pas la bonne manière de procéder. Pourquoi ? Car comme vous allez le voir, nous allons utiliser un pseudo-element
; ::before
et ce n'est pas possible de l'utiliser sur un élément de type input
, car celui est une balise auto-fermante et ne permet la création de pseudo-element
. Donc, au lieu de créer une 45ème balise div
, nous allons utiliser la balise label
sur laquelle nous pouvons faire tout ça.
Autant dans le précédent tutoriel, ça nous arrangeais pas la propriété appearance: none;
, autant ici ça nous arrange. Elle nous permet de nous débarraser visuellement de la checkbox
sans l'enlever du DOM, elle reste donc complètement accessible.
Une autre technique, aurait été d'enlever la propriété ... et d'appliquer ce snippet de style à l'input
pour cacher cet élément visuellement, sans le détacher du DOM pour qu'il reste accessible pour les screen readers.
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
Pour plus d'informations, n'hésitez pas à aller sur l'article de a11y, Hide content.
Par conséquent, ce sous-titre est mensongé et je vous propose de passer au suivant.
Ajouter du style au label
Maintenant que l'input
est visuellement caché, nous allons nous attaquer au label
. Comme style, j'ai décidé du Neumorphism, même si cette tendance est très déconseillée car elle est très pauvre en contraste et est très peu accessible pour les gens qui ont des déficiences visuelles. Je vous conseille d'aller lire ces petits articles pour plus comprendre la problématique autant de cette tendance :
- Let’s talk Neumorphism and Accessibility
- Optimising Neumorphism for better learnability and accessibility
- Your Last Neumorphism Guide: (The Designer’s Dos and Don’ts)
label {
/* Important, cela nous permettra de centrer l'icône à l'intérieur. */
position: relative;
/* Hauteur, largeur, ... */
height: 70px;
width: 70px;
padding: 20px;
/* Permet d'être un rond */
border-radius: 50%;
transition: 0.3s ease;
/* Ce qui donne l'effet neomorphique */
box-shadow: -2px -2px 5px rgba(white, 1), 2px 2px 5px rgba(black, 0.1);
/* Pour cacher le texte du label */
white-space: nowrap;
text-indent: -2000%;
overflow: hidden;
}
Il nous manque plus qu'à ajouter l'icône au milieu du cercle. Pour cela, je vais utiliser le pseudo-élément ::before
, faire en sorte qu'il fasse la taille du label et après mettre mon icône en background
. Il y a des milliards de faire différentes et la mienne n'est pas forcément la meilleure. J'ai récupérer l'icône sur le super site Iconmonstr.
label::before {
/* Important et indispensable si vous voulez que votre pseudo-élément s'affiche */
content: "";
width: 100%;
height: 100%;
background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0xOCAyNGgtMTJsLTIuNDA0LTEzLjg5OWMtLjYgMS4wODctMS4yODggMi4zMzYtMS43MDQgMy4wOTUtLjQ5Ni45MDctMS44OTIuNTUxLTEuODkyLS40OCAwLS4xNjIuMDU0LS4zMjcuMTM3LS40OC44MjgtMS41MTQgMi43MzctNC45NjMgMi44OC01LjIyMWwtLjAwMi0uMDE1aDkuOTI0bDEuNjIzLTYuMjU5Yy4xMi0uNDQ3LjUyNC0uNzQxLjk2NS0uNzQxLjY1MSAwIDEuMTM5LjYxOS45NjggMS4yNTlsLTEuNDg1IDUuNzQxaC4zOThsNC4xOTktNS41N2MuMzE3LS40NTMuOTQxLS41NjMgMS4zOTMtLjI0Ni40NTIuMzE2LjU2Mi45NDEuMjQ2IDEuMzkzbC0zLjM5NyA0LjQyM2gzLjE2NmwtLjAwNy4wMzZjLjIxMi4zODIgMi4wNTkgMy43MTggMi44NjkgNS4yLjA4My4xNTMuMTIzLjMxOC4xMjMuNDggMCAxLjAzNi0xLjM4NCAxLjM4NC0xLjg3OC40OC0uNDEzLS43NTYtMS4wOTUtMS45OTItMS42OTMtMy4wNzRsLTIuNDI5IDEzLjg3OHptLTIuNDctOGgtNy4wM2wtMi4zOTEtMy4zNDcgMS41NjUgOS4zNDdoOC42ODFsMS41NjUtOS4zNDctMi4zOSAzLjM0N3ptMi41NDItN2gtMTIuMTE0bDMuNTcxIDVoNC45NzFsMy41NzItNXptLTQuMDU3IDIuNWMwLS4yNzYtLjIyNC0uNS0uNS0uNWgtM2MtLjI3NiAwLS41LjIyNC0uNS41IDAgLjI3NS4yMjQuNS41LjVoM2MuMjc2IDAgLjUtLjIyNS41LS41Ii8+PC9zdmc+");
background-position: center;
background-size: 50px;
background-repeat: no-repeat;
/* Pour centrer l'icône */
position: absolute;
left: 0;
top: 0;
transition: background 0.3s ease;
}
Personnaliser l'état checked de l'input checkbox
Nous avons le style de base de notre input. Pourtant, quand je clique sur mon "faux" bouton (car c'est un label
), rien ne se passe. Il nous faut encore définir le style pour l'état :checked
de l'input. faison cela sans attendre.
input:checked + label {
outline: none;
cursor: pointer;
transition: 0.2s ease-in-out;
box-shadow: inset -2px -2px 5px white, inset 2px 2px 5px rgba(0, 0, 0, 0.1);
}
input:checked + label::before {
background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0xOCAyMy45OTlsLTEyIC4wMDEtMS45ODMtMTEuNTc4LjYzNy0xLjEyMyAzLjY5MiA0LjE3MyA3LjI2NC4wMDMgMy43MjEtNC4yMTQuNjUyIDEuMTYtMS45ODMgMTEuNTc4em0tNS4wNzUtMTdsMS42MjItNi4yNThjLjEyLS40NDcuNTI0LS43NDEuOTY1LS43NDEuNjUxIDAgMS4xMzkuNjE4Ljk2OCAxLjI1OGwtMS40ODUgNS43NDFoLjM5OGw0LjIxNC01LjU3MWMuMzE3LS40NTIuOTQxLS41NjIgMS4zOTMtLjI0NS40NTIuMzE2LjU2Mi45NC4yNDYgMS4zOTJsLTMuNDEyIDQuNDI0aDMuMTY2bC0uMDA3LjAzNmMuMjEyLjM4MiAyLjA1OSAzLjcxOCAyLjg2OSA1LjIuMDgzLjE1My4xMzguMzE4LjEzOC40OCAwIDEuMDM2LTEuMzk5IDEuMzg0LTEuODkzLjQ4LS42MS0xLjExNS0xLjgwNi0zLjI3OS0yLjQ1MS00LjQ0NmwtNC42OCA1LjI1aC01Ljk2M2wtNC42NDItNS4zMjdjLS42MzQgMS4xNDYtMS44NyAzLjM4My0yLjQ5NCA0LjUyMy0uNDk1LjkwNy0xLjg3Ny41NTEtMS44NzctLjQ4IDAtLjE2Mi4wNC0uMzI3LjEyMy0uNDguODI4LTEuNTE0IDIuNzM3LTQuOTYyIDIuODgtNS4yMmwtLjAwMy0uMDE2aDkuOTI1em0xLjA3NSA0LjVjMC0uMjc2LS4yMjQtLjUtLjUtLjVoLTNjLS4yNzYgMC0uNS4yMjQtLjUuNXMuMjI0LjUuNS41aDNjLjI3NiAwIC41LS4yMjQuNS0uNSIvPjwvc3ZnPg==");
}
Conclusions
Félicitations !! Vous l'avez fait !
J'espère que ça vous aura aidé. J'essaye d'être la plus claire possible, mais je ne suis pas la meilleure écrivaine, donc je suis toujours ouverte aux feedbacks ouverts réspectueux.
N'hésitez pas à laisser un commentaire et de me supporter en m'achetant un café ✨
Ciao !