로드 표시줄 구성요소 빌드

<progress> 요소를 사용하여 색상 적응형 및 액세스 가능한 로드 바를 빌드하는 방법에 관한 기본 개요입니다.

이 게시물에서는 색상 적응력을 구축하고 <progress> 요소로 액세스할 수 있는 로드 바 사용해 보기: 데모를 살펴보고 출처!

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph> 밝은/어두움, 확정되지 않음, 증가, 완료가 Chrome에서 시연되었습니다.

동영상을 선호한다면 이 게시물의 YouTube 버전을 참고하세요.

개요

<progress> 드림 요소는 완료에 대해 사용자에게 시각적 및 청각적 피드백을 제공합니다. 이 시각적 피드백은 양식을 통한 진행 상황, 다운로드 또는 업로드 정보를 표시하거나 심지어 진행률은 알 수 없지만 작업이 아직 활성 상태입니다.

GUI 챌린지는 기존 HTML <progress> 요소를 사용하여 접근성을 위한 노력을 절약할 수 있습니다. 이 기본 제공되는 요소에 대한 맞춤설정의 한계를 뛰어넘어 구성요소를 현대화하고 설계 시스템에 더 적합하게 만들 수 있습니다

<ph type="x-smartling-placeholder">
</ph> 각 브라우저의 밝은 탭과 어두운 탭을 제공하여 
    적응형 아이콘의 개요를 위에서 아래로: 
    Safari, Firefox, Chrome 등이죠. <ph type="x-smartling-placeholder">
</ph> Firefox, Safari, iOS Safari Chrome 및 Android Chrome(밝은 색과 어두운 색 구성표)

마크업

<progress> 요소를 <label>만큼 명시적 관계 속성은 암시적인 관계 속성을 관계를 지양합니다. 또한 로드 상태의 영향을 받는 상위 요소에 라벨을 지정했으므로 리더 기술은 해당 정보를 사용자에게 다시 전달할 수 있습니다.

<progress></progress>

value가 없으면 요소의 진행률은 미확정 max 속성의 기본값은 1이므로 진행률은 0에서 1 사이입니다. max 설정 예를 들어 100으로 설정하면 범위가 0~100으로 설정됩니다. 0에 머무르기로 했습니다. 및 1 한도를 지정하여 진행률 값을 0.5 또는 50%로 변환합니다.

라벨 래핑 진행률

암시적 관계에서 진행률 요소는 다음과 같이 라벨로 래핑됩니다.

<label>Loading progress<progress></progress></label>

이 데모에서는 스크린 리더 라벨을 포함하도록 선택했습니다. 만 해당을 선택합니다. 라벨 텍스트를 <span>에 래핑하고 몇 가지 스타일을 적용하면 됩니다. 실질적으로 화면에서 벗어나게 합니다.

<label>
  <span class="sr-only">Loading progress</span>
  <progress></progress>
</label>

WebAIM의 다음과 같은 CSS를 함께 사용합니다.

.sr-only {
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px;
  width: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
}

화면 준비 전용 요소를 표시하는 devtools의 스크린샷

로드 진행률의 영향을 받는 영역

시력이 정상이라면 진행률 지표를 연관 짓기 쉬울 수 있습니다 관련 요소와 페이지 영역을 포함하지만 시각 장애가 있는 사용자의 경우 아주 명확하죠. 이를 개선하려면 aria-busy 드림 속성의 값을 변경할 수 있습니다. 또한 진행률과 로드 영역 간의 관계를 나타냅니다. 다음 코드로 교체합니다. aria-describedby

<main id="loading-zone" aria-busy="true">
  …
  <progress aria-describedby="loading-zone"></progress>
</main>

JavaScript에서 작업 시작 시 aria-busytrue로 전환하고 완료되면 false입니다.

ARIA 속성 추가

<progress> 요소의 암시적 역할은 progressbar, 음란물을 표시했습니다. 를 사용해야 합니다. 또한 이 속성은 indeterminate는 요소를 알 수 없는 상태로 명시적으로 전환합니다. 더 명확해집니다.value

