설정 구성요소 빌드

슬라이더와 체크박스의 설정 구성요소를 빌드하는 방법에 관한 기본 개요입니다.

이 게시물에서는 반응성이 뛰어나고 여러 기기 입력을 지원하며 여러 브라우저에서 작동하는 웹용 설정 구성요소를 빌드하는 방법에 관한 생각을 공유하고자 합니다. 데모를 사용해 보세요.

데모

동영상을 선호하거나 YouTube에서 개발 중인 기능의 UI/UX를 미리 보려면 다음을 참고하세요.

개요

이 구성요소의 측면을 다음 섹션으로 분류했습니다.

  1. 레이아웃
  2. 색상
  3. 맞춤 범위 입력
  4. 맞춤 체크박스 입력
  5. 접근성 고려사항
  6. 자바스크립트

레이아웃

전부 CSS 그리드로 구성된 첫 번째 GUI 챌린지 데모입니다. 다음은 그리드용 Chrome DevTools로 강조 표시된 각 그리드입니다.

설정 레이아웃을 구성하는 모든 상자를 표시하는 데 도움이 되는 다채로운 윤곽선 및 간격 오버레이

간격만

가장 일반적인 레이아웃은 다음과 같습니다.

foo {
  display: grid;
  gap: var(--something);
}

이 레이아웃은 그리드만 사용하여 블록 사이에 간격을 추가하므로 '간격 전용' 레이아웃이라고 합니다.

이 전략을 사용하는 레이아웃은 5개이며 다음과 같이 모두 표시됩니다.

윤곽선으로 강조 표시되고 간격이 채워진 세로 그리드 레이아웃

각 입력 그룹 (.fieldset-item)을 포함하는 fieldset 요소는 gap: 1px를 사용하여 요소 간에 머리카락 선 테두리를 만듭니다. 복잡한 테두리 솔루션은 없습니다.

채워진 간격
.grid {
  display: grid;
  gap: 1px;
  background: var(--bg-surface-1);

  & > .fieldset-item {
    background: var(--bg-surface-2);
  }
}
테두리 트릭
.grid {
  display: grid;

  & > .fieldset-item {
    background: var(--bg-surface-2);

    &:not(:last-child) {
      border-bottom: 1px solid var(--bg-surface-1);
    }
  }
}

자연스러운 그리드 래핑

가장 복잡한 레이아웃은 <main><form> 사이의 논리적 레이아웃 시스템인 매크로 레이아웃이었습니다.

콘텐츠 래핑 중앙 정렬

Flexbox와 그리드 모두 align-items 또는 align-content에 기능을 제공하며, 래핑 요소를 처리할 때 content 레이아웃 정렬은 하위 요소 간에 공간을 그룹으로 배포합니다.

main {
  display: grid;
  gap: var(--space-xl);
  place-content: center;
}

기본 요소는 place-content: center 정렬 바로가기를 사용하여 하위 요소가 1열 및 2열 레이아웃 모두에서 세로 및 가로로 가운데에 배치되도록 합니다.

위 동영상에서 줄바꿈이 발생해도 '콘텐츠'가 가운데에 유지되는 방식을 확인하세요.

자동 맞춤 최솟값/최댓값 반복

<form>는 각 섹션에 적응형 그리드 레이아웃을 사용합니다. 이 레이아웃은 사용 가능한 공간에 따라 열 1개에서 2개로 전환됩니다.

form {
  display: grid;
  gap: var(--space-xl) var(--space-xxl);
  grid-template-columns: repeat(auto-fit, minmax(min(10ch, 100%), 35ch));
  align-items: flex-start;
  max-width: 89vw;
}

이 그리드는 반응형 레이아웃에 맞춤 터치를 적용하기 위해 row-gap (--space-xl)의 값을 column-gap (--space-xxl)과 다르게 지정합니다. 열이 쌓일 때는 넓은 화면에서와 같이 크지는 않지만 큰 간격을 두는 것이 좋습니다.

grid-template-columns 속성은 repeat(), minmax(), min()이라는 3가지 CSS 함수를 사용합니다. Una Kravets훌륭한 레이아웃 블로그 게시물에서 이를 RAM이라고 부르고 있습니다.

