Progressive Disclosure with CSS

Recently we were lucky enough to read here at SiloCreativo a great article by Félix Ortega about UX entitled “Progressive Disclosure: Looking for the Simple in the Complex“with good real examples to better understand this technique of progressive disclosure and how to apply it to our work.

In web design we can find many points where applying this technique would mean an improvement in the User Experience, but perhaps the example that comes first are the forms, those points where the user acts directly with the application.

We have spoken several times about the forms and about what improvements we can apply to them (in Spanish). Today we are going to execute some actions of progressive disclosure in a form with the particularity that we are only going to apply CSS, nothing of JS nor libraries or frameworks, as we already did with the demo of the progress bar of the reading time.


Progressive Disclosure Form with CSS-only

For this demo we have opted for a very simple form, with three input fields (Name, Surname and email) and a textarea for the users to leave their comment. It could be a contact form for any website.

The application of progressive disclosure in this demo is something extreme, because we only show one field at a time, being necessary to properly complete it for the next field to be shown, but we can see the live performance.

Pseudo selectors : valid and :invalid to proceed to the next step

From the start, all the elements of the form will be hidden, except the first input (:first-of-type) By completing this input, we can use two pseudo selectors to define if the content is valid (:valid) and move to the next field or invalid (:invalid) to warn the user that the data entered are not correct (do not comply with the pattern or the length is not correct.) The validation of forms has almost complete compatibility.

In order to apply this correctly, we need all the fields to be mandatory, that is, they must have the required attribute in the html, otherwise all the fields will be valid without filling in any data and we will not be able to use the following CSS:

#form input:valid + label + input,
#form input:valid + label + textarea,
#form textarea:valid + label + input,
#form textarea:valid + label + textarea {
    display: block;

Indicator of steps and progress with label HTML

The HTML label is fundamental in a form. Each label is linked to an element of the form, for example to an input or textarea, indicating certain information relative to it. Although thanks to the placeholder attribute we can indicate in the input the information we need (Name, Surname, email …,)it is important that the label is present for screen readers.

Therefore, since we have this element at our disposal, we are going to use it to create a visual progress bar thanks to the CSS pseudo elements :after and :before. It would be cleaner to associate these pseudo elements to the inputs and textarea, but these HTML elements are not containers, so it is not possible to define them over them.

#form input:focus + label:after,
#form textarea:focus + label:after {
    content: "";
    width: 100%;
    height: 6px;
    background: linear-gradient(to right, #d8d8d8 0%,#d8d8d8 24%,transparent 24%,transparent 25%,#d8d8d8 25%,#d8d8d8 49%,transparent 49%,transparent 50%,#d8d8d8 50%, #d8d8d8 74%,transparent 74%,transparent 75%,#d8d8d8 75%,#d8d8d8 100%);
    display: block;
    margin: 0 auto;
This will show the progress bar, indicating the field on which we are working and if the data is correct or erroneous.

The progress bar will only be displayed on the field that we are filling in, hence we use the pseudo-class :focus to identify the input or textarea on which we are working. But it is important that the user knows where he is and how much time is needed to finish.

Squeezing HTML5 and CSS3 to improve UX

This is just a simple example of how we can improve our web applications using the tools we have available (HTML5 and CSS3) and without the need of bulky plugins or external libraries that increase the load time and end up playing against the user experience. We have already seen other similar cases with the zoom examples in images with CSS-only or the CSS animations of the hamburger icon.

Today’s example is a little extreme; four fields can be displayed perfectlyat the same time without the user feeling overwhelmed by so much information. It helps illustrate how to work progressive disclosure in a simple way with elements compatible with all browsers. I hope it will inspire you!

Comments (2)

  1. Pretty nice approach and GREAT solution to solve it with pure CSS.
    Few months ago did something similar but with the help of javascript – wish new this earlier – indeed will keep in mind for the future.

    The use case for this of approach is to use it on mobile if you have to make a form that is always visible (pinned at the bottom) while the user is scrolling the content – it’s a non-intrusive solution to maintain balance.

    1. Hi Andrea,
      thank you for your words.

      Yes, that is a good idea. I had thought about having the form inside a widget in a sidebar, so the content is still visible and the height of the sidebar is growing without altering the main content. But your solution is great because it can work like a call to action or so, showing only the first input at the bottom of the screen.

Leave a Reply

Your email address will not be published. Required fields are marked *