<label>
  Loading 
  <progress 
    indeterminate 
    role="progressbar" 
    aria-describedby="loading-zone"
    tabindex="-1"
  >unknown</progress>
</label>

사용 tabindex="-1" 드림 을 사용하여 JavaScript에서 진행률 요소를 포커스 가능하게 만들 수 있습니다. 이는 진행이 변화함에 따라 진행률 포커스를 주기 때문에 업데이트된 진행률이 사용자에게 표시됩니다.

스타일

진행률 요소는 스타일 지정에 다소 까다롭습니다. 기본 제공 HTML 요소에는 선택하기 어렵고 종종 제한된 속성 집합만 설정할 수 있기 때문입니다.

레이아웃

레이아웃 스타일은 진행 과정에서 약간의 유연성을 허용하기 위한 것입니다. 요소의 크기와 라벨 위치를 변경합니다. 특수 완료 상태가 추가되어 유용한 추가 시각적 신호여야 합니다(필수는 아님).

<progress> 레이아웃

진행률 요소의 너비는 그대로 유지되어 축소되고 커질 수 있습니다. 디자인에 필요한 공간을 확보할 수 있습니다 내장 스타일은 appearancebordernone로 설정합니다. 이렇게 하면 요소가 각 브라우저에 고유의 스타일이 있기 때문에 요소가 포함됩니다.

progress {
  --_track-size: min(10px, 1ex);
  --_radius: 1e3px;

  /*  reset  */
  appearance: none;
  border: none;

  position: relative;
  height: var(--_track-size);
  border-radius: var(--_radius);
  overflow: hidden;
}

_radius1e3px 값은 과학수를 사용합니다. 표기법을 사용하여 큰 숫자여야 하므로 border-radius가 항상 반올림됩니다. 다음과 동일합니다. 1000px 나는 이 옵션을 사용하는 것이 좋으며, 설정하고 잊어버릴 수 있습니다 (1000px보다 작성하는 것이 짧습니다). 또한 필요한 경우 더 크게 만들 수 있습니다. 3을 4로 변경하면 1e4px10000px와 같습니다.

overflow: hidden은 논쟁의 여지가 있는 스타일로 사용되었습니다. 이를 통해 border-radius 값을 트랙 및 '채움 요소 추적'을 적용할 수 있습니다. 어떤 하위 요소도 요소 외부에 있을 수 있습니다. 이 맞춤 진행률의 또 다른 반복 요소는 overflow: hidden 없이도 수행할 수 있으며 일부 더 나은 완료 상태를 제공할 수 있습니다.

진행 완료

CSS 선택자는 최댓값과 값을 비교하여 어려운 작업을 하며, 두 선택자가 일치하면 진행이 완료됩니다. 완료되면 의사 요소가 생성되고 진행률 요소의 끝에 추가되어 완료에 멋진 추가 시각적 신호가 제공됩니다.

progress:not([max])[value="1"]::before,
progress[max="100"][value="100"]::before {
  content: "";
  
  position: absolute;
  inset-block: 0;
  inset-inline: auto 0;
  display: flex;
  align-items: center;
  padding-inline-end: max(calc(var(--_track-size) / 4), 3px);

  color: white;
  font-size: calc(var(--_track-size) / 1.25);
}
드림

로드 표시줄이 100% 이며 끝에 체크표시가 표시된 스크린샷

색상

브라우저는 진행률 요소에 자체 색상을 가져오며 한 개의 CSS 속성만 사용하여 밝게 또는 어둡게 만들 수 있습니다. 이를 기반으로 구축될 수 있는 사용할 수 있습니다.

밝은 브라우저 스타일 및 어두운 브라우저 스타일

사이트를 어둡고 밝은 적응형 <progress> 요소로 선택하려면 다음 단계를 따르세요. color-scheme만 있으면 됩니다.

progress {
  color-scheme: light dark;
}

