개발자 의견 요청: 맞춤설정 가능한 선택

<select> 요소와 같은 양식 컨트롤의 스타일 지정이 수년 동안 개발자들에게 가장 큰 문제로 지적되어 왔으며, Google에서는 해결책을 모색하고 있습니다. 이 작업은 복잡하고 제대로 구현하는 데 시간이 오래 걸렸지만 이제 이 기능을 출시할 준비가 거의 되었습니다. 맞춤설정 가능한 버전의 select 요소는 WHATWG2단계에 공식적으로 있으며, 교차 브라우저 관심이 높고 Chrome Canary 130에서 테스트할 수 있는 프로토타입이 있습니다.

사용해 보고 의견 보내기

Chrome Canary 설치가 버전 130으로 업데이트되었는지, 실험용 웹 플랫폼 기능 플래그가 사용 설정되어 있는지 확인합니다. 주소 표시줄에서 chrome://flags로 이동하여 #experimental-web-platform-features를 사용 설정하면 이 플래그를 사용 설정할 수 있습니다. 그러면 이 게시물에 Codepen 데모가 표시됩니다. 또는 이 Codepen 컬렉션을 확인하여 한곳에서 모두 볼 수 있습니다.

이 양식을 사용하여 기능에 관한 의견을 보내주세요. 완료하는 데 3분밖에 걸리지 않습니다.

기존 HTML select 태그를 기반으로 하는 맞춤설정 가능한 select API의 기능을 자세히 살펴보겠습니다.

<select> 선택

새 동작을 선택하려면 페이지 내 선택 버튼과 선택 도구 모두에서 CSS appearance 속성을 사용하세요. 선택하려면 <select> 요소와 ::picker(select)에서 appearance: base-select를 설정합니다.

::picker(select)appearance: base-select를 사용하여 새 동작을 선택한 <select> 요소에만 적용되는 새로운 사용자 에이전트 제공 가상 요소입니다. 이 선택 도구 가상 요소는 기본 선택 버튼으로 트리거되는 팝오버입니다. 다음 코드와 같이 둘 다 선택할 수 있습니다.

select,
::picker(select) {
  appearance: base-select;
}

페이지 내 버튼만 선택할 수는 있지만 페이지 내 버튼을 선택하지 않고 선택 도구 팝오버만 선택할 수는 없습니다. ::picker(select)appearance: base-select<select>에 적용된 후에만 생성됩니다.

이제 선택 요소를 맞춤설정할 준비가 되었습니다. 맞춤설정이 가능한 새로운 선택에는 브라우저와 운영체제에서 동일하게 표시되는 몇 가지 기본 스타일이 있습니다. macOS용 Chrome의 기존 선택과 기본 맞춤 선택의 비교는 다음과 같습니다.

오른쪽의 맞춤설정 가능한 선택의 기본 사용자 에이전트 스타일입니다. 이 내용은 변경될 수 있으며 의견을 보내주시면 감사하겠습니다.
기본 선택과 맞춤설정 가능한 선택의 데모

구성요소 분석

선택의 일부를 보여주는 다이어그램

맞춤설정이 가능한 새 선택 모드로 전환되면 이제 다음과 같은 새 요소에 액세스할 수 있습니다. - selectedoption: 현재 선택된 옵션의 내부 HTML을 반영합니다. - option::before: 현재 선택된 옵션을 기본 접근성 어포던스로 나타내는 체크표시가 포함됩니다 (변경될 수 있음). - ::picker(select): 맞춤설정 가능한 선택 내의 button 외부의 모든 콘텐츠가 포함된 팝오버입니다.

선택의 모든 부분에 스타일을 지정할 수 있습니다. 예를 들어 <option> 요소 내에 상호작용이 없는 임의의 콘텐츠를 추가하고, 선택 드롭다운을 여는 페이지 내 버튼의 스타일을 지정하고, 옵션 드롭다운 목록 (::picker(select))의 스타일을 지정할 수 있습니다.