Una의 레이아웃과 비교하면 Google의 레이아웃에는 3가지 특별한 추가사항이 있습니다.

  • 추가 min() 함수를 전달합니다.
  • align-items: flex-start를 지정합니다.
  • max-width: 89vw 스타일이 있습니다.

추가 min() 함수는 Evan Minto의 블로그에 있는 minmax() 및 min()을 사용한 본질적으로 반응형 CSS 그리드 게시물에 잘 설명되어 있습니다. 읽어보시기 바랍니다. flex-start 정렬 수정은 기본 늘리기 효과를 삭제하는 것입니다. 따라서 이 레이아웃의 하위 요소는 높이가 같을 필요가 없으며 자연스러운 고유 높이를 가질 수 있습니다. YouTube 동영상에서 이 정렬 추가에 관한 간단한 내용을 확인하세요.

max-width: 89vw는 이 게시물에서 간단히 살펴볼 만한 가치가 있습니다. 스타일이 적용된 레이아웃과 적용되지 않은 레이아웃을 보여드리겠습니다.

어떤 상황인가요? max-width가 지정되면 auto-fit레이아웃 알고리즘이 공간에 맞는 반복 횟수를 알 수 있도록 컨텍스트, 명시적 크기 또는 정확한 크기를 제공합니다. 공간이 '전체 너비'인 것이 분명해 보이지만 CSS 그리드 사양에 따라 정해진 크기 또는 최대 크기를 제공해야 합니다. max-size를 제공했습니다.

그렇다면 89vw는 왜 필요한가요? 내 레이아웃에 '효과가 있었기' 때문입니다. 저와 다른 Chrome 직원 몇 명이 100vw와 같이 더 합리적인 값이 충분하지 않은 이유와 실제로 버그인지 조사하고 있습니다.

간격

이 레이아웃의 조화는 제한된 간격 팔레트(정확히 7개)에서 비롯됩니다.

:root {
  --space-xxs: .25rem;
  --space-xs:  .5rem;
  --space-sm:  1rem;
  --space-md:  1.5rem;
  --space-lg:  2rem;
  --space-xl:  3rem;
  --space-xxl: 6rem;
}

이러한 흐름은 그리드, CSS @nest, @media의 5단계 구문과 함께 매우 잘 작동합니다. 다음은 완전한 <main> 레이아웃 스타일 세트의 예입니다.

main {
  display: grid;
  gap: var(--space-xl);
  place-content: center;
  padding: var(--space-sm);

  @media (width >= 540px) {
    & {
      padding: var(--space-lg);
    }
  }

  @media (width >= 800px) {
    & {
      padding: var(--space-xl);
    }
  }
}

콘텐츠가 가운데에 배치되고 기본적으로 적당한 패딩이 적용된 그리드입니다 (모바일과 마찬가지로). 하지만 더 많은 뷰포트 공간을 사용할 수 있게 되면 패딩을 늘려서 펼쳐집니다. 2021 CSS가 꽤 좋아 보입니다.

이전의 '간격만을 위한' 레이아웃을 기억하시나요? 다음은 이 구성요소에서 텍스트가 표시되는 방식을 보여주는 더 완전한 버전입니다.

header {
  display: grid;
  gap: var(--space-xxs);
}

section {
  display: grid;
  gap: var(--space-md);
}

색상

색상을 적절하게 사용해 표현적이면서도 간결한 디자인을 완성했습니다. 저는 다음과 같이 합니다.

:root {
  --surface1: lch(10 0 0);
  --surface2: lch(15 0 0);
  --surface3: lch(20 0 0);
  --surface4: lch(25 0 0);

  --text1: lch(95 0 0);
  --text2: lch(75 0 0);
}

표시 경로에서 표시 경로와 텍스트 색상을 전환할 것이므로 밝음과 어두움이 의미가 없으므로 surface-darksurface-darker와 같은 이름 대신 숫자로 표시 경로와 텍스트 색상의 이름을 지정합니다.