단일 속성 진행률 음영 색상

<progress> 요소에 색조를 적용하려면 accent-color를 사용합니다.

progress {
  accent-color: rebeccapurple;
}

트랙 배경 색상이 밝은색에서 어두운 색상으로 변경되는 것을 볼 수 있습니다. accent-color 브라우저가 적절한 대비를 유지합니다. 아주 깔끔하게 표시됩니다.

완전히 맞춤 밝은 색상 및 어두운 색상

<progress> 요소에서 두 개의 맞춤 속성(하나는 트랙 색상용)을 설정합니다. 다른 하나는 트랙 진행률 색상입니다. 내부 prefers-color-scheme 드림 미디어 쿼리의 경우 트랙에 대한 새 색상 값을 제공하고 진행률을 추적합니다.

progress {
  --_track: hsl(228 100% 90%);
  --_progress: hsl(228 100% 50%);
}

@media (prefers-color-scheme: dark) {
  progress {
    --_track: hsl(228 20% 30%);
    --_progress: hsl(228 100% 75%);
  }
}
드림

초점 스타일

앞서 프로그래매틱 방식으로 작동할 수 있도록 요소에 제외 탭 색인을 제공했습니다. 초점을 맞추고 있습니다. 사용 :focus-visible(으)로 포커스를 사용자 지정하여 더 스마트한 초점 링 스타일을 선택할 수 있습니다. 이렇게 하면 마우스가 클릭 및 포커스를 클릭해도 포커스 링이 표시되지 않지만 키보드 클릭은 표시됩니다. 이 YouTube 동영상에서 더 자세히 살펴보고 검토해 볼 가치가 있습니다

progress:focus-visible {
  outline-color: var(--_progress);
  outline-offset: 5px;
}

주변에 포커스 링이 있는 로드 표시줄의 스크린샷 색상이 모두 일치합니다.

브라우저별 맞춤 스타일

<progress> 요소에서 각각이 지정된 부분을 선택하여 스타일을 맞춤설정합니다. 영향을 주지 않습니다. 진행률 요소를 사용하는 것은 단일 태그이지만 CSS 의사 선택기를 통해 노출되는 하위 요소가 거의 없습니다. Chrome DevTools 설정을 사용 설정하면 다음 요소가 표시됩니다.

  1. 페이지를 마우스 오른쪽 버튼으로 클릭하고 Inspect Element를 선택하여 DevTools를 표시합니다.
  2. DevTools 창 오른쪽 상단에 있는 설정 톱니바퀴 아이콘을 클릭합니다.
  3. Elements 제목 아래에서 사용자 에이전트 그림자 표시 DOM 체크박스를 선택합니다.

DevTools에서 사용자 에이전트 Shadow DOM을 노출할 수 있는 위치의 스크린샷

Safari 및 Chromium 스타일

Safari 및 Chromium과 같은 WebKit 기반 브라우저는 ::-webkit-progress-bar::-webkit-progress-value는 사용할 CSS입니다. 지금은 커스텀 속성을 사용하여 background-color를 설정합니다. 빛과 어두움에 맞춰 조정됩니다.

/*  Safari/Chromium  */
progress[value]::-webkit-progress-bar {
  background-color: var(--_track);
}

progress[value]::-webkit-progress-value {
  background-color: var(--_progress);
}

진행률 요소의 내부 요소를 보여주는 스크린샷

Firefox 스타일

Firefox는 ::-moz-progress-bar 의사 선택기만 <progress> 요소 즉, 트랙의 색조를 직접 조정할 수도 없습니다.

/*  Firefox  */
progress[value]::-moz-progress-bar {
  background-color: var(--_progress);
}

Firefox 스크린샷 및 진행률 요소 부분을 찾을 수 있는 위치

Safari, iOS Safari 
  Firefox, Chrome, Android용 Chrome에서는 모두 로드 표시줄이 작동하는 것으로 표시됩니다.

