html
<progress></progress>
<progress></progress>
<progress value="10" max="100"></progress>
Check out the documentation for the spinner.
If the <progress>
element is describing the loading progress of a section of a page:
aria-describedby
to point to the statusaria-busy="true"
on the section that is being updated, removing it when loading is finished.Source: MDN
<div aria-busy="true" aria-describedby="progress-bar">
Content here is loading.
</div>
<progress id="progress-bar" aria-label="Content loading…"></progress>
:where(progress) {
--_accent-color: var(--primary);
--_bg-color: var(--surface-tonal);
appearance: none;
background-color: var(--_bg-color);
border-radius: var(--border-radius, 0.25rem);
border: 0;
display: inline-block;
block-size: var(--size-1);
overflow: hidden;
position: relative;
vertical-align: baseline;
inline-size: 100%;
&::-webkit-progress-bar {
border-radius: var(--border-radius, 0.25rem);
background: none;
}
&[value]::-webkit-progress-value {
background-color: var(--_accent-color);
@media (prefers-reduced-motion: no-preference) {
transition: inline-size 0.2s var(--ease-out-4, cubic-bezier(0, 0, 0.1, 1));
}
}
&::-moz-progress-bar {
background-color: var(--_accent-color);
}
}
@media (prefers-reduced-motion: no-preference) {
progress:indeterminate {
background-color: var(--_bg-color);
&::after {
animation: indeterminate 2s linear infinite;
background-color: var(--_accent-color);
content: "";
inset: 0 auto 0 0;
position: absolute;
will-change: inset-inline-start, inset-inline-end;
}
&[value]::-webkit-progress-value {
background-color: transparent;
}
&::-moz-progress-bar {
background-color: transparent;
}
}
}
[dir="rtl"] {
:where(progress):indeterminate {
animation-direction: reverse;
}
}
[dir="rtl"] {
:where(progress):indeterminate::after {
animation-direction: reverse;
}
}
@keyframes indeterminate {
0% {
left: -200%;
right: 100%;
}
60% {
left: 107%;
right: -8%;
}
100% {
left: 107%;
right: -8%;
}
}