Des labels flottants en CSS pur #CodingPartyAtHome đŸ’•đŸ€ŁđŸ€œđŸ€›đŸ˜Ž

Depuis que mon grand est en fac d'info, on a un nouveau sujet de conversation et j'ai ENFIN un interlocuteur dans le domaine Ă  la maison !

Du coup, il arrive le weekend avec les TP qu'il a eus pendant la semaine et me pose des questions sur les difficultés qu'il a.

En ce moment, il commence PHP et CSS/HTML...

On me   nomme ?

Du coup, aujourd'hui, il travaillait sur la page de login pour le projet final, une todolist en PHP+HTML+CSS sans JS.

Il voulait faire des labels flottants parce qu'il avait vu que c'était joli... Comme il découvre le monde merveilleux du frontend, on s'y est mis à deux et on a improvisé un petit cours.

Il a appris les subtilités du ciblage, les pseudo éléments, l'usage de :not() et :has()...

Car OUI  on a réussi des labels flottants en pur CSS.png

TLDR;

Pour la page de démo: c'est par là.

Pour le code : c'est sur snippetvamp.

Petit résumé du problÚme

En gros, on veut que le label soit dans l'input, comme un placeholder, lorsque il est vide mais que le label reprenne une place normale lorsque l'utilisateur clique dans l'input pour le remplir.

Capture du 2024-03-17 15-15-33.png Capture du 2024-03-17 15-15-57.png
Pour ça, j'ai créé un label contenant un span avec le texte et l'input correspondant:
<label><span>Username</span>
    <input type="text" name="login" value="" placeholder=" " >
</label>

Ensuite, je déplace le span vers l'intérieur de l'input:

label span{
    position: relative;
    top:2em;
    left:24px;
    transition:all 500ms;/* et on fait une transition douce, merci*/
}

Puis on utilise :has() pour cibler le span du label contenant un input ayant le focus.

label:has(input:focus) span
{
    color:grey;
    top:0;
    left:0;
    transition:all 500ms;
}

À ce stade, quand l'utilisateur clique dans l'input, le label glisse vers le haut pour sortir de l'input.

Toutefois, le problĂšme c'est que lorsque l'input perd le focus, le label revient Ă  l'intĂ©rieur mĂȘme si l'input a Ă©tĂ© complĂ©tĂ©... et les deux textes se chevauchent hideusement...

Et la,   c'est le drame

La logique voudrait qu'on cible alors le span du label contenant un input vide, genre avec input[value=""] ... sauf que ça ne marche pas car le fait de remplir un input ne modifie pas l'attribut value de la balise input...

Zut flute et   cacaboudin

Heureusement, on peut gruger...

Puisqu'on ne peut pas cibler un changement de l'attribut value, on peut cibler... le placeholder ! Enfin... styler en fonction de la visibilité du placeholder...

Ainsi, en utilisant :placeholder-shown, on peut ajouter une rÚgle de ciblage au CSS précédent:

label:has(input:focus) span,
label:has(input:not(:placeholder-shown)) span
{
    color:grey;
    top:0;
    left:0;
    transition:all 500ms;
}

Et là, les plus observateurs d'entre-vous - qui se demandaient avec une angoisse et un mépris non dissimulés pourquoi j'avais collé un placeholder=" " dans mon HTML - comprennent l'astuce: si le placeholder est visible, c'est que l'input est vide...

Et ça marche, tout est supporté dans la plupart des navigateurs. En plus, c'est léger, ne demande pas une structure HTML alambiquée ou des rÚgles CSS à la mords-moi le zboub...

Si ça peut servir, c'est cadeau

❝ 3 commentaires ❞

1  Captain Kaskouye le

Bonjour,


La page de démo ne marche pas sur mon Firefox 114 (LMDE 5 Elsie)
Le label reste dans l'input...

 
2  Bronco le

Rhaaa... c'est sûrement parce que c'est une version un peu ancienne de Firefox


je regarde sur caniuse et je vois que :has() ne fonctionne qu'Ă  partir de firefox 120...


 
3  Jerry Wham le

Bravo !
Et merci pour le partage

 

Fil RSS des commentaires de cet article

✍ Écrire un commentaire

les commentaires relevant du SPAM seront filtrés et dégagés direct...

Quelle est le quatriĂšme caractĂšre du mot tz96c ?