Votre navigateur ne supporte pas cette démonstration
Votre navigateur ne supporte pas les transitions discrètes mais cela n'empêche pas la démonstration de fonctionner.
<form>
<div class=cadre-input>
<label for="email">Email :</label>
<div class=input-form>
<svg></svg>
<input required type="email" id="email" title="Veuillez entrer une adresse valide" placeholder="Veuillez entrer une adresse valide">
</div>
<div class="erreur"><span>Veuillez entrer une adresse valide</span></div>
</div>
<div class=cadre-input>
<label for="password">Mot de passe :</label>
<div class=input-form>
<svg>...</svg>
<input required type="password" id="password" placeholder="Votre mot de passe" title="Votre mot de passe doit contenir au moins 8 caractères" pattern=".{8,}">
</div>
<div class="erreur"><span>Votre mot de passe doit contenir au moins 8 caractères</span></div>
</div>
<button type="submit">Se connecter</button>
</form>
*{box-sizing: border-box}
:root {
--rouge: oklch(48% .25 30);
--vert: oklch(51% 0.18 145.47);
--jaune: color-mix(in oklch,var(--vert),var(--blanc));
--vert-1: oklch(71% 0.1 145.47);
--gris: oklch(65% 0 0);
--blanc:oklch(1 0 0);
--texte: oklch(52% 0 0);
--transition: 0.25s;
}
form {
display: grid;
grid-template-columns: auto minmax(30ch,1fr);
max-width: 75ch;
margin: 20rem auto;
gap: 1rem;
overflow:hidden
}
.cadre-input {
--color: var(--texte);
grid-column: span 2;
display: grid;
gap: 1rem;
grid-template-columns: subgrid;
grid-template-rows: auto 3rem;
align-items: center;
}
form label {
display: flex;
font-weight: bold;
color: var(--color);
font-size: 1.125rem;
}
form input {
border: 2px solid var(--color);
border-radius: 4px;
height: 3rem;
padding-left:3.5rem;
font-weight: 400;
}
form input:is(:focus-within,:focus-visible){
outline:2px solid var(--color);
outline-offset: 2px
}
form input::placeholder {
color: transparent;
}
[type="submit"] {
place-self:center;
grid-column: span 2;
padding: 1rem 2rem;
border-radius: 4px;
border: 0;
cursor: pointer;
background:linear-gradient(to right,var(--step,var(--gris)) 50%,var(--gris) 50%);
font-weight: bold;
font-size: 1.125rem;
color: var(--color);
}
.input-form{
display: grid;
}
.input-form>*{
grid-area:1/1
}
.input-form svg{
border-radius: 4px;
margin-left:.5rem;
width:2.5rem;
height:2.5rem;
fill:var(--color);
z-index:1;
align-self:center
}
.cadre-input:has(:invalid) {
--color: var(--rouge);
}
.cadre-input:has(:focus) {
--color: var(--jaune);
}
.cadre-input:has(:valid) {
--color: var(--vert);
}
.cadre-input:has(:placeholder-shown) {
--color: var(--texte);
}
.erreur {
display: none;
translate:0 10px;
opacity:0;
white-space: nowrap;
font-size: 1rem;
grid-column:span 2;
}
.erreur span {
position: relative;
background-color: var(--rouge);
border-radius: 5px;
padding: 1rem;
color:var(--blanc);
text-align: center;
}
.erreur span::after {
content: "";
position: absolute;
top: -5px;
right: 10%;
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 5px solid var(--rouge);
}
.cadre-input:first-of-type:has(:valid) ~ [type="submit"]{
--step:var(--vert);
--gris:var(--vert-1)
}
.cadre-input:has(:valid) ~ .cadre-input:last-of-type:has(:valid) ~ [type="submit"] {
--gris:var(--vert);
color:var(--blanc)
}
.cadre-input:has(:invalid:not(:focus):not(:placeholder-shown)) .erreur {
display: block;
translate:0 0;
opacity:1;
}
@media (prefers-reduced-motion: no-preference) {
form input{transition: border-color var(--transition);}
form label{transition: color var(--transition);}
.cadre-input:has(:invalid:not(:focus):not(:placeholder-shown)) .erreur {
transition:opacity var(--transition), translate var(--transition), display var(--transition)
}
@starting-style {.cadre-input:has(:invalid:not(:focus):not(:placeholder-shown)) .erreur{
opacity:0;
translate:0 10px;
}
}
}