Maîtriser les sélecteurs de fratrie généraux: éléments de formulaire personnalisés
() translation by (you can also view the original English article)
L'un des sélecteurs CSS les plus puissants et les moins utilisés est le combinateur général de frères et sœurs: ~
. Dans les tutoriels à venir, je vais aborder différentes façons d'utiliser ~
pour créer des composants non seulement visuellement attrayants, mais aussi fonctionnels et utiles. Ce tutoriel couvrira les éléments du formulaire; radio, case à cocher et entrées régulières.
Nous apprendrons beaucoup: les sélecteurs de CSS modernes, la propriété de will-change
, les propriétés de SVG stroke
, les états d'entrée et beaucoup plus!
Avant de commencer..
Une clause de non-responsabilité rapide: ces effets CSS peuvent ou ne fonctionnent pas dans les anciens navigateurs–je les ai testés dans les dernières versions de Chrome, Firefox et Safari.
J'utiliserai Haml (un compilateur HTML) et Sass (un préprocesseur CSS) pour accélérer le processus de codage! Les démonstrations utiliseront Haml alors que n'importe quel code en ligne utilisera un HTML régulier.
J'utiliserai également l'incroyable AutoPrefixer au lieu des préfixes de fournisseur. Si vous utilisez CodePen, assurez-vous d'accéder aux paramètres de votre stylo, cliquez sur CSS et sélectionnez AutoPrefixer.



