tutorials/css/the complete guide/11. adding_and_styling_form...

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 &amp; 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;
}