다음과 같이 환경설정 미디어 쿼리에서 전환합니다.

:root {
  ...

  @media (prefers-color-scheme: light) {
    & {
      --surface1: lch(90 0 0);
      --surface2: lch(100 0 0);
      --surface3: lch(98 0 0);
      --surface4: lch(85 0 0);

      --text1: lch(20 0 0);
      --text2: lch(40 0 0);
    }
  }
}

색상 문법 세부정보를 살펴보기 전에 전체적인 그림과 전략을 빠르게 살펴보는 것이 중요합니다. 하지만 제가 조금 앞서 나가고 있네요. 조금 뒤로 돌아가겠습니다.

LCH?

색상 이론에 너무 깊이 들어가지 않고 말하자면 LCH는 수학 (예: 255)으로 색상을 측정하는 방식이 아니라 인간이 색상을 인식하는 방식에 맞는 인간 중심의 문법입니다. 따라서 인간이 더 쉽게 작성할 수 있고 다른 인간이 이러한 조정에 맞춰 조정할 수 있다는 뚜렷한 이점이 있습니다.

Color 2: Perception 에피소드가 열려 있는 pod.link/csspodcast 웹페이지의 스크린샷
CSS 팟캐스트에서 지각적 색상 등에 대해 자세히 알아보세요.

오늘 이 데모에서는 밝은 색상과 어두운 색상을 만들기 위해 전환하는 구문과 값에 집중하겠습니다. 노출 영역 1개와 텍스트 색상 1개를 살펴보겠습니다.

:root {
  --surface1: lch(10 0 0);
  --text1:    lch(95 0 0);

  @media (prefers-color-scheme: light) {
    & {
      --surface1: lch(90 0 0);
      --text1:    lch(40 0 0);
    }
  }
}

--surface1: lch(10 0 0)10% 밝기, 0 크로마, 0 색조로 변환됩니다. 즉, 매우 어두운 무색 회색입니다. 그런 다음 밝은 모드의 미디어 쿼리에서 밝기가 --surface1: lch(90 0 0);90%로 전환됩니다. 이것이 전략의 핵심입니다. 디자인에 필요한 대비 비율이나 접근성을 유지할 수 있는 대비 비율을 유지하면서 두 테마 간의 밝기를 변경하는 것으로 시작합니다.

여기서 lch()의 장점은 밝기가 인간 중심이라는 점입니다. 밝기에 % 변화를 주면 지각적으로 일관되게 % 다르게 느껴지므로 안심할 수 있습니다. 예를 들어 hsl()신뢰성이 떨어집니다.

관심이 있다면 색상 공간 및 lch()에 대해 자세히 알아보세요. 곧 제공됩니다.

현재 CSS는 이러한 색상에 전혀 액세스할 수 없습니다. 다시 한번 말씀드리자면 대부분의 최신 모니터에서 색상의 3분의 1을 사용할 수 없습니다. 그리고 이러한 색상은 그냥 색상이 아니라 화면에서 표시할 수 있는 가장 선명한 색상입니다. 모니터 하드웨어가 CSS 사양 및 브라우저 구현보다 빠르게 발전하여 웹사이트가 희미해집니다.

Lea Verou

색 구성표가 있는 적응형 양식 컨트롤

많은 브라우저(현재 Safari 및 Chromium)에서 어두운 테마 컨트롤을 제공하지만 디자인에서 이를 사용한다고 CSS 또는 HTML에 지정해야 합니다.

위는 DevTools의 스타일 패널에서 속성의 효과를 보여주는 예입니다. 데모에서는 일반적으로 더 나은 위치라고 생각되는 HTML 태그를 사용합니다.

<meta name="color-scheme" content="dark light">

토마스 슈타이너의 이 color-scheme도움말에서 자세히 알아보세요. 어두운 체크박스 입력 외에도 얻을 수 있는 이점이 많습니다.

CSS accent-color

