5.9 KiB
Adding And Styling Forms
Styling form elements and handling user input with grace.
Adding The Unstyled Form
<main class="signup-page">
<h1 class="signup-title">Awesome! Let's dive right in!</h1>
<form action="index.html" class="signup-form">
<label for="title">Title</label>
<select id="title">
<option value="mr">Mr.</option>
<option value="ms">Ms.</option>
</select>
<label for="first-name">First name</label>
<input type="text" id="first-name">
<label for="last-name">Last name</label>
<input type="text" id="last-name">
<label for="email">E-Mail</label>
<input type="email" id="email">
<label for="password">Password</label>
<input type="password" id="password">
<input type="checkbox" id="agree-terms">
<label for="agree-terms">Agree to
<a href="#">Terms & Conditions</a>
</label>
<button type="submit" class="button">Sign Up</button>
</form>
</main>
Page Initialization
main {
padding-top: 1rem;
}
.signup-title {
text-align: center;
font-size: 1.8rem;
color: #ff5454;
}
.signup-form label,
.signup-form input,
.signup-form select {
display: block;
margin-top: 1rem;
width: 100%;
}
Understanding Advanced Attribute Selectors
We can select elements using attributes, e.g. [type], but what we can also do is be more specific and select elements with attribute type of value email, e.g. [type="email"].
Likewise we can also select elements with specific attribute value in like, e.g. [lang~="en-us"], means the lang attribute can have a list of values, and should contain the value en-us.
We can also select attributes with a prefix value, e.g. [lang|="en"] means elements with lang attribute starting with en OR en-.
| Element with Attributes | Element with Specific Attribute Value | Element with Specific Attribute Value in List | Element with Specific Attribute Value/Value- |
|---|---|---|---|
[type] { color: red; } |
[type="email"] { color: red; } |
[lang~="en-us"] { color: red; } |
[lang|="en"] { color: red; } |
<input type="text"> |
<input type="email"> |
<p lang="en-us en-gb">Hi!</p> |
<p lang="en-us">Hi!</p> |
We also can select attributes with a specific value prefix, e.g. [href^="#"] would select all elements with href attribute with value starting with a #.
We can also select attributes with value suffix, e.g. [href$=".de"] would select all elements with href attribute with value end with .de.
To select an element with attribute src that contains atleast one value cdn, we can use [src*="cdn"].
And finally, we can use i to make it case insensitive, e.g. [src*="cdn" i].
| Element with Specific Attribute Value Prefix | Element with Specific Attribute Value Suffix | Element with At Least One Attribute Value | Check Values Case-Insensitivity |
|---|---|---|---|
[href^="#"] { color: red; } |
[href$=".de"] { color: red; } |
[src*="cdn"] { color: red; } |
[src*="cdn" i] { color: red; } |
<input type="text"> |
<input type="email"> |
<p lang="en-us en-gb">Hi!</p> |
<p lang="en-us">Hi!</p> |
Working On The General Layout
Selecting the checkbox element using our knowledge about attribute selectors, checkbox element is an input element which has type="checkbox":
.signup-form input[type="checkbox"] {
...
}
And for our submit button:
.signup-form button[type="submit"] {
...
}
Restyling The Form Elements
.signup-form input,
.singup-form select {
border: 1px solid #ccc;
padding: 0.2rem 0.5rem;
font: inherit;
}
.signup-form input:focus,
.singup-form select:focus {
outline: none;
background: #d8f3df;
border-color: #2ddf5dc;
}
Styling The Checkbox
First of all we don't want the styles we defined previously using .signup-form input selector to be applied to our checkbox, to exclude checkbox we can use the not() sudo selector, which takes in a selector to exclude:
.singup-form input:not([type="checkbox"]),
.signup-form select {
...
}
.signup-form input:not([type="checkbox"]):focus,
.singup-form select:focus {
...
}
And now to style our checkbox:
.signup-form input[type="checkbox"] {
border: 1px solid #ccc;
background: white;
width: 1rem;
height: 1rem;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.signup-form input[type="checkbox"]:checked {
background: #2ddf5c;
border: #0e4f1f;
}
Providing Validation Feedback
A manual approach would be too mark a field as invalid, we can probably add a class to the element we want to mark invalid, lets name it invalid. And then we can add the styles for our invalid class:
.signup-form input.invalid,
.signup-form select.invalid {
border-color: red;
background: #faacac;
}
A more elegent approach is using the :invalid sudo selector, which the browser will add the input element automatically based on the type:
.signup-form input.invalid,
.signup-form select.invalid,
.signup-form :invalid {
border-color: red !important;
background: #faacac;
}
We can also add the required attribute to our HTML elements and they will appear red or invalid from the start.
There's also a :valid sudo selector, which as you can guess is opposite of :invalid.
Keep in mind that for a production website, we need javascript to add and remove classes for form validatoin etc, that we are not covering here.
Styling The Signup Button
To style a button element with disabled attribute, to give the user a clear feedback that the button is not clickable:
.button[disabled] {
cursor: not-allowed;
border: #a1a1a1;
background: #ccc;
color: #a1a1a1;
}