button, 가져오기 화살표 표시기의 스타일을 지정하고 요소 내부와 주변에 임의의 콘텐츠를 추가할 수도 있습니다. 콘텐츠를 추가하는 것 외에도 이러한 새 요소와 기본 스타일을 숨길 수 있습니다. 예를 들어 옵션의 ::before 가상 요소에 표시기 체크표시를 표시하지 않으려면 다음 CSS를 사용하세요.

/* Remove the default checkmark from the selected option */
option::before {
 display: none;
}

선택 내부에는 요소가 무제한으로 있을 수 있지만 브라우저는 <button> 요소 외부의 모든 요소를 버튼에 고정된 팝오버처럼 작동하는 ::picker(select) 가상 요소로 버케팅합니다. 이 <button>::picker(select)를 전환합니다. select 내부에 있는 옵션과 기타 요소는 ::picker(select)로 호이스팅되며 스타일 지정을 위해 자체 래퍼를 가져올 수도 있습니다. 이 래퍼도 ::picker(select) 가상 요소 내에 배치됩니다.

<select>
  <button>
    <selectedoption></selectedoption>
  </button>
  // Everything else that will go into the ::picker(select) popover
</select>

맞춤설정이 가능한 새로운 <select>팝오버앵커 위치 지정의 기능을 사용합니다. 이 두 가지 기본 기술로 빌드됩니다. 즉, 선택 내의 드롭다운 옵션 목록은 선택을 여는 트리거 버튼에 고정된 팝오버 역할을 합니다.

앵커 위치 지정을 사용하여 이 ::picker(select) 팝오버의 스타일을 지정할 수 있습니다 (다른 요소에 고정하는 작업 포함). 이 콘텐츠 모델은 최상위 레이어 애니메이션 스타일이 옵션 목록과 함께 작동하여 진입 및 종료 효과를 애니메이션 처리한다는 것을 의미합니다.

기존 <select> 요소 개선

이전에는 Chrome팀에서 <selectlist> 요소에 관한 아이디어를 연구하고 있었습니다. 이 게시물에서는 기존 <select> 요소를 재사용하도록 다시 설계된 이 기능을 설명합니다.

기존 <select> 요소를 재사용하면 기본 HTML 요소를 점진적으로 개선할 수 있다는 것이 큰 이점입니다. 새 요소와 비교할 때 <select>를 재사용하면 페이지에 의미 있는 콘텐츠가 계속 렌더링됩니다. 다음 예는 맞춤설정된 선택 항목과 지원되지 않는 브라우저 사용자에게 표시되는 항목을 보여줍니다.

option 내의 모든 텍스트 콘텐츠는 선택 요소의 대체 버전으로 렌더링됩니다.

기본 스타일 지정

선택한 요소의 시각적 스타일을 변경하는 것만큼 간단할 수 있습니다. 예를 들어 버튼 스타일, 마우스 오버 및 포커스 스타일 또는 선택 옵션의 배경을 업데이트할 수 있습니다. appearance: base-select를 선택한 후 선택한 부분에 원하는 CSS를 적용합니다.

기본 버튼을 사용하여 선택의 여러 부분의 스타일을 변경합니다.

화살표 표시기를 맞춤설정하려면 선택 안에 자체 버튼과 화살표를 추가합니다.

<select>
  <button>
    <selectedoption></selectedoption>
    <span>
      // Arrow here
    </span>
  </button>
  // Everything else that will go into the ::picker(select) popover
</select>

그런 다음 화살표의 스타일을 지정합니다.

/* style the arrow */
button span {
  /* arrow styles */
  transition: rotate 0.2s;
}

/* adjust arrow styles when the picker is open */
select:open button span {
  rotate: -180deg;
}

옵션 내의 복잡한 콘텐츠

<select> 내의 <option> 요소 내에 문자열 외의 콘텐츠를 추가하고 스타일을 지정하는 기능으로 한 단계 더 나아가세요. 기본적인 예로는 드롭다운 메뉴의 국가 이름 옆에 국기 이미지를 추가하는 것이 있습니다. 이렇게 하려면 옵션 텍스트 옆에 이미지 요소를 추가합니다.