브라우저 입력 요소에 사용되는 색조 색상을 변경할 수 있는 단일 CSS 스타일인 양식 요소의 accent-color에 관한 최근 활동이 있었습니다. GitHub에서 자세히 알아보세요. 이 구성요소의 스타일에 포함했습니다. 브라우저에서 지원하므로 체크박스가 핑크색과 보라색의 포인트 색상으로 테마에 더 잘 맞게 표시됩니다.

input[type="checkbox"] {
  accent-color: var(--brand);
}

Linux용 Chromium의 분홍색 체크박스 스크린샷

고정된 그라데이션 및 내부 포커스가 있는 컬러 팝

색상은 쓰는 양이 적을 때 가장 눈에 띄며, 이를 달성하는 방법 중 하나는 다채로운 UI 상호작용을 사용하는 것입니다.

위 동영상에는 다음과 같은 방식으로 상호작용에 개성을 부여하는 데 도움이 되는 여러 레이어의 UI 피드백과 상호작용이 있습니다.

  • 맥락 강조 표시
  • 값이 범위 내에서 '얼마나 꽉 찼는지'에 관한 UI 피드백을 제공합니다.
  • 필드에서 입력을 수락하고 있다는 UI 피드백을 제공합니다.

요소와 상호작용할 때 의견을 제공하기 위해 CSS는 :focus-within 의사 클래스를 사용하여 다양한 요소의 모양을 변경합니다. .fieldset-item를 분석해 보겠습니다. 매우 흥미롭습니다.

.fieldset-item {
  ...

  &:focus-within {
    background: var(--surface2);

    & svg {
      fill: white;
    }

    & picture {
      clip-path: circle(50%);
      background: var(--brand-bg-gradient) fixed;
    }
  }
}

이 요소의 하위 요소 중 하나에 focus-within이 있는 경우:

  1. .fieldset-item 배경에는 더 높은 대비 표면 색상이 할당됩니다.
  2. 중첩된 svg는 대비를 높이기 위해 흰색으로 채워집니다.
  3. 중첩된 <picture> clip-path가 전체 원으로 확장되고 배경은 밝은 고정 그래디언트로 채워집니다.

기간 설정

다음 HTML 입력 요소를 사용하여 모양을 맞춤설정하는 방법을 보여드리겠습니다.

<input type="range">

이 요소에는 맞춤설정해야 하는 세 가지 부분이 있습니다.

  1. 범위 요소 / 컨테이너
  2. 추적
  3. 썸네일

범위 요소 스타일

input[type="range"] {
  /* style setting variables */
  --track-height: .5ex;
  --track-fill: 0%;
  --thumb-size: 3ex;
  --thumb-offset: -1.25ex;
  --thumb-highlight-size: 0px;

  appearance: none;         /* clear styles, make way for mine */
  display: block;
  inline-size: 100%;        /* fill container */
  margin: 1ex 0;            /* ensure thumb isn't colliding with sibling content */
  background: transparent;  /* bg is in the track */
  outline-offset: 5px;      /* focus styles have space */
}

CSS의 처음 몇 줄은 스타일의 맞춤 부분이며 명확하게 라벨을 지정하면 도움이 될 것입니다. 나머지 스타일은 대부분 구성요소의 까다로운 부분을 빌드하기 위한 일관된 기반을 제공하기 위한 재설정 스타일입니다.

트랙 스타일

input[type="range"]::-webkit-slider-runnable-track {
  appearance: none; /* clear styles, make way for mine */
  block-size: var(--track-height);
  border-radius: 5ex;
  background:
    /* hard stop gradient:
        - half transparent (where colorful fill we be)
        - half dark track fill
        - 1st background image is on top
    */
    linear-gradient(
      to right,
      transparent var(--track-fill),
      var(--surface1) 0%
    ),
    /* colorful fill effect, behind track surface fill */
    var(--brand-bg-gradient) fixed;
}

이 트릭은 선명한 채우기 색상을 '표시'하는 것입니다. 이는 상단의 하드 스톱 그라데이션을 사용하여 수행됩니다. 그래디언트는 채우기 백분율까지 투명하고 그 이후에는 채워지지 않은 트랙 표면 색상을 사용합니다. 채워지지 않은 노출 영역 뒤에는 투명도가 적용되어 표시될 때까지 기다리는 전체 너비 색상이 있습니다.

