Skip to content

Add Progress bar guidance - #1386

Open
dvdherron wants to merge 2 commits into
mainfrom
1246-progress-guide
Open

Add Progress bar guidance#1386
dvdherron wants to merge 2 commits into
mainfrom
1246-progress-guide

Conversation

@dvdherron

Copy link
Copy Markdown
Contributor

Fixes #1246

Open to feedback on fleshing out the Fallbacks section. Should the fully custom approach to styling be considered a fallback? Also, feedback on some of the accessibility approaches here would be great.

@LeaVerou LeaVerou left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments for some more specific things. Bigger picture feedback is that the bulk of this guide is several large code examples, and it's not always clear what the agent is meant to extract from each of these.

In general, we try to avoid large code examples as they mix important bits with boilerplate, and thus can be wasteful in terms of tokens and less clear which bits are the actual guidance vs scaffolding. Instead, extract the meaningful guidance into short prose, and use (short!) code snippets for those things that are best explained in code (complementing the prose).


1. **Use the native `<progress>` element**: It provides built-in accessibility and platform-consistent behavior.
2. **Define the state**:
* **Determinate**: Set the `max` and `value` attributes. Note that `<progress>` does **not** support a `min` attribute; the minimum is always `0`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to set the max attribute if we're using the default 0-1 scale (though it may still be better for clarity).
I'm not sure we need to mention that it doesn't support a min, <progress> is old enough that this is known.

1. **Use the native `<progress>` element**: It provides built-in accessibility and platform-consistent behavior.
2. **Define the state**:
* **Determinate**: Set the `max` and `value` attributes. Note that `<progress>` does **not** support a `min` attribute; the minimum is always `0`.
* **Indeterminate**: Omit the `value` attribute for tasks of unknown duration to set the progress bar into an indeterminate state. You can also use the `:indeterminate` pseudo-class to explicitly put the progress bar in an indeterminate state.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The :indeterminate (or any other) pseudo-class cannot affect state, it just matches only when the progress bar is already in an indeterminate state.

2. **Define the state**:
* **Determinate**: Set the `max` and `value` attributes. Note that `<progress>` does **not** support a `min` attribute; the minimum is always `0`.
* **Indeterminate**: Omit the `value` attribute for tasks of unknown duration to set the progress bar into an indeterminate state. You can also use the `:indeterminate` pseudo-class to explicitly put the progress bar in an indeterminate state.
* **Mandatory:** If a progress bar needs to change from determinate to indeterminate, you must remove the value attribute (`element.removeAttribute('value')`);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is known.

* **Determinate**: Set the `max` and `value` attributes. Note that `<progress>` does **not** support a `min` attribute; the minimum is always `0`.
* **Indeterminate**: Omit the `value` attribute for tasks of unknown duration to set the progress bar into an indeterminate state. You can also use the `:indeterminate` pseudo-class to explicitly put the progress bar in an indeterminate state.
* **Mandatory:** If a progress bar needs to change from determinate to indeterminate, you must remove the value attribute (`element.removeAttribute('value')`);
3. **Standardize Styles**: Use `appearance: none` and `border: unset` to normalize the progress bar across different browsers before applying more customized styles.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why border: unset? I'd just set whatever border we need (or border: 0 if we don't need one). Reset styles makes sense more broadly, here we're only dealing with a single element, and we know how we want to style it.

* **Indeterminate**: Omit the `value` attribute for tasks of unknown duration to set the progress bar into an indeterminate state. You can also use the `:indeterminate` pseudo-class to explicitly put the progress bar in an indeterminate state.
* **Mandatory:** If a progress bar needs to change from determinate to indeterminate, you must remove the value attribute (`element.removeAttribute('value')`);
3. **Standardize Styles**: Use `appearance: none` and `border: unset` to normalize the progress bar across different browsers before applying more customized styles.
4. **Ensure Accessibility**:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Might want to make this a separate sub-section.

ping @knowler to review this too

4. **Ensure Accessibility**:
* **Associate a label**: Use `<label for="...">`, `aria-labelledby`, or `aria-label`.
* **Contextual state**: Use `aria-describedby` to reference the loading progress of a section of a page. Use `aria-busy="true"` on the container being updated. Set `aria-busy` to `"false"` when the task is complete.
* **Forced Announcements**: Set `tabindex="-1"` and call `.focus()` on the element in JavaScript when significant updates occur to force screen readers to announce the new progress.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to clarify that "the element" here means "the <progress> element".

<!-- Link to progress-ring and spinner for circular styling -->
# Build a Styled Progress Bar

The `<progress>` element is the semantic way to represent the completion progress of a task, like downloading or uploading information or completing part of a multi-step process. Using the native element helps with accessibility, as screen readers have an implicit `role="progressbar"` and can announce values.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once #1371 is merged, we should add GUIDE_REF references to them here. This is for a horizontal styled progress bar, whereas these are for a circular one.

## Best Practices

* **DO** use `<progress>` for task completion. Use the `<meter>` element for scalar measurements.
* **DO** use `accent-color` for simple branding and `color-scheme` for dark mode support.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this will stop working once we apply our own styles (with appearance: none). We can use accentcolor if supported to bring it back, but there's no web-feature for it currently. So this is more of an alternative path rather than complementary. Still worth mentioning though, but I'd move it to the intro, i.e. "if all you need is to customize the colors, you might want to just do that. This guide is for deeper customizations"

* **Mandatory:** **DO NOT** add a fallback value inside the `<progress>` element. It is not used by assistive technology and ignored by all modern browsers.
* **DO NOT** use `<progress>` for scroll position indicators; use scroll-driven animations instead.
* **DO** respect `prefers-reduced-motion` if you apply custom animations.
* **DO** ensure proper contrast between the progress bar and track when adden custom styles.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "adden"

Should we move the last two bullets to the a11y section?


color-scheme: light dark;
/* Set accent color for progress and other built-in UI elements */
accent-color: var(--brand-color, AccentColor); /* Use system accent color as a fallback */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note that AccentColor is not supported in every browser, and there is no web-feature id for it so we can't just use it.

(We can however detect support and apply it conditionally — or even extract that into a --default-accent-color variable)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create guide and evals for the progress use case

2 participants