- 웹 기능 구현은 HTML, CSS, JavaScript 순으로 덜 강력한 기술을 먼저 검토하는 편이 로딩 실패와 접근성 문제를 줄이는 데 유리함
- JavaScript는 브라우저 동작을 직접 제어할 수 있지만, 추가 리소스와 오류 가능성 때문에 키보드·보조 기술 사용자를 배제하기 쉬움
- 과거 JavaScript가 필요했던 체크박스 스위치,
datalist,input type="color",details/summary,dialog같은 기능이 이제는 HTML/CSS 기본 기능으로 상당 부분 가능해짐 - HTML과 CSS의 선언적 기능은 브라우저가 네이티브 동작, 사용자 환경 설정, 접근성 대응을 맡을 수 있어 더 나은 기본값을 제공할 수 있음
- 익숙한 JavaScript 구현이 계속 동작하더라도 최신 HTML/CSS 대안을 주기적으로 확인하고, 바꿀 때는 접근성 테스트를 함께 해야 함
최소 권한의 규칙
- 최소 권한의 규칙은 목적을 달성할 수 있는 가장 덜 강력한 언어를 선택하라는 웹 개발 원칙임
- 웹에서는 보통 HTML을 CSS보다, CSS를 JavaScript보다 먼저 고려하는 방식으로 적용됨
- JavaScript는 세 기술 중 가장 다재다능하지만 그만큼 부담도 큼
- 깨질 수 있음
- 로드에 실패할 수 있음
- 다운로드, 파싱, 실행에 추가 리소스가 필요함
- 키보드 사용자와 보조 기술 사용자를 배제하기 쉬움
- HTML과 CSS는 명령형 JavaScript와 달리 선언적으로 동작함
- 개발자는 브라우저에 무엇을 원하는지 알리고, 구현 방식은 브라우저가 선택함
- 브라우저가 더 효율적인 처리 방식을 고를 수 있음
- 브라우저가 HTML/CSS 기능을 처리하면 성능, 네이티브 동작, 사용자 환경 설정 대응, 접근성 면에서 유리할 수 있음
- 다만 접근성이 항상 자동으로 보장되는 것은 아님
예전에는 JavaScript가 필요했던 기능들
- 브라우저 제작자와 명세 작성자는 몇 년 전까지 JavaScript가 필요했던 기능을 CSS와 HTML로 옮겨 왔음
- 웹은 하위 호환성을 유지하므로, 한 번 익힌 구현 방식이 도구상자에 남아 반복 사용되기 쉬움
- 어떤 기능에 JavaScript가 필요하다고 알고 있더라도 지금도 그런지 가끔 확인하면 더 나은 웹사이트를 만들 수 있음
체크박스로 만드는 커스텀 스위치
- 커스텀 스위치는
div,onclick핸들러, 내부 상태 대신 기본 체크박스와 CSS로 구현할 수 있음 <label>안에<input type="checkbox">를 넣으면 브라우저가 둘을 연결함- 라벨 어디를 클릭해도 체크박스가 토글됨
- 별도
onclick핸들러가 필요 없음
appearance: none은 브라우저 기본 폼 컨트롤 렌더링을 멈추고 직접 스타일링할 수 있게 함input자체를 스위치 배경처럼 꾸밀 수 있음::before를 토글되는 내부 점으로 사용할 수 있음
:checked의사 클래스는 체크 상태에 따라 배경색과::before위치를 바꿀 수 있음- 키보드 사용자를 위해 포커스 표시가 필요함
outline: none으로 포커스를 숨기는 방식은 좋지 않음:focus-visible은 키보드 상호작용 때만 보기 좋은 포커스 링을 표시할 수 있음outline-offset으로 포커스 윤곽선을 요소 바깥이나 안쪽으로 조정할 수 있음
input:focus { outline-color: transparent; }는 일반 상황에서는 윤곽선을 투명하게 만들고, 고대비 모드에서는 사용자가 선택한 색으로 다시 보이게 할 수 있음- 강제 색상 모드는 forced colors explained에서 더 볼 수 있음
datalist로 만드는 네이티브 자동완성
datalist는 사용자가 입력하는 동안 옵션 목록을 보여주는 브라우저 내장 자동 제안 기능임- 구성은 단순함
datalist요소에id와 여러option을 넣음input의list속성으로 해당datalist와 연결함
- 사용자가 입력하면 브라우저가 드롭다운을 표시하고, 입력 내용에 맞게 옵션을 자동 필터링함
- 기본 입력 필드이므로 목록에 없는 값을 직접 입력할 수도 있음
- 입력 필드를 선택한 뒤 화살표 키로 목록을 탐색하거나, 브라우저가 추가한 드롭다운 아이콘을 클릭해 전체 옵션을 볼 수 있음
input type="color"의 기본 컬러 피커
<input type="color">한 줄로 브라우저 네이티브 컬러 피커를 사용할 수 있음- 많은 JavaScript로 만든 캔버스 UI와 슬라이더를 대체할 수 있음
- Chromium 브라우저의 네이티브 컬러 피커는 사이트 내부뿐 아니라 화면 어디에서든 색을 고를 수 있음
- 모든 사용자가 브라우저 컬러 피커를 쓸 수 있는 것은 아니므로, 일반 텍스트 입력처럼 색을 고르는 다른 방법을 함께 제공하는 편이 좋음
details와 summary로 만드는 아코디언
details와summary요소는 콘텐츠를 접었다 펼치는 아코디언을 브라우저 기본 기능으로 제공함- 기본 동작은 단순함
details안의 내용은summary를 제외하고 숨겨짐- 사용자가
summary를 클릭하면 나머지 내용이 표시됨
open속성은 처음 열린 상태를 지정함- 사용자 상호작용 후 고정되는 값이 아니라, 사용자가 열고 닫으면 상태가 바뀜
summary::marker로 기본 삼각형 마커를 스타일링할 수 있음- 콘텐츠를 이모지 등으로 바꿀 수 있음
- 배경색, 배경 이미지, 글꼴 크기 등을 조정할 수 있음
- 많은 CSS 속성은 동작하지 않으며, 완전히 다른 위치로 배치하는 식의 스타일링은 제한됨
- Safari에서는
::-webkit-details-marker의사 요소가 필요함 - 마커 콘텐츠 변경은 보조 기술이 아코디언을 알리는 방식에 영향을 줄 수 있으므로 details/summary inconsistencies를 참고할 수 있음
summary는 클릭 가능하지만 기본적으로 링크처럼 포인터 커서가 나오지 않고 버튼처럼 보이지도 않으므로, hover와 focus 상태를 추가해 클릭 가능성을 드러내야 함
dialog로 만드는 모달
alert(),prompt(),confirm()은 사용자에게 알리거나 확인을 받을 수 있지만 메인 스레드를 잠그고 디자인에 맞게 스타일링하기 어려움- 직접 다이얼로그를 만들면 접근성 처리가 복잡해짐
- 포커스를 다이얼로그 안에 유지해야 함
- 모달임을 알려야 함
- 사용자가 실수로 빠져나가지 않게 해야 함
- 매우 높은
z-index를 가진 위젯과 충돌할 수 있음
- 브라우저의
dialog요소는 네이티브 다이얼로그를 제공함 - 현재는 다이얼로그를 열기 위해 JavaScript가 필요함
- JavaScript 없이 여는 변경이 진행 중이지만 아직 완전히 명세화되거나 구현되지는 않음
showModal()함수로 다이얼로그를 열 수 있음
dialog는 top layer에 열림- top layer는 HTML과 분리된 새 레이어임
- 이 레이어의 요소는
z-index와 스태킹 컨텍스트 중첩과 관계없이 항상 위에 표시됨 - 개념 설명은 MDN의 Top layer를 참고할 수 있음
dialog는 기본 닫기 UI를 제공하지 않으므로 직접 UI를 넣어야 함form method="dialog"가 제출되면 브라우저가 다이얼로그를 닫음- 두 개의 제출 버튼에 서로 다른
value를 넣으면 확인 다이얼로그처럼 사용할 수 있음 close이벤트에서dialog.returnValue를 읽어 사용자가 누른 버튼 값을 확인할 수 있음- 추가 폼 데이터는 FormData로 읽을 수 있음
dialog::backdrop은 다이얼로그와 나머지 페이지 사이의 레이어임- 배경을 어둡게 하거나 흐리게 해 사용자의 주의를 다이얼로그로 유도할 수 있음
- 브라우저가 배치하므로 스크롤, 고정 요소, 브라우저 크기 변경을 직접 처리할 필요가 없음
더 적은 JavaScript로 가능한 기능들
- JavaScript를 줄일 수 있는 기능은 더 많음
scroll-behavior: smooth를 이용한 네이티브 부드러운 스크롤prefers-reduced-motion: no preference가 맞을 때만 사용하는 조건이 붙음
scroll-snap을 이용한 네이티브 캐러셀position: sticky를 이용한 “in-view” 요소- 컨테이너 쿼리
- 앞으로 추가될 기능도 있음
- 스크롤 기반 애니메이션
masonry.js없이grid-template-rows: masonry로 만드는 Masonry 레이아웃- 새
selectlist요소를 통한 완전 스타일링 가능한select - JavaScript 선택 코드의 한 범주를 줄일 수 있는
:has()선택자
- 발표 영상 Stop Using JavaScript for That: Moving Features from JS to CSS and HTML.에서 관련 내용을 더 볼 수 있음
- 기존에 검증된 구현을 새로운 방식으로 바꿀 때는 특히 접근성을 테스트해 누구도 배제하지 않도록 해야 함