설정 구성요소 빌드

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

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

데모

동영상을 선호하거나 빌드 중인 기능의 UI/UX 미리보기를 원하는 경우 YouTube에 관한 간단한 과정을 살펴볼 수 있습니다.

개요

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

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

레이아웃

모든 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 정렬 축약을 사용하여 하위 요소가 한 개의 열과 두 개의 열 레이아웃 모두에서 세로 및 가로로 중앙에 배치되도록 합니다.

위 동영상에서 래핑이 발생해도 '콘텐츠'가 중앙에 유지되는 방식을 확인하세요.

자동 맞춤 최솟값 반복

<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;
}

이 그리드는 반응형 레이아웃에 맞춤 터치를 배치하기 위한 column-gap (--space-xxl)과 다른 row-gap (--space-xl) 값을 갖습니다. 열이 쌓일 때 큰 간격을 원하지만 와이드 화면에서만큼 크지는 않습니다.

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

Una의 레이아웃과 비교해보면 레이아웃에 3가지 특별한 추가 기능이 있습니다.

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

추가 min() 함수는 에반 민토가 블로그에서 minmax() 및 min()을 사용한 내장형 CSS 그리드 게시물의 잘 설명하고 있습니다. 읽어보는 것이 좋습니다. flex-start 정렬 수정은 기본 확장 효과를 삭제하는 것입니다. 따라서 이 레이아웃의 하위 요소 높이가 동일하지 않아도 되는 자연스러운 고유 높이를 가질 수 있습니다. YouTube 동영상에서 이 정렬 추가에 대한 간단한 분석을 확인할 수 있습니다.

max-width: 89vw은(는) 이 게시물에서 간략하게 살펴볼 가치가 있습니다. 스타일이 적용된 경우와 적용되지 않은 레이아웃을 보여 드리겠습니다.

변경된 사항 max-width가 지정되면 auto-fit 레이아웃 알고리즘이 공간에 맞는 반복 횟수를 파악할 수 있도록 컨텍스트, 명시적인 크기 조정 또는 확정 크기 조정을 제공합니다. 공간이 '전체 너비'인 것으로 보이지만 CSS 그리드 사양에 따라 확실한 크기 또는 최대 크기를 제공해야 합니다. 최대 크기를 입력했습니다.

그렇다면 왜 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 사양 및 브라우저 구현보다 빠르게 발전했기 때문에 Google 웹사이트가 단조로워졌습니다.

레아 베루

색 구성표를 사용한 적응형 양식 컨트롤

현재 Safari와 Chromium 등 대부분의 브라우저에서 어두운 테마 컨트롤을 제공하지만 디자인에서 이를 사용하도록 CSS 또는 HTML에서 지정해야 합니다.

위는 DevTools의 스타일 패널에 있는 속성의 효과를 보여줍니다. 이 데모에서는 HTML 태그를 사용하는데, 제 생각에는 이 태그가 일반적으로 더 나은 위치라고 생각합니다.

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

자세한 내용은 토마스 슈타이너color-scheme 도움말을 참조하세요. 어두운 체크박스 입력보다 얻어야 할 것이 훨씬 많습니다

CSS accent-color

양식 요소에 관한 accent-color 관련 최근 활동이 있습니다. 이는 브라우저 입력 요소에 사용되는 색조 색상을 변경할 수 있는 단일 CSS 스타일입니다. 자세한 내용은 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;
    }
  }
}

이 요소의 하위 요소 중 하나에 포커스가 있는 경우:

  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;
}

비결은 선명한 채우기 색상을 '표시'하는 것입니다. 맨 위에 있는 하드 스톱 그라데이션을 사용하면 됩니다. 그라데이션은 채우기 비율까지 투명하며, 그 후에는 채워지지 않은 트랙 표면 색상을 사용합니다. 채워지지 않은 표면 뒤에는 전체 너비 색상이 있어 투명도가 드러나지 않을 때까지 기다립니다.

트랙 채우기 스타일

채우기 스타일을 유지하기 위해 내 디자인에 자바스크립트가 필요합니다. CSS 전용 전략이 있지만 thumb 요소의 높이가 트랙과 동일해야 하며 이러한 한도 내에서 조화를 찾을 수 없었습니다.

/* 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 속성이 필요하지 않으며, 없는 경우 채우기 스타일이 없습니다. 자바스크립트를 사용할 수 있는 경우 맞춤 속성을 채우면서 사용자 변경사항을 관찰하면서 맞춤 속성을 값과 동기화합니다.

이 게시물Ana TudorCSS-Tricks에서 확인할 수 있습니다. 이 게시물에서는 트랙 채우기를 위한 CSS 전용 솔루션을 시연합니다. 또한 이 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;
  }
}

목표는 관리하기 쉬운 애니메이션으로 시각적으로 하이라이트를 보여주는 사용자 피드백이었습니다. 상자 그림자를 사용하면 효과로 인한 레이아웃 트리거를 방지할 수 있습니다. 이렇게 하려면 흐려지지 않으며 thumb 요소의 원형 모양과 일치하는 그림자를 만듭니다. 그런 다음 마우스 오버 시 확산 크기를 변경하고 전환합니다.

체크박스에서 강조표시 효과가 그렇게 쉽다면...

교차 브라우저 선택기

교차 브라우저 일관성을 달성하려면 다음과 같은 -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로 가리키는 for 속성(<label for="text-notifications">)을 라벨에 배치합니다. 체크박스에서 이름과 ID를 두 배로 표시하여 마우스나 스크린 리더와 같은 다양한 도구와 기술로 찾을 수 있는지 확인합니다. <input type="checkbox" id="text-notifications" name="text-notifications"> :hover, :active 등은 연결 시 무료로 제공되므로 양식과 상호작용하는 방식이 개선됩니다.

체크박스 강조표시

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

유사 요소와 같이 까다로운 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 공간에 약간 다시 배치하여 3D 공간을 탭했습니다.

접근성

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

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 요소 사이에 마우스 오버 간격이 없습니다.