트랙 채우기 스타일

디자인에서 채우기 스타일을 유지하려면 JavaScript가 필요합니다. CSS 전용 전략이 있지만 썸네일 요소가 트랙과 동일한 높이여야 하며 이러한 제한 내에서 조화를 찾을 수 없었습니다.

/* grab sliders on page */
const sliders = document.querySelectorAll('input[type="range"]')

/* take a slider element, return a percentage string for use in CSS */
const rangeToPercent = slider => {
  const max = slider.getAttribute('max') || 10;
  const percent = slider.value / max * 100;

  return `${parseInt(percent)}%`;
};

/* on page load, set the fill amount */
sliders.forEach(slider => {
  slider.style.setProperty('--track-fill', rangeToPercent(slider));

  /* when a slider changes, update the fill prop */
  slider.addEventListener('input', e => {
    e.target.style.setProperty('--track-fill', rangeToPercent(e.target));
  })
})

시각적으로도 멋진 업그레이드가 될 것 같습니다. 슬라이더는 JavaScript 없이도 잘 작동합니다. --track-fill 속성은 필요하지 않으며, 없으면 채우기 스타일이 없을 뿐입니다. JavaScript를 사용할 수 있는 경우 사용자 변경사항을 관찰하면서 맞춤 속성을 채우고 맞춤 속성을 값과 동기화합니다.

트랙 채우기에 관한 CSS 전용 솔루션을 보여주는 아나 튜더CSS-Tricks에 관한 유용한 게시물을 확인해 보세요. 이 range 요소도 매우 인상적이었습니다.

썸네일 스타일

input[type="range"]::-webkit-slider-thumb {
  appearance: none; /* clear styles, make way for mine */
  cursor: ew-resize; /* cursor style to support drag direction */
  border: 3px solid var(--surface3);
  block-size: var(--thumb-size);
  inline-size: var(--thumb-size);
  margin-top: var(--thumb-offset);
  border-radius: 50%;
  background: var(--brand-bg-gradient) fixed;
}

이러한 스타일의 대부분은 멋진 원을 만드는 것입니다. 썸네일, 트랙, 연결된 SVG 요소의 동적 색상을 통합하는 고정된 배경 그래디언트가 다시 표시됩니다. 마우스 오버 강조 표시에 사용되는 box-shadow 기법을 분리하기 위해 상호작용의 스타일을 구분했습니다.

@custom-media --motionOK (prefers-reduced-motion: no-preference);

::-webkit-slider-thumb {
  

  /* shadow spread is initally 0 */
  box-shadow: 0 0 0 var(--thumb-highlight-size) var(--thumb-highlight-color);

  /* if motion is OK, transition the box-shadow change */
  @media (--motionOK) {
    & {
      transition: box-shadow .1s ease;
    }
  }

  /* on hover/active state of parent, increase size prop */
  @nest input[type="range"]:is(:hover,:active) & {
    --thumb-highlight-size: 10px;
  }
}

목표는 관리하기 쉽고 애니메이션이 적용된 사용자 의견 시각적 강조 표시를 만드는 것이었습니다. 박스 그림자를 사용하면 이 효과로 레이아웃이 트리거되는 것을 방지할 수 있습니다. 이렇게 하려면 흐리게 처리되지 않고 썸네일 요소의 원형 도형과 일치하는 그림자를 만듭니다. 그런 다음 마우스 오버 시 펼쳐지는 크기를 변경하고 전환합니다.

체크박스에 강조 표시 효과를 적용하는 것이 이렇게 쉬웠다면…

교차 브라우저 선택기

교차 브라우저 일관성을 달성하려면 다음 -webkit--moz- 선택기가 필요하다는 것을 알게 되었습니다.

input[type="range"] {
  &::-webkit-slider-runnable-track {}
  &::-moz-range-track {}
  &::-webkit-slider-thumb {}
  &::-moz-range-thumb {}
}

맞춤 체크박스

다음 HTML 입력 요소를 사용하여 모양을 맞춤설정하는 방법을 보여드리겠습니다.