<option value="france">
  <img src="img/flag_of_france.svg" alt="" />
  <span>France</span>
</option>
국기와 함께 국가 선택 도구.

더 복잡한 예로는 드롭다운에서 선택할 항목을 결정하는 데 도움이 되는 프로필 사진, 이름, 대체 정보가 포함될 수 있습니다.

<option value="eur">
    <img src="euro-flag.png" alt="" />
    <div class="currency">
      <div class="currency-short">EUR</div>
      <div class="currency-long">Euro</div>
    </div>
    <div class="symbol" aria-hidden="true">€</div>
</option>
통화 선택 도구의 스크린샷

선택한 옵션의 스타일 지정

선택한 옵션이 선택된 상태에서 드롭다운과 다르게 표시되도록 할 수 있습니다. Gmail UI가 이러한 예입니다. Gmail UI에서는 공간을 절약하기 위해 옵션을 선택하면 라벨이 삭제됩니다. 스타일 지정을 위해 <selectedoption> 요소를 후크하면 됩니다. <option>에는 다음과 같은 마크업이 모두 포함됩니다.

 <option value="reply-all">
    <img class="material-symbol"  src="material-symbol-reply.png">
    <span class="text">Reply all</span>
  </option>

이제 <selectedoption> 내의 .textdisplay: none을 적용하여 텍스트 콘텐츠를 숨기고 아이콘만 표시합니다.

selectedoption .text {
  display: none;
}
선택한 옵션을 나타내는 아이콘이 있는 Gmail 스타일 선택

양방향 옵션

::picker(select)의 스타일을 완전히 제어하여 이전 데모를 기반으로 마우스 오버 및 포커스 시 양방향으로 만들 수 있습니다. 이 데모에서는 새 calc-size() 함수가 선택 도구의 너비를 아이콘을 표시하는 것에서 마우스 오버 시 옵션의 전체 너비를 표시하는 것 또는 선택 도구에 focus-visible이 있는 옵션이 있는 경우 애니메이션을 적용하는 데 사용됩니다.

/* base styles when picker is open but not interacted with */
::picker(select) {
  width: var(--icon-width);
  transition: width 0.5s;
}

/* animate the text in on hover & focus */
::picker(select):hover,
select:has(option:focus-visible)::picker(select) {
  /*  auto width!  */
  width: calc-size(auto, size + 0.5rem);
}
마우스 오버 또는 포커스 시 점진적으로 콘텐츠가 표시되는 양방향 Gmail 스타일 선택

제한사항 및 접근성 메모

큰 힘에는 큰 책임이 따른다. 액세스할 수 있도록 하기 위해 이 기능에는 몇 가지 제한사항이 있습니다.

  • <option> 요소 외에는 버튼이나 기타 요소와 같은 상호작용형 (포커스를 받을 수 있는) 요소가 <select> 내부에 허용되지 않습니다. 현재 제안된 콘텐츠 모델은 <div>, <span>, <option>, <optgroup>, <img>, <svg>, <hr> 요소만 허용합니다.
  • 분할 버튼은 현재 액세스 가능한 솔루션을 찾기 위해 실험 단계에 있습니다.

향후 이러한 환경의 접근성 스토리가 구체화됨에 따라 콘텐츠 모델이 더욱 유연해질 것으로 예상됩니다.

결론

Google은 이 기능이 작업반과 표준 기관을 통해 진행되는 모습을 지켜보고 프로토타입을 적극적으로 빌드하고 이 기능의 형태를 평가하면서 진행 상황을 공유할 수 있어 기쁩니다. 예상대로 작동하지 않는 문제가 발생하면 알려주세요.

이 기능은 아직 개발 중이지만 간단한 의견 양식을 통해 의견을 보내주시면 감사하겠습니다.

웹에서 액세스 가능하고 맞춤설정 가능한 양식 컨트롤을 더 쉽게 빌드할 수 있도록 도와주셔서 감사합니다.