Overview of This Lesson

If you already know how to style things like block elements and tables, and you're familiar with responsive design, then you've already got a head start on styling forms. You can use most of the CSS properites you are already familiar with including Box Model properties, backgrounds, text formatting, etc.

There are some pseudo-classes that you can use specifically for forms. Using these pseudo-classes in yor selectors will allow you to add specific styling for input fields when they contain invalid values or when they have the focus. This tutorial focuses on these pseudo-classes.

Basic Form Styling

You can style your forms already using selectors and properties/values that you've already learned. For example:

In addtion to the styling mentioned above, you may wish to style specific types of form elements. This might seem a bit challenging: several different kinds of inputs use the <input> element: text fields, check boxes, radio buttons, and even buttons. How can you style specific types of <input> elements without cumbersome use of id selectors and class selectors? By using attribute selectors. If you are unfamiliar with attribute selectors, you should go through the Attribute Selectors tutorial.

The example below gives you an example of some form styling. It includes several techniques, including the use of attribute selectors. Feel free to fork/copy the CodePen and play with the styles.

See the Pen Form Styling Example by Wendi Jollymore (@ProfWendi) on CodePen.

Styling Form Validation

You've probably used forms on web pages that provide visual cues for form validation: for example, you might have seen an icon appear, or an input field's background or border changes colour when the input is invalid. This is done with special CSS pseudo-classes. You learned about pseudo classes in the Pseudo Classes tutorial.

The pseudo classes that will be helpful in providing visual feedback for form validation are:

When adding the required attribute to an input, you should also provide a text indicator that the field is required, such as an asterisk * or the value "(required)" inside the input's accessible <label>. This is outlined in WCAG Techniques G83 and H90. Additionally, some screen readers don't recognize the required attribute, so it's also a good practice to add the aria-required="true" attribute to any element that has required.

This codepen demonstrates how you might use the :required and :invalid pseudo classes, along with the WCAG techniques. Notice that it also implements G85 and H177 by providing information about what values are valid for the term number field via the element's title attribute (this meets SC 3.3.3). The value inside the title attribute will show in the browser (and also read out loud by a screen reader when the user attemps to submit the form.

See the Pen Form Validation: CSS by Wendi Jollymore (@ProfWendi) on CodePen.

Other Form Pseudo-Selectors

You already know how to style an element using the :hover pseudo class. This can allow you to create visually pleasing affects on buttons and other form controls.

Focusable Elements

In addtion, you might want to style an element when it has the focus: when the user tabs into/on an input field or clicked inside/on the control, this gives the element "the focus" An element that has the focus will be the recipient of any key-presses. For example, if a text field has the focus, any keys you press will cause the corresponding characters to appear int he field. If a checkbox or radio button has the focus, pressing the SPACE bar/key will toggle (select or unselect) the control. If a button has the focus, pressing ENTER will be equivalent to clicking the button with the mouse.

You can style an element when it has the focus by using the :focus or :focus-visible pseudo classes.

:focus is used to style the appearance of an element when it has the focus. An item recieves the focus when the user tabs into it or on it, or when the user clicks in or on the item. In the codepen example below, I styled elements to have a teal border and light background when they receive the focus:

See the Pen Styling Forms: Focus by Wendi Jollymore (@ProfWendi) on CodePen.

Try tabbing between elements, and also try clicking on each input element so you can see the focus indicators.

The :focus-visible pseudo class is also used to style the appearance of an element when it has the focus. The difference between :focus and :focus-visible is that :focus-visible styles apply only when the user needs to be informed that the element has the focus.

For example, when the user clicks on a button with a mouse or their finger, there is no need to indicate that the button has the focus. However, if the user tabs to the button, they need to know that they tabbed to the right control, so the button would need a focus indicator. :focus-visible will only style the button in the latter scenario (when the user tabs to the button).

Additionally, :focus-visible will keep the focus indicator on an item the user clicked in/on if there is "more to do". For example, clicking on a text field will show the focus indicator because there is still more to do: the user will be typing more keys to enter an input value into the field, so they need the focus indicator to stay visible so they know which field is being affected by the key presses. When clicking a button, there are no more actions to perform: once the button is clicked, that's the end of that action.

Here's the same CodePen as before, but using :focus-visible instead of :focus (also, in order to prevent form submission while you try out the example, I changed the submit button to a generic button, but the demo would still work in a real form with an actual submit button). Again, try tabbing vs clicking on the various elements to see the difference in behaviour. Notice how tabbing to each element shows the indicator, but clicking on the radio buttons or the submit (generic) button does not cause the focus indicator to appear. Clicking on the text fields does show the focus indicator because there are still keys to press while the field has the focus.

See the Pen Styling Forms: Focus Visible by Wendi Jollymore (@ProfWendi) on CodePen.

Accessibility of Focusable Elements

Note that there are some WCAG success criteria that affect the appearance of items that have the focus:

Sc 2.4.7 and SC 1.4.11

SC 1.4.11 (Non-text Contrast) and SC 2.4.7 (Focus Visible) state the miminum requirements for AA-level compliance on focused items.

SC 1.4.11

There are several specific details about focusable elements in the criteria's documentation. You can see in the two CodePen examples for :focus and :focus-visible that I used colours that met these constrast minimums.

SC 2.4.7

Techniques you can use to meet 2.4.7 include:

You can see in both the :focus and :focus-visible examples I used technqies G149, G195, and C15 by setting a thicker outline around the elements in a colour that contrasted the rest of the element and the surrounding colours.

SC 2.4.13

SC 2.4.13 (Focus Appearance) is a combination of SC 2.4.7 and 1.4.11 that was added to WCAG 2.2 that has stricter requirements to meet AAA-level compliance. To meet this criteria:

There are a couple of exceptions that are relevant if the developer didn't style the focus indicator or the element's background colour(they're using the browser defaults).

You can see in both the :focus and :focus-visible examples from earlier that I met this success criteria by setting a thicker outline of .2em (my base font was 20px) and in contrasting colours: my outline and foreground colour had a contrast ratio of 3.25:1 and the outline colour had a contrast ratio of 3.8:1 with the background of the <div> that contained the label/input.

Styling Active Elements

You can also style controls that are active: An active control is in the process of being clicked, so this generally only applies to links and buttons. This can be done by using the :active pseudo class. An example of how you might use :active to style a button is shown in the following demonstration:

See the Pen Styling Forms: active by Wendi Jollymore (@ProfWendi) on CodePen.

Styling Checked/Selected Items

You can style items when they're in the checked or selected state by using the :checked pseudo class. This allows you to add styling to checkboxes and radio buttons when they have been checked/selected, and to <option> elements of a <select> list when the <option> has been selected. The browser already has default styling for these states, but you can customize the appearance using the :checked pseudo class.

Here's a simple CodePen that shows an example of how you might style :checked elements:

See the Pen Styling Forms: checked by Wendi Jollymore (@ProfWendi) on CodePen.

Styling Placeholders

Placeholders are text contents that are often added to text input fields to add additional information about the required or expected inputs, or to provide a field label when there isn't enough screen real estate for an actual <label> element. For example:

<label for="fname">First Name:
  <input type="text" id="fname" name="firstname" 
  placeholder="first or given name">

You can use the :placeholder-shown pseudo class to style the appearance of an element when it contains placeholder textm and you can use the ::placeholder pseudo element to style the actual placeholder text. The CodePen below shows an example of styling both the :placeholder-shown and ::placeholder pseudo selectors:

See the Pen Form Styling: placeholder by Wendi Jollymore (@ProfWendi) on CodePen.