Jan 28, 2022 · 7 min read

State and <main>

Providing feedback to the user action: a tour of the different UI component states.

An important part of a UI designer job when designing interfaces it's providing feedback to the users about the status of the components, to have a clear understanding about when they're over an element, when a link was already visited, when something is loading or when the information they just filled in the input is correct.

Meme of Vince McMahon reaction about providing feedback to teammates, boss and users.

Fig. 1 - Providing feedback to your users.

So, what is a state?The Accessible Rich Internet Applications (WAI-ARIA) 1.2describes it as:"A state is a dynamic property expressing characteristics of an object that may change in response to user action or automated processes."

I'll try to cover some of the most common states a designer should think about...

User action pseudo-classes

Examples of a button styles when enabled, hovered, focused and active

Fig. 2 - Enabled, hover, focus and active button states.

The CSS user action pseudo-classes apply when the user interacts with some element:

  • :hoverThe element is being pointed by the cursor. Only works on desktop.

  • :focusThe user clicks or taps on an element or selects it with the keyboard's Tab key.

  • :activeThe user press down the element.

  • :visitedRepresents links that have been already visited.

It's important to style all these states differently. Usually, the most subtle style changes can be applied to the :hover state, since it's easier for the user to know when they hovered over something, the :focus state change instead, needs to have more visibility since the user don't know beforehand where the next element in the tab sequence is located.

Design tip

It's possible to hide the focus styles when the user clicks or taps an element and show it only when the interaction is being made via keyboard with the :focus-within pseudo-class.

In addition, in an <input> or <textarea> components the placeholder text is displayed before the user enters a value and should be visually different. The CSS ::placeholder pseudo-class can be used to style the element state.

Disabled and read-only

Fig. 3 - Enabled versus disabled and read-only states.

These states communicate to the user that there are restrictions in the interaction with the UI element:

  • Disabled: This component is not available for interaction, it can't receive focus.

  • Readonly: The user cannot modify the value of the control, but is still focusable.

Only some of the UI components can have a readonly state, <input> and<textarea>(although maybe others should), where some relevant information to the user needs to be shown, but cannot be modified. Communicate visually when the element has some restrictions, but still allows interaction, and also when doesn't allow it.

Accessibility tip

The WCAG 2.1 Success Criterion 1.4.3: Contrast (Minimum) says that "Text or images of text that are part of an inactive user interface component, that are pure decoration, that are not visible to anyone, or that are part of a picture that contains significant other visual content, have no contrast requirement."In other words: A disabled element doesn't have a contrast requirement.

Contextual states

Fig. 4 - Error and success states.

These states show the user what's occurring in the user context. In this article, I will cover its application mainly in form inputs.

  • Error: Show the user that what they just entered is invalid.

  • Success: Show the user that what they just entered is valid.

Be careful not to design these states in such a way that they hide others (e.g. use theborder-color to represent both error and :focus states, and when the element is focused on, the reference that the field had an error is lost)

Usability tip

Show only the error state in a component when the focus is moved to another element. Having said that, there are some cases when can be interesting to show it when the user is still interacting with the component (e.g. Exceeding the character limit in an input or textarea). Above all, it is important to avoid those cases that can cause the error to be displayed as soon as the user interacts with the field, without having entered a value yet. I'm watching you 👀

Although I listed here only error and success states, warning, info or any other contextual state needed to provide feedback to the users should be designed in a way that is understandable and scalable across components or applications.

Dragged elements and drop areas

Fig. 5 - Enabled, drag and dragover states.

These states provide feedback of an ongoing drag operation, from when an element is being dragged to when a zone is available to drop that element.

  • Dragged: This element is being pressed and dragged.

  • Dragover: Indicate that the element is a valid drop target.

According to the MDN documentation, the dragged state usually is "A translucent representation of the draggable elements" and it's a common pattern used to represent this element state. Another distinction that can be used is a drop shadow to represent the change in the z-axis position of the element when placed with other visually equal siblings.

Accessibility tip

Although aria-dropeffect andaria-grabbed are deprecated since ARIA 1.1, they remain in the spec and can be used since there are accessibility concerns related to the HTML Drag and Drop API.

Checked and unchecked / Selected and unselected

Fig. 6 - Selected and unselected states in an option list.

These states are engaged by checking/selecting or unchecking/deselecting an element, and they apply to checkboxes, radio buttons, and select options (among others).

  • Checked / Selected: The element has been checked or selected (by default or by the user) or all his children have been.

  • Unchecked / Unselected: The element has not been checked / selected.

  • Indeterminate: The indeterminate state indicates that the checkbox contains a sublist of selections and not all of them have been checked or unchecked.

Other elements where selected / unselected states can apply are: sidenav links, tabs, toggles

Design tip

Different states can be applied to an element at the same time (e.g. a checkbox can be selected | unselected | indeterminate, hovered | focused | active and have an error). Try to define all the possibilities beforehand when designing the component interaction.


Fig. 7 - Current state in a breadcrumbs component.

Do not confuse this state with the CSS :currentpseudo-class. The current state applies in a group of related elements, such as several links in a breadcrumb, steps in a multi-step flow, or the current date in a date-picker or time-picker.

  • Current: indicate that this is the current element within its group.

The line between current and selected can be sometimes blurred, in multiple cases those states will overlap and onlyone visual definition needs to be made (e.g. a navigation link in a tree: the user interacted selecting it at the same time is showing the current page).

Accessibility tip

Use the aria-current state to indicate the current item in a set of related elements.

WAI-ARIA 1.2 - aria-current state


Fig. 8 - Loading state in a file item.

Multiple components can have loading states: buttons, modal dialogs, autocomplete or select dialogs, file items, etc...

  • Loading: Indicate that the element is loading (I know...too obvious)

Design tip

Design a loading indicator component with different sizes so you can reuse it across multiple scenarios: the entire screen, a portion of it, or inside a component.


  • Cover every state needed to provide information about the component status.

  • When a component has multiple states at the same time (e.g. focused and error) make sure that both are visible and understandable.

  • Selected elements should be clearly visible, avoid using subtle changes in the background color or font-weight.

  • Disabled states don't need to be readable, don't use them if the information is necessary for understanding the context, use readonly instead.

“Only second chance I know, is the chance to make the same mistake twice.”

Bob Barrenger (Alec Baldwin) - State and main

Me writing the second article of the year ☝️.Imposter syndrome intensifies.

Sending my ❤️ to @emilianos for the amazing Mac cursor set!