Entrées radio
Nous commencerons avec l'un des éléments de forme les plus élémentaires: l'entrée radio. Il existe deux états visuels principaux (vérifiés et non contrôlés) ainsi que deux états intermédiaires (le survol et le clic/actif–le clic est semblable en apparence à coché).
Version SVG
La première étape consiste à configurer notre HTML. Vous aurez besoin d'un conteneur extérieur principal et d'un conteneur intérieur avec deux enfants: un div
contenant les éléments d'entrée et visuels et un label
pour l'entrée. J'aime utiliser un fieldset
pour le conteneur externe. Assurez-vous d'ajouter une ID pour l'entrée qui correspond à l'attribut for
de l'étiquette.
1 |
<fieldset>
|
2 |
<div class="container"> |
3 |
<div class="svg"> |
4 |
<input id="radio-svg" type="radio" name="option"/> |
5 |
<div></div>
|
6 |
<svg viewBox="0 0 24 24"> |
7 |
<circle cx="12" cy="12" r="8"></circle> |
8 |
<circle cx="12" cy="12" r="8"></circle> |
9 |
</svg>
|
10 |
</div>
|
11 |
<label for="radio-svg">SVG</label> |
12 |
</div>
|
13 |
</fieldset>
|
L'étape suivante consiste à cacher l'entrée par défaut, à ajouter un style visuel de base et à masquer les éléments supplémentaires qui ne s'affichent que lorsque l'entrée radio est sélectionnée. L'idée est de rendre l'entrée invisible, mais de la positionner sur top des éléments visuels, de sorte que cliquer sur l'entrée de la radio semble cliqueter sur l'option radio visuelle. Nous pouvons le faire en position: relative
à .svg
et position: absolute
à l'entrée, puis à cacher l'entrée.
Remarque: vous pouvez formater cette façon de choisir. J'ai choisi un style de cercle de base qui imite la radio par défaut, sauf qu'il est plus plat.
Nous allons définir certaines variables de couleur à l'aide de Sass; quelques couleurs grises et un bleu vif pour la radio sélectionnée. Nous allons également définir une variable $p
pour notre unité par défaut: 12px est un bon nombre car il est divisible par une large gamme de nombres différents (1, 2, 3, 4, 6).
J'ai mis les variables principales dans l'intégration directement, mais un style supplémentaire peut être trouvé ici ou en cliquant sur la page CodePen, en cliquant sur Settings dans le coin supérieur droit et en cliquant sur l'onglet CSS pour afficher des feuilles de style supplémentaires.
Nous avons fait du premier cercle un gris clair et le deuxième du bleu vif, puis caché le deuxième en configurant transform: scale(0)
. Plus tard, nous allons animer le cercle, alors il est important de définir l'échelle maintenant.
Après avoir réglé tout cela, nous devons décider des styles visuels pour chaque état. Pour cet exemple, j'ai décidé que sur le vol stationnaire, le cercle gris clair devrait tourner à un bleu clair; sur le clic, le cercle bleu s'efface et le fond gris devient blanc, puis reste ainsi pour l'état vérifié. La seule façon de supprimer l'état vérifié d'une radio est de cliquer sur une autre radio, auquel cas le bleu et le blanc devraient simplement disparaître.
Nous allons régler les couleurs en premier, puis animer après que tous les états ont des couleurs. C'est là que le tilde ~
est pratique. Ce sélecteur de fratrie général (le combinateur de fratrie) sélectionnera le second élément tant qu'il sera précédé du premier élément quelque part, et ils partagent un parent commun. Nous utilisons input:hover ~ div
pour sélectionner l'élément visuel lorsque l'entrée survient.
Essayez de cliquer sur la première radio, puis sur la seconde–vous devriez clairement voir les états actifs et contrôlés.
L'étape finale consiste à configurer les animations pour chaque état. La clé pour animer tous ces états différents est de définir les transitions non contrôlées par défaut et de définir les transitions vérifiées lorsque l'entrée est cliquée. J'utilise une nouvelle propriété CSS appelée will-change
pour permettre au navigateur de connaître les propriétés que je vais animer.
Version HTML
Vous pouvez également créer cette entrée radio personnalisée sans utiliser de SVG. La configuration est similaire:
1 |
<fieldset>
|
2 |
<div class="container"> |
3 |
<div class="svg"> |
4 |
<input id="radio-html" type="radio" name="option"/> |
5 |
<div></div>
|
6 |
<div></div>
|
7 |
<div></div>
|
8 |
</div>
|
9 |
<label for="radio-html">HTML</label> |
10 |
</div>
|
11 |
</fieldset>
|
Le CSS est presque exactement le même, sauf avec un peu plus de style pour les deux éléments div
qui ont remplacé les cercles SVG. Dans ce cas, nous utilisons nth-of-type(n)
pour sélectionner les différents éléments div afin que nous ne devrions pas leur donner une classe dans le HTML.
Avec la version SVG, il y a plus de balisage mais moins de style; avec la version HTML, c'est l'inverse. Les résultats semblent identiques, alors essayez l'un de vos préférences de codage!
Entrées de case à cocher
L'élément de formulaire suivant que nous allons personnaliser est l'entrée de la case à cocher. Ses états sont semblables à ceux de l'entrée radio: deux états visuels principaux (vérifiés et non contrôlés) et deux états intermédiaires (survoler et cliquer/actif).
Version SVG
La configuration ressemble beaucoup à l'entrée radio, mais utilise des lignes pour former la case à cocher au lieu des cercles.
1 |
<fieldset>
|
2 |
<div class="container"> |
3 |
<div class="svg"> |
4 |
<input id="checkbox-svg" type="checkbox"> |
5 |
<div></div>
|
6 |
<div></div>
|
7 |
<svg viewBox="0 0 24 24"> |
8 |
<g>
|
9 |
<line x1="4.5" x2="9.24" y1="12.5" y2="17.24"></line> |
10 |
<line x1="9.24" x2="19.76" y1="17.24" y2="6.73"></line> |
11 |
</g>
|
12 |
<g>
|
13 |
<line x1="4.5" x2="9.24" y1="12.5" y2="17.24"></line> |
14 |
<line x1="9.24" x2="19.76" y1="17.24" y2="6.73"></line> |
15 |
</g>
|
16 |
</svg>
|
17 |
</div>
|
18 |
<label for="checkbox-svg">SVG</label> |
19 |
</div>
|
20 |
</fieldset>
|
Les lignes du premier groupe auront une couleur gris clair et ne seront pas animées; les lignes du second groupe seront animées lorsque la saisie est cliquée.
Il existe également un élément div
supplémentaire; Nous allons l'utiliser pour créer un effet de clic où le bleu vif se développe en arrière-plan. Afin de faire fonctionner l'effet, le div doit être un cercle bleu avec une plus grande largeur et hauteur que la case à cocher réelle, et le conteneur extérieur doit avoir un overflow: hidden;
définissez de sorte que les bords du cercle ne s'affichent pas. La division ronde devrait avoir transform: scale(0)
définie, semblable à la radio.



