<form id="demo-form">
<div class="form-feedback error">
Something terribly went wrong :(
</div>
<div class="form-group">
<fieldset>
<label for="#form-field">Username</label>
<input type="text" placeholder="Enter a lowercase username" id="form-field" name="form-field" pattern="[a-z]{1,15}" title="Username should only contain lowercase letters. e.g. jane" required />
<div class="feedback">Username should only contain lowercase letters</div>
</fieldset>
<button type="submit">Send</button>
</div>
<div class="form-feedback sent">
You did it!
</div>
</form>
:root {
--input-border-color: #a13d63;
}
.feedback {
margin-block-start: 5px;
font-size: 0.9rem;
line-height: 1.4;
color: red;
opacity: 0;
transition: opacity 0.4s ease;
}
fieldset:has(:invalid) .feedback {
opacity: 1;
}
fieldset:has(:placeholder-shown) .feedback {
opacity: 0;
}
input:invalid {
--input-border-color: red;
}
input:placeholder-shown {
--input-border-color: #a13d63;
}
/* Generic styling */
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
display: flex;
align-items: center;
justify-content: center;
margin: 0;
padding: 24px 16px;
font-family: "Figtree", sans-serif;
font-size: 1.2rem;
line-height: 1.6rem;
background-image: radial-gradient(circle, #a13d63, #351e29);
min-height: 100vh;
}
fieldset {
border: none;
padding: 0;
}
form {
background: rgba(255, 255, 255, 0.9);
padding: 16px;
width: 100%;
max-width: 500px;
border-radius: 14px;
box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 2px, rgba(0, 0, 0, 0.07) 0px 2px 4px,
rgba(0, 0, 0, 0.07) 0px 4px 8px, rgba(0, 0, 0, 0.07) 0px 8px 16px,
rgba(0, 0, 0, 0.07) 0px 16px 32px, rgba(0, 0, 0, 0.07) 0px 32px 64px;
}
.form-group {
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
}
label {
display: block;
font-weight: 600;
font-size: 1rem;
text-transform: uppercase;
}
input {
width: 100%;
padding: 12px 16px;
border-radius: 7px;
font-size: 1.2rem;
border: 2px solid var(--input-border-color);
background: #fafafa;
box-shadow: rgba(0, 0, 0, 0.08) 0px 3px 5px;
transition: all 0.3s ease;
}
input:focus {
background: #fff;
border-color: #351e29;
box-shadow: inset rgba(0, 0, 0, 0.2) 0px 3px 5px;
outline: 0;
}
button {
width: 100px;
padding: 14px 20px;
font-family: "Figtree", sans-serif;
font-size: 1rem;
font-weight: 600;
text-transform: uppercase;
color: #fff;
border: none;
border-radius: 50%;
background: #a13d63;
transition: background 0.5s ease;
cursor: pointer;
aspect-ratio: 1;
box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px,
rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;
}
button:hover,
button:focus {
background: #c64a7a;
}
button:active {
background: #c64a7a;
box-shadow: inset rgba(0, 0, 0, 0.2) 0px 3px 5px;
}
.form-feedback {
display: none;
}
form.success .sent {
display: block;
color: green;
text-align: center;
padding: 16px;
border: 3px solid green;
font-weight: 600;
}
form.success button {
display: none;
}
/* this should not occur */
form.fail .error {
display: block;
color: red;
text-align: red;
padding: 16px;
border: 3px solid red;
}
@media screen and (min-width: 500px) {
form {
padding: 50px;
}
.form-group {
display: flex;
flex-direction: row;
align-items: center;
gap: 16px;
}
button {
margin-block-start: -18px;
}
}
const form = document.forms[0];
form.addEventListener('submit', (elem) => {
event.preventDefault();
const invalidList = form.querySelectorAll(':invalid');
if (invalidList.length === 0) {
form.classList.add('success');
} else {
form.classList.add('fail');
}
});
This Pen doesn't use any external JavaScript resources.