Progress Bar Expressive Component
The expressive progress bar can replace our traditional spinner to feel faster during periods of longer loading. To portray responsive and quicker loads, the expressive loader's design uses visual momentum to indicate progression across refreshing, page loading and user actions.
This pattern consists of an animated progress bar in various colors and an optional set of messages that are cycled into view. These messages render in an element with role="status" , which announces new content to assistive technology. The live examples that follow use aria-live="off" to prevent the status element from proactively announcing new content. This is only for demo purposes, so that this documentation page does not overwhelm the viewer with example status updates. The aria-live override should not be included in implementations of this pattern.
Default Expressive Progress Bar
The base expressive loader consists of a progressbar with 12 lines of varying widths. Each line has a width of 10% - 40% of its container, with each set of four lines adding up to 100% width. You can use JavaScript to randomly generate the line widths, though it's not required.
In the default behavior, lines scale up from 0% to their defined width and move horizontally across the screen. When the user prefers reduced motion, the lines still animate. However, instead of growing from 0% to their defined width, they stay a fixed size and scroll more slowly across the screen.
<div class="progress-bar-expressive">
<div
role="progressbar"
aria-label="Loading..."
class="progress-bar-expressive__progress"
>
<div class="progress-bar-expressive__lines">
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
</div>
</div>
</div>
Expressive Progress Bar with Single Message
If there is only one message, add the progress-bar-expressive__message--in class to its status element to animate it in.
<div class="progress-bar-expressive">
<div class="progress-bar-expressive__messages">
<div
role="status"
id="progress-bar-expressive-message-3"
class="progress-bar-expressive__message progress-bar-expressive__message--in"
>
Hang tight.
</div>
</div>
<div
role="progressbar"
aria-label="Loading..."
aria-describedby="progress-bar-expressive-message-3"
class="progress-bar-expressive__progress"
>
<div class="progress-bar-expressive__lines">
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
</div>
</div>
</div>
Expressive Progress Bar with Multiple Messages
The following examples demonstrate cycling through messages using JavaScript. Note that JavaScript is not bundled with Skin, so you will need to write your own js implementation of this pattern. We have outlined the steps below so you can recreate them in your JavaScript framework of choice.
Default behavior
To cycle a message into view in the default mode:
- Animate in the message:
- Put the message content in the aria-hidden element with class
progress-bar-expressive__message. This element is used just for the visual message animation; it is not read to screen readers. - Add the
progress-bar-expressive__message--inclass to animate that message into view.
- Put the message content in the aria-hidden element with class
- After the message animates in:
- Put the message content in the status element with class
progress-bar-expressive__message. This will read the message aloud to screen reader users. - Remove the
progress-bar-expressive__message--inclass from the aria-hidden element.
- Put the message content in the status element with class
- After a fixed amount of time, add the
expressive_loader__message--outclass to the current message to animate it out of view. This can happen concurrently with the next message animating in.
Reduced motion behavior
When @media (prefers-reduced-motion: reduce) , there is no transition state between messages, so the aria-hidden message is not needed. To fade in the first message, add the progress-bar-expressive__message--initial class to the status element. For all subsequent messages, remove the progress-bar-expressive__message--initial class and simply update the content in the status element.
<div class="progress-bar-expressive">
<div class="progress-bar-expressive__messages">
<div aria-hidden="true" class="progress-bar-expressive__message">
We're finishing your order.
</div>
<div
role="status"
id="progress-bar-expressive-message-2"
class="progress-bar-expressive__message"
>
Hang tight.
</div>
</div>
<div
role="progressbar"
aria-label="Loading..."
aria-describedby="progress-bar-expressive-message-2"
class="progress-bar-expressive__progress"
>
<div class="progress-bar-expressive__lines">
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
</div>
</div>
</div>
Medium text
By default, the expressive progress bar displays with large text. For smaller text, apply the progress-bar-expressive--medium class to the message container.
<div class="progress-bar-expressive progress-bar-expressive-messages-example">
<div
class="progress-bar-expressive__messages progress-bar-expressive__messages--medium"
>
<div aria-hidden="true" class="progress-bar-expressive__message">
We're finishing your order.
</div>
<div
role="status"
id="progress-bar-expressive-message-5"
class="progress-bar-expressive__message"
>
Hang tight.
</div>
</div>
<div
role="progressbar"
aria-label="Loading..."
aria-describedby="progress-bar-expressive-message-5"
class="progress-bar-expressive__progress"
>
<div class="progress-bar-expressive__lines">
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
<div class="progress-bar-expressive__line" />
</div>
</div>
</div>