<input type="checkbox">

이 요소에는 맞춤설정해야 하는 세 가지 부분이 있습니다.

  1. 체크박스 요소
  2. 연결된 라벨
  3. 강조 효과

체크박스 요소

input[type="checkbox"] {
  inline-size: var(--space-sm);   /* increase width */
  block-size: var(--space-sm);    /* increase height */
  outline-offset: 5px;            /* focus style enhancement */
  accent-color: var(--brand);     /* tint the input */
  position: relative;             /* prepare for an absolute pseudo element */
  transform-style: preserve-3d;   /* create a 3d z-space stacking context */
  margin: 0;
  cursor: pointer;
}

transform-styleposition 스타일은 나중에 소개할 하이라이트 스타일을 지정하기 위한 가상 요소를 준비합니다. 그 외에는 대부분 제 개인적인 스타일에 따른 사소한 사항입니다. 커서가 포인터가 되는 것이 좋습니다. 윤곽선 오프셋이 좋습니다. 기본 체크박스가 너무 작습니다. accent-color지원되는 경우 이러한 체크박스를 브랜드 색상 구성표로 가져옵니다.

체크박스 라벨

체크박스에 라벨을 제공하는 것은 다음 두 가지 이유로 중요합니다. 첫 번째는 체크박스 값이 무엇에 사용되는지 나타내 '무엇을 사용 또는 사용 중지할 것인가?'에 답하는 것입니다. 두 번째는 UX입니다. 웹 사용자는 연결된 라벨을 통해 체크박스와 상호작용하는 데 익숙해졌습니다.

입력
<input
  type="checkbox"
  id="text-notifications"
  name="text-notifications"
>
라벨
<label for="text-notifications">
  <h3>Text Messages</h3>
  <small>Get notified about all text messages sent to your device</small>
</label>

라벨에 ID: <label for="text-notifications">로 체크박스를 가리키는 for 속성을 배치합니다. 체크박스의 이름과 ID를 모두 두 번 입력하여 마우스나 화면 리더와 같은 다양한 도구와 기술로 찾을 수 있도록 합니다. <input type="checkbox" id="text-notifications" name="text-notifications"> :hover, :active 등이 연결과 함께 무료로 제공되므로 양식과 상호작용하는 방법이 늘어납니다.

체크박스 강조 표시

인터페이스를 일관되게 유지하고 싶습니다. 슬라이더 요소에는 체크박스와 함께 사용하고 싶은 멋진 썸네일 강조 표시가 있습니다. 썸네일은 box-shadowspread 속성을 사용하여 그림자를 위아래로 크기 조절할 수 있었습니다. 하지만 체크박스가 정사각형이므로 그리고 정사각형이어야 하므로 이 효과는 작동하지 않습니다.

가상 요소와 다소 복잡한 CSS를 사용하여 동일한 시각 효과를 얻을 수 있었습니다.

@custom-media --motionOK (prefers-reduced-motion: no-preference);

input[type="checkbox"]::before {
  --thumb-scale: .01;                        /* initial scale of highlight */
  --thumb-highlight-size: var(--space-xl);

  content: "";
  inline-size: var(--thumb-highlight-size);
  block-size: var(--thumb-highlight-size);
  clip-path: circle(50%);                     /* circle shape */
  position: absolute;                         /* this is why position relative on parent */
  top: 50%;                                   /* pop and plop technique (https://web.dev/centering-in-css#5-pop-and-plop) */
  left: 50%;
  background: var(--thumb-highlight-color);
  transform-origin: center center;            /* goal is a centered scaling circle */
  transform:                                  /* order here matters!! */
    translateX(-50%)                          /* counter balances left: 50% */
    translateY(-50%)                          /* counter balances top: 50% */
    translateZ(-1px)                          /* PUTS IT BEHIND THE CHECKBOX */
    scale(var(--thumb-scale))                 /* value we toggle for animation */
  ;
  will-change: transform;

  @media (--motionOK) {                       /* transition only if motion is OK */
    & {
      transition: transform .2s ease;
    }
  }
}