Firefox의 트랙 색상은 accent-color에서 설정된 반면 iOS Safari는 하늘색 트랙이 있습니다. 이것은 어두운 모드에서도 동일합니다. Firefox에는 어두운 트랙이 있지만 설정된 맞춤 색상이 아니며 Webkit 기반 브라우저에서 작동합니다.

애니메이션

브라우저에 내장된 의사 선택기로 작업할 때 허용된 CSS 속성 집합입니다.

트랙이 채워지는 애니메이션

전환을 추가하여 inline-size/ 진행률 요소는 Chromium에서는 작동하지만 Safari에서는 작동하지 않습니다. Firefox도 ::-moz-progress-bar에서 전환 속성을 사용하지 않습니다.

/*  Chromium Only 😢  */
progress[value]::-webkit-progress-value {
  background-color: var(--_progress);
  transition: inline-size .25s ease-out;
}

:indeterminate 상태 애니메이션

여기서는 애니메이션을 제공할 수 있도록 좀 더 창의적인 것을 얻었습니다. 의사 요소 Chromium이 생성되고 그라데이션이 적용되어 뒤로 애니메이션이 적용된 3개 브라우저 모두에서 지원됩니다.

맞춤 속성

커스텀 속성은 많은 경우에 유용하지만 개인적으로 가장 좋아하는 것 중 하나는 마법처럼 보이는 CSS 값에 이름을 지정합니다. 다음 동영상은 복잡함 linear-gradient님, 멋진 이름을 붙이고 있어요. 그 목적과 사용 사례를 명확하게 이해할 수 있습니다.

progress {
  --_indeterminate-track: linear-gradient(to right,
    var(--_track) 45%,
    var(--_progress) 0%,
    var(--_progress) 55%,
    var(--_track) 0%
  );
  --_indeterminate-track-size: 225% 100%;
  --_indeterminate-track-animation: progress-loading 2s infinite ease;
}

맞춤 속성은 코드가 DRY를 유지하는 데에도 도움이 됩니다. 다시 한번 말하지만 이러한 브라우저별 선택자를 함께 그룹화합니다.

키프레임

이리저리 움직이는 무한한 애니메이션을 만드는 것이 목표입니다. 시작과 끝 CSS에서 설정됩니다. 하나의 키프레임(중간 키프레임)만 필요합니다. 50%에서 시작 지점으로 돌아가는 애니메이션을 만듭니다. 또다시!

@keyframes progress-loading {
  50% {
    background-position: left; 
  }
}

각 브라우저 타겟팅

일부 브라우저에서는 <progress>에서 유사 요소 생성을 허용하지 않습니다. 요소 자체에 배치하거나 진행률 표시줄을 애니메이션으로 표시할 수 있습니다. 더 많은 브라우저 지원 트랙을 pseudo-elements보다 애니메이션을 사용하기 때문에 pseudo-elements에서 업그레이드합니다. 애니메이션을 막대로 만들 수 있습니다.

Chromium 의사 요소

Chromium은 의사 요소(::after)를 커버할 위치와 함께 사용하는 것을 허용합니다. 요소 확정되지 않은 맞춤 속성이 사용되며 뒤로 및 애니메이션이 잘 작동합니다.

progress:indeterminate::after {
  content: "";
  inset: 0;
  position: absolute;
  background: var(--_indeterminate-track);
  background-size: var(--_indeterminate-track-size);
  background-position: right; 
  animation: var(--_indeterminate-track-animation);
}
Safari 진행률 표시줄

Safari의 경우 맞춤 속성과 애니메이션이 pseudo-element 진행률 표시줄:

progress:indeterminate::-webkit-progress-bar {
  background: var(--_indeterminate-track);
  background-size: var(--_indeterminate-track-size);
  background-position: right; 
  animation: var(--_indeterminate-track-animation);
}
Firefox 진행률 표시줄

Firefox의 경우, 사용자 지정 속성과 애니메이션은 pseudo-element 진행률 표시줄:

