<progress> 요소는 정보 다운로드 또는 업로드, 다단계 프로세스의 일부 완료와 같은 작업의 완료 진행 상황을 나타내는 시맨틱 방식입니다. 스크린 리더에는 암시적 role="progressbar"가 있고 값을 읽을 수 있으므로 네이티브 요소를 사용하면 접근성에 도움이 됩니다.
이 가이드에서는 스타일 맞춤설정이 적용된 완전한 스타일의 가로 진행률 표시줄을 구현합니다.
진행률 표시줄 또는 달성률 링
- 공간이 제한되어 있거나 정사각형 가로세로 비율이 더 적합한 경우 원형 진행률 표시줄 (달성률 링)을 사용하는 것이 좋습니다. 달성률 링
- 대부분의 불확정 진행 상황 시나리오에서는 스피너를 사용하는 것이 좋습니다 (로딩 스피너). 불확정 상태가 일시적이고 곧 확정 진행률 표시줄로 대체될 경우 불확정 진행률 표시줄을 사용합니다 (예: 진행률 % 를 표시하기 전에 업로드 관련 메타데이터를 기다리는 경우).
마크업
- 네이티브
<progress>요소 사용: 기본 제공 접근성과 플랫폼 일관성 동작을 제공합니다. - 기본 0~1 배율과 다른 배율이 필요한 경우
max를 사용합니다. - 특정 진행률 값의 경우
value속성을 설정합니다. 불확정 상태 (예: 더 구체적인 피드백이 시작되기 전)에서는value를 생략합니다. <label for="...">,aria-labelledby또는aria-label를 사용하여 진행률 요소를 라벨과 연결합니다.
어떤 유형의 맞춤설정이 필요한가요?
제한된 스타일 지정의 경우 다음 속성으로 충분합니다.
accent-color: 진행률 표시줄의 색상 변경width/inline-size: 진행률 표시줄 너비 변경height/block-size가 일관되지 않게 적용됨 - 먼저 테스트하세요.writing-mode: vertical-lr: 세로 막대- 페인팅 후 적용되는 효과:
opacity,filter,clip-path, 마스크, 변환,box-shadow등
제한된 스타일 지정으로 충분하다면 다음 섹션을 건너뜁니다.
경고: 특정 속성 (예: border-radius, background, border)은 기본 진행률 표시줄 스타일 지정을 자동으로 사용 중지합니다. 위 속성 이외의 스타일 지정이 필요한 경우 다음 섹션에 설명된 대로 완전한 맞춤 스타일 지정을 구현해야 합니다. '혹시 모르니'라는 생각으로 더 광범위한 스타일을 적용하지 마세요.
완전한 맞춤 스타일 지정
1. 기본 설정
- 필수:
appearance: none를 사용하여 맞춤 스타일 지정을 사용 설정합니다. border: 0 solid를 사용하여 UA 경계 재설정- 활성 막대를 요소의 border-radius에 맞게 자르려면
overflow: clip를 사용하거나 막대에 동일한border-radius를 적용합니다. Shadow DOM의 특정 요소 구조에 따라 달라지는border-radius: inherit를 막대에 사용하지 마세요.
progress {
/* Reset default browser styles */
appearance: none;
border: 0 solid;
/* Clip bar to element’s border-radius */
overflow: clip;
}
2. 스타일 지정
progress요소 자체에서 트랙의 스타일을 지정합니다.- 적절한 브라우저 타겟팅 가상 요소를 사용하여 진행률 표시줄 자체를 타겟팅합니다. WebKit/Blink의 경우
::-webkit-progress-value, Firefox의 경우::-moz-progress-bar를 사용합니다. - 필수: 동일한 규칙에서
-webkit-및-moz-가상 요소를 그룹화하지 마세요. 규칙이 잘못된 것으로 간주되어 무시됩니다.:is()및:where()는 의사 요소를 지원하지 않으므로 여기서는 도움이 되지 않습니다. - 브라우저 타겟팅 가상 요소는 정확히 한 번만 표시되어야 합니다. 상태별 맞춤설정 (예: 불확정 세그먼트 크기 및 애니메이션)은
progress요소 자체에 설정된 맞춤 속성을 통해 라우팅해야 합니다. - 선택사항: 채우기에
inline-size을 전환하여 확정 값이 점프하는 대신 애니메이션으로 표시되도록 합니다. Firefox는 레이아웃의 채우기 크기를 조정하고 무시하므로 문제가 되지 않습니다.
progress {
--progress-bar-radius: 1e5px;
border-radius: var(--progress-bar-radius);
/* Apply color for custom progress track (background) */
background: var(--progress-bar-track, var(--color-neutral-90));
/* Subtle depth on the empty part of the track */
box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.1);
}
/* Let <progress> styling show through */
progress::-webkit-progress-bar {
background: transparent;
}
/* Webkit, Chrome */
progress::-webkit-progress-value {
background: var(--progress-bar-fill, var(--accent-color));
border-radius: var(--progress-bar-radius);
transition: inline-size 0.3s;
}
/* Firefox */
progress::-moz-progress-bar {
background: var(--progress-bar-fill, var(--accent-color));
border-radius: var(--progress-bar-radius);
transition: inline-size 0.3s;
}
3. 불확정 상태 스타일 지정
불확정 상태에 대한 맞춤 애니메이션 추가: 채우기 가상 요소를 짧은 세그먼트로 변환하고 트랙을 따라 슬라이드합니다.
- 채우기 자체의 스타일을 지정합니다.
progress에서 배경으로 다시 만들지 마세요. - 불확정 채우기는 애니메이션을 통해서만 존재합니다. 키프레임은 실제
inline-size로 길이를 설정하고(Chromium의 UA 인라인inline-size보다 우수함)translate로 이동합니다. 길이에scale를 사용하지 마세요. 채우기에 그려진 패턴이 왜곡됩니다. translate비율은 채우기의 자체 너비에 따라 결정되므로 대신 트랙 단위로 위치를 표현합니다.progress를 인라인 크기 컨테이너로 만들고 키프레임에서cqi를 사용합니다.from, to에margin-right: auto를 포함하여 Chromium이 RTL에서도 물리적 왼쪽에 채우기를 배치하도록 합니다.- 여백이 아닌 변환을 사용하여 채우기를 이동합니다.
- 변환은 애니메이션을 컴포지터에 유지합니다(
inline-size도 애니메이션화되지 않는 한). - RTL에서 여백이 깨지는 이유는 두 가지입니다.
- Firefox는 실제 왼쪽 여백만 사용하여 불확정 채우기를 배치하므로
margin-inline-start는 RTL에 영향을 미치지 않으며 채우기가 이동하지 않습니다. - 채우기를 일반 블록으로 배치하는 Chromium 및 WebKit에서는 여백이 채우기를 트랙 끝을 지나 밀어내면 여백이 트랙보다 더 많이 합산됩니다. 표준 CSS는 RTL에서
margin-left를 무시하여 이 문제를 해결하므로 세그먼트가 가장자리에서 미끄러지는 대신 가장자리로 이동합니다. translate는 레이아웃 후에 적용되므로 두 문제 모두 적용되지 않습니다.
- 변환은 애니메이션을 컴포지터에 유지합니다(
- Chrome의 기본 표시줄과 같이 RTL에서 모션을 미러링하려면
:dir(rtl)에서 애니메이션을 반전합니다.
progress:dir(rtl) {
--progress-bar-indeterminate-animation: progress-bar-indeterminate var(--progress-bar-indeterminate-animation-duration) infinite linear reverse;
}
- 소비자가
:indeterminate에 관해 알지 못해도 재정의할 수 있도록progress에서 공개--progress-bar-indeterminate-*속성을 정의합니다(이름이 이미 상태로 범위가 지정됨). - 세그먼트 길이를 변경하려면 (예: 앞쪽 가장자리가 앞서 나가고 뒤쪽 가장자리가 따라잡음)
--progress-bar-indeterminate-animation를 두 개의 동시 애니메이션으로 설정합니다. 하나는 키프레임이cqi(위치)에서translate에 애니메이션을 적용하고 다른 하나는 키프레임이inline-size(길이)에 애니메이션을 적용하여 각각 자체 키프레임과 이징을 갖습니다. 단일 키프레임 목록에서 두 가장자리를 모두 형성하려고 시도하지 마세요. 키프레임별animation-timing-function는 해당 키프레임의 모든 속성에 적용됩니다. --progress-bar-animation는 두 상태 모두에 적용되며, 확정된 반짝임과 같은 효과에 사용할 수 있습니다.revert-rule는 구성 가능성을 극대화하기 위해 설정된 경우에만 재정의하는 데 사용됩니다.- 불확정 애니메이션을 사용 중지하지 마세요. Chromium에서
animation: none은 너비가 0인 채우기를 남깁니다. 동작 줄이기의 경우 대신 속도를 늦춥니다.
progress {
/* Lets the fill position itself in track units (cqi) */
container-type: inline-size;
/* Segment length relative to the track */
--progress-bar-indeterminate-size: 30%;
--progress-bar-indeterminate-animation-duration: 1.5s;
/* Respect prefers-reduced-motion */
@media (prefers-reduced-motion: reduce) {
--progress-bar-indeterminate-animation-duration: 10s;
}
}
progress:indeterminate {
--progress-bar-animation: var(
--progress-bar-indeterminate-animation,
progress-bar-indeterminate var(--progress-bar-indeterminate-animation-duration) infinite linear
);
}
/* Add to the existing pseudo-element rules */
progress::-webkit-progress-value {
animation: var(--progress-bar-animation, revert-rule);
}
progress::-moz-progress-bar {
animation: var(--progress-bar-animation, revert-rule);
}
/* Physical: left to right regardless of direction (reverse under :dir(rtl) to mirror). */
@keyframes progress-bar-indeterminate {
from, to {
inline-size: var(--progress-bar-indeterminate-size);
/* Pin to the physical left; Chromium would otherwise lay the fill out at the inline start */
margin-right: auto;
}
from { translate: -100%; } /* Own width: fully outside the left edge */
to { translate: 100cqi; } /* Track width: fully outside the right edge */
}
추가 접근성 고려사항
위에 언급된 가이드라인 외에도 다음 사항을 준수해야 합니다.
- 포커스를 가로채지 않고 완료 알림:
<progress>에서tabindex를 설정하거나.focus()를 호출하지 마세요. 상호작용이 불가능하며 포커스를 이동하면 키보드 사용자가 방해를 받습니다. 백그라운드 작업이 완료되면 이를 알리기 위해 정중한 상태 요소 (role="status"또는aria-live="polite")를 업데이트합니다. <progress>내부에 대체 텍스트를 추가하지 마세요.<progress>내부의 텍스트는 최신 브라우저에서 무시되며 보조 기술에서 사용되지 않습니다.- 라벨이 지정되지 않은 일반
<div>에서aria-busy+aria-describedby를 사용하지 마세요.aria-busy에는 일관되지 않은 스크린 리더 지원이 있으며, 역할이 없는 이름이 지정되지 않은<div>의aria-describedby는 보조 기술에서 무시됩니다. 로드하는 동안 리전의 콘텐츠가 준비되지 않은 경우hidden또는aria-hidden="true"를 사용하여 숨깁니다. - 맞춤 스타일을 추가할 때는 진행률 표시줄과 트랙 간에 적절한 대비를 유지해야 합니다.
- 불확정 상태를 나타내는 대안 고려: 다른 콘텐츠와 함께 표시되는 불확정 진행률 표시줄 애니메이션은 일부 사용자에게 방해가 될 수 있습니다.
대체 전략
accent-color의 대체 및 브라우저 지원
accent-color 속성은 점진적 개선입니다.
이 속성을 지원하지 않는 브라우저는 이를 무시하고 기본 UI 색상을 사용합니다.
accent-color가 지원되지 않고 진행률 표시줄의 스타일을 지정해야 하는 경우 맞춤설정된 스타일 지정 메서드를 사용하여 진행률 표시줄에 원하는 스타일을 적용합니다.
revert-rule의 대체 및 브라우저 지원
revert-rule가 지원되지 않으면 animation: var(--progress-bar-animation, revert-rule)는 --progress-bar-animation가 설정되지 않은 경우 0s 기간으로 animation-name: revert-rule로 대체됩니다. 이는 @keyframes revert-rule가 없는 경우 무해한 무작업입니다.