/* on hover, set scale custom property to "in" state */
input[type="checkbox"]:hover::before {
  --thumb-scale: 1;
}

원 가상 요소를 만드는 것은 간단하지만 연결된 요소 뒤에 배치하는 것이 더 어려웠습니다. 수정 전과 수정 후를 비교해 보세요.

확실히 미시적 상호작용이지만 시각적 일관성을 유지하는 것이 중요합니다. 애니메이션 크기 조정 기법은 다른 곳에서 사용한 것과 동일합니다. 맞춤 속성을 새 값으로 설정하고 CSS가 모션 환경설정에 따라 전환하도록 합니다. 여기서 중요한 기능은 translateZ(-1px)입니다. 상위 요소가 3D 공간을 만들었고 이 가상 요소 하위 요소는 z-space에서 약간 뒤로 배치하여 이 공간을 활용했습니다.

접근성

이 YouTube 동영상에서는 이 설정 구성요소의 마우스, 키보드, 화면 리더 상호작용을 훌륭하게 보여줍니다. 여기에서 몇 가지 세부정보를 알려드리겠습니다.

HTML 요소 선택

<form>
<header>
<fieldset>
<picture>
<label>
<input>

각 힌트는 사용자의 탐색 도구에 관한 힌트와 도움말을 보유하고 있습니다. 일부 요소는 상호작용 힌트를 제공하고, 일부는 상호작용을 연결하며, 일부는 스크린 리더가 탐색하는 접근성 트리를 형성하는 데 도움이 됩니다.

HTML 속성

스크린 리더에 필요하지 않은 요소(이 경우 슬라이더 옆의 아이콘)를 숨길 수 있습니다.

<picture aria-hidden="true">

위 동영상에서는 Mac OS의 화면 리더 흐름을 보여줍니다. 입력 포커스가 한 슬라이더에서 다음 슬라이더로 바로 이동하는 방식을 확인합니다. 다음 슬라이더로 이동하는 도중에 중지되었을 수 있는 아이콘을 숨겼기 때문입니다. 이 속성이 없으면 사용자는 사진을 보지 못할 수 있으므로 멈추고 듣고 지나가야 합니다.

SVG는 수학의 집합입니다. 마우스 오버 시 표시되는 제목과 수학이 생성하는 내용에 관한 사람이 읽을 수 있는 주석을 위한 <title> 요소를 추가해 보겠습니다.

<svg viewBox="0 0 24 24">
  <title>A note icon</title>
  <path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/>
</svg>

그 외에도 마우스, 키보드, 비디오 게임 컨트롤러, 화면 리더에서 양식을 매우 효과적으로 테스트할 수 있도록 HTML을 명확하게 표시했습니다.

자바스크립트

JavaScript에서 트랙 채우기 색상을 관리하는 방법은 이미 다뤘습니다. 이제 <form> 관련 JavaScript를 살펴보겠습니다.

const form = document.querySelector('form');

form.addEventListener('input', event => {
  const formData = Object.fromEntries(new FormData(form));
  console.table(formData);
})

양식과 상호작용하고 변경할 때마다 콘솔은 양식을 테이블에 객체로 로깅하여 서버에 제출하기 전에 쉽게 검토할 수 있도록 합니다.

양식 데이터가 표에 표시된 console.table() 결과의 스크린샷

결론

이제 제가 어떻게 했는지 알았으니 어떻게 하시겠어요? 이를 통해 재미있는 구성요소 아키텍처를 만들 수 있습니다. 좋아하는 프레임워크에 슬롯이 있는 첫 번째 버전을 만들 사람은 누구인가요? 🙂

접근 방식을 다양화하고 웹에서 빌드하는 모든 방법을 알아보겠습니다. 데모를 만들어 트윗해 주시면 아래의 커뮤니티 리믹스 섹션에 추가해 드리겠습니다.

커뮤니티 리믹스

  • @tomayac님이 체크박스 라벨의 마우스 오버 영역과 관련된 스타일을 제공해 주었습니다. 이 버전에는 demosource 요소 간에 마우스 오버 간격이 없습니다.