progress:indeterminate::-moz-progress-bar {
  background: var(--_indeterminate-track);
  background-size: var(--_indeterminate-track-size);
  background-position: right; 
  animation: var(--_indeterminate-track-animation);
}

자바스크립트

JavaScript는 <progress> 요소에서 중요한 역할을 합니다. 제어 요소에 전송된 값을 확인하고 참조하세요.

const state = {
  val: null
}

데모에는 진행률을 제어하는 버튼이 있습니다. state.val을(를) 업데이트합니다. 그런 다음 DOM.

document.querySelector('#complete').addEventListener('click', e => {
  state.val = 1
  setProgress()
})

setProgress()

이 함수에서 UI/UX 조정이 발생합니다. 먼저 setProgress() 함수를 사용하세요. 에 액세스 권한이 있으므로 매개변수가 필요하지 않습니다. state 객체, 진행률 요소, <main> 영역.

const setProgress = () => {
  
}

<main> 영역에서 로드 상태 설정

진행의 완료 여부에 따라 관련 <main> 요소의 aria-busy 속성:

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)
}

로드 금액을 알 수 없는 경우 속성 삭제

값을 알 수 없거나 설정하지 않은 경우 이 사용에서 null인 경우 valuearia-valuenow 속성 이렇게 하면 <progress>가 미확정으로 바뀝니다.

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }
}

자바스크립트 십진수 수학 문제 해결

진행률 기본값인 최대 1을 유지하기로 선택했기 때문에 데모는 증가 및 감소 함수는 십진수를 사용합니다. JavaScript 및 기타 항상 뛰어나지 않거나 설명을 참고하세요. 다음은 수학에서 초과분을 제거하는 roundDecimals() 함수입니다. 결과:

const roundDecimals = (val, places) =>
  +(Math.round(val + "e+" + places)  + "e-" + places)

표시되고 읽을 수 있도록 값을 반올림합니다.

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }

  const val = roundDecimals(state.val, 2)
  const valPercent = val * 100 + "%"
}

스크린 리더 및 브라우저 상태 값 설정

이 값은 DOM의 세 위치에서 사용됩니다.

  1. <progress> 요소의 value 속성
  2. aria-valuenow 속성
  3. <progress> 내부 텍스트 콘텐츠
const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }

  const val = roundDecimals(state.val, 2)
  const valPercent = val * 100 + "%"

  progress.value = val
  progress.setAttribute('aria-valuenow', valPercent)
  progress.innerText = valPercent
}

진행 상황에 집중

값이 업데이트되면 시력이 정상인 사용자에게는 진행률 변화가 표시되지만 리더 사용자는 아직 변경사항에 대한 공지를 받지 못했습니다. <progress> 요소를 추가하면 브라우저가 업데이트를 알립니다.

const setProgress = () => {
  zone.setAttribute('aria-busy', state.val < 1)

  if (state.val === null) {
    progress.removeAttribute('aria-valuenow')
    progress.removeAttribute('value')
    progress.focus()
    return
  }

  const val = roundDecimals(state.val, 2)
  const valPercent = val * 100 + "%"

  progress.value = val
  progress.setAttribute('aria-valuenow', valPercent)
  progress.innerText = valPercent

  progress.focus()
}

Mac OS Voice Over 앱의 스크린샷 
  사용자에게 로드 표시줄의 진행률을 읽어냅니다.

결론

이제 제가 어떻게 했는지 알게 되셨으니 어떻게 하면 좋을까요?‽ 보상

한 번 더 바꾸고 싶은 부분이 있습니다. 현재 구성요소를 정리하고 <progress> 요소의 의사 클래스 스타일 제한 없이 구성요소를 빌드해 볼 여지가 있다고 생각합니다. 살펴볼 만합니다!

접근방식을 다각화하고 웹에서 빌드하는 방법을 모두 알아보겠습니다.

데모를 만들고 링크를 트윗하여 추가하면 됩니다. 아래 커뮤니티 리믹스 섹션을 공유해 주세요

커뮤니티 리믹스