Encore une fois, formatez ceci en fonction de vos préférences. J'ai décidé d'arrondi les bords de la marque de contrôle ainsi que tous les coins.
L'étape suivante consiste à préparer les animations. Les effets sont semblables à la radio, sauf qu'au lieu d'un cercle en expansion, la marque de contrôle s'inspire. Pour cette animation, nous devrons utiliser stroke-dashoffset
sur les lignes SVG.
Afin d'animer stroke-dashoffset
, nous aurons besoin de la longueur de chaque ligne. J'ai créé un outil sur CodePen pour calculer les longueurs, mais si vous utilisez la case à cocher que j'ai déjà créée, la longueur de la ligne la plus courte est 6.708
et la plus longue est 14.873
. Nous utiliserons cette valeur pour définir à la fois stroke-dashoffset
et stroke-dasharray
. Ceci est uniquement nécessaire pour la première coche (le deuxième ensemble de lignes s'affiche par défaut dans l'état non contrôlé).
Lorsque l'entrée est cliquée, nous définissons le stroke-dashoffset
sur 0
, lequel (avec une transition) ressemblera à la ligne "dessinée". Nous devons également ajouter les autres changements d'état à partir de la radio personnalisée, y compris les changements d'arrière-plan sur le vol stationnaire et l'échelle du cercle sur le clic.
La dernière étape consiste à ajouter toutes les transitions. Encore une fois, nous allons régler les transitions non contrôlées par défaut et définir les transitions vérifiées à la cliquet. De la même manière que le cercle qui s'efface pour la radio, nous ferons disparaître la coche après avoir été désactivé.
Version HTML
Vous pouvez également obtenir le même effet avec quelques éléments div au lieu d'utiliser un SVG; le marquage est plus simple, mais pas aussi clairement délimité. La première div vide est le cercle bleu en expansion, la seconde est la case à cocher par défaut et la troisième est la case à cocher qui s'anime lorsqu'elle est cliquée.
1 |
<fieldset>
|
2 |
<div class="container"> |
3 |
<div class="line"> |
4 |
<input id="checkbox-html" type="checkbox"> |
5 |
<div></div>
|
6 |
<div></div>
|
7 |
<div></div>
|
8 |
</div>
|
9 |
<label for="checkbox-html">HTML</label> |
10 |
</div>
|
11 |
</fieldset>
|
Nous utiliserons :before
et :after
chaque partie de la case à cocher, ce qui simplifie le balisage, sinon vous auriez besoin de quatre éléments vides ou plus pour créer les deux cases à cocher. Nous devons positionner les lignes manuellement et les faire pivoter, mais vous pouvez utiliser une seule transformation pour les faire pivoter et les dessiner.
Version symbolique
Vous pouvez également utiliser un symbole de coche au lieu de faire pivoter les éléments div. Ce n'est pas tout à fait le même que les deux autres visuellement, mais cela fonctionne aussi bien.
1 |
<fieldset>
|
2 |
<div class="container"> |
3 |
<div class="symbol"> |
4 |
<input id="checkbox-sym" type="checkbox"> |
5 |
<div></div>
|
6 |
<div>✓</div> |
7 |
<div>✓</div> |
8 |
</div>
|
9 |
<label for="checkbox-sym">Symbol</label> |
10 |
</div>
|
11 |
</fieldset>
|
Remarque: vous n'avez besoin que du symbole HTML dans les deux derniers éléments div, mais dans la démo ci-dessous, je l'ai inclus dans les trois divs afin que je puisse l'inclure dans la boucle répétée.
Puisque nous ne pouvons pas dessiner le symbole, la version blanche s'efface en appuyant sur. Découvrez les trois versions ci-dessous!
Entrées régulières
La dernière partie de ce tutoriel est la saisie régulière de texte. Je me suis inspiré des entrées de ligne Matériel de Google. Ces entrées ont quelques états différents: par défaut, actif/foyer (lorsque le curseur clignotant est visible) et un survol subtil.
La configuration est encore plus minime que les deux styles de saisie précédents. Nous avons un jeu de champs, l'entrée, une étiquette et un élément div pour la bordure.
1 |
<fieldset>
|
2 |
<input id="example" type="text"> |
3 |
<label for="example">Label</label> |
4 |
<div></div>
|
5 |
</fieldset>
|
La prochaine étape consiste à définir l'entrée. Nous ne cacherons pas l'entrée cette fois puisque nous en avons besoin pour montrer la valeur. Nous allons également créer une étiquette qui se déplace vers le haut et vers le bas lorsque nous nous concentrons sur l'entrée. Pour que cela fonctionne, nous devrons positionner l'étiquette exactement au dessus de l'entrée. La bordure div aura un :after
pseudo élément qui s'inspire de la bordure lorsque l'entrée est cliquée; nous allons mettre un scale(0)
sur le pseudo élément pour la préparer à l'animation.
Si vous essayez de cliquer sur l'entrée de démonstration ci-dessus et de commencer à taper, vous remarquerez que les types de texte sont affichés en haut de l'étiquette. Nous allons animer l'étiquette à rétrécir et à traduire en cliquant dessus. Vous pouvez utiliser entièrement des transformations pour éviter le repeint, au lieu d'utiliser le font-size
comme je l'ai fait, mais j'ai constaté que l'utiliser ainsi que le translateY
m'a donné une animation beaucoup plus précise. Nous supprimerons également l'échelle sur les div :after
pour faire l'animation du dessin.
Maintenant, si vous essayez de cliquer sur l'entrée de démonstration ci-dessus et de recommencer à taper, l'étiquette diminue et se déplace en douceur, mais si vous laissez le texte saisi dans l'entrée et cliquez sur l'extérieur, l'étiquette redescend, obstruant l'entrée. Nous pourrions utiliser JavaScript pour éviter ce comportement, mais nous pouvons également utiliser un état d'entrée CSS appelé :valid
.
Nous pouvons ajouter required
comme attribut vide à notre contribution en HTML ou ajouter :required => true
à nos attributs d'entrée dans Haml. Ensuite, nous ajoutons :valid
pour les propriétés :focus
dans notre Sass/CSS. Cela ajoute un état visuel supplémentaire à notre saisie, et comme c'est une entrée de texte simple, le seul état valide est le moment où le texte est entré.
Remarque: l'utilisation d'un type d'entrée différent, par exemple une entrée par courrier électronique, entraînera la rupture de ce comportement, car les entrées de courrier électronique ont des exigences de validité différentes.
Inspiration
Si vous souhaitez créer vos propres entrées en utilisant ces techniques, mais vous avez besoin de plus d'inspiration visuelle, consultez les kits UI disponibles avec un abonnement Envato Elements:



Conclusion
Il existe des dizaines de façons différentes d'utiliser le sélecteur général de frères et sœurs qui est visuel, fonctionnel ou les deux. Il fournit un moyen puissant de personnaliser les composants sans avoir à utiliser plus que CSS et HTML. Nous avons couvert trois types différents d'éléments de formulaire dans ce tutoriel; dans le prochain, nous explorerons les menus et la navigation. N'hésitez pas à laisser un commentaire ci-dessous si vous avez des questions ou des commentaires!