스크랩

라이브러리 없이 끝내는 UI, 브라우저가 이미 다 갖고 있었다

라이브러리 없이 끝내는 UI, 브라우저가 이미 다 갖고 있었다

새 프레임워크 대신 브라우저 기본기부터

요즘 웹 개발 하다 보면 모달 하나, 아코디언 하나 만들 때도 라이브러리부터 검색하게 되죠. 그런데 사실 최신 브라우저는 HTML·CSS·JS만으로도 꽤 많은 걸 네이티브하게 처리할 수 있습니다. GeekNews에 소개된 'HTMLcat' 레퍼런스 사이트는 이런 작은 팁 42개를 모아둔 곳인데, 오늘은 그중 핵심만 골라 정리해봤습니다.

입력 방식을 추측하지 말고 물어보자

  • any-pointer, any-hover 미디어 쿼리를 쓰면 User-Agent로 모바일인지 데스크톱인지 눈치 볼 필요 없이, 실제로 연결된 입력 장치가 정밀 포인터인지 터치인지 Hover가 가능한지 바로 알 수 있습니다.
  • 터치스크린 노트북처럼 두 가지 입력이 공존하는 기기도 자연스럽게 커버됩니다. 단, Hover에만 의존한 기능은 키보드·터치 사용자를 소외시키니 항상 대체 경로를 마련해두세요.

CSS 셀렉터로 상태 관리 줄이기

  • :has()는 자식이나 형제 조건으로 부모를 선택할 수 있어서, form:has(:invalid)처럼 하위 요소 상태에 따라 부모 스타일을 바꾸는 게 가능해졌습니다.
  • :target은 URL의 #fragment가 가리키는 요소를 선택하니, 딥링크 강조나 간단한 패널 전환을 JS 상태 없이 구현할 수 있어요.
  • :where()는 여러 셀렉터를 묶으면서 Specificity를 0으로 만들어주기 때문에, 나중에 쉽게 덮어쓸 수 있는 기본 스타일 작성에 유용합니다.
  • classList.toggle(class, boolean)처럼 두 번째 인자에 boolean을 넘기면 상태를 '반전'시키는 대신 명시적으로 동기화할 수 있습니다.

레이아웃, 이제 트릭이 필요 없다

  • 중앙 정렬은 display: grid; place-items: center 두 줄이면 끝. 1차원 배치는 Flexbox가 여전히 더 적합합니다.
  • @scope는 네임스페이스 클래스를 매번 붙이지 않고도 특정 DOM 영역으로 CSS 적용 범위를 제한할 수 있습니다. 다만 상속 속성과 커스텀 프로퍼티는 경계를 넘나드니 완전한 캡슐화는 아니라는 점 기억하세요.
  • Container Query를 쓰면 뷰포트가 아니라 컴포넌트가 실제로 받은 공간을 기준으로 카드 레이아웃을 바꿀 수 있습니다.
  • CSS Grid Lanes는 네이티브 Masonry를 목표로 개발 중이지만 아직 실험 단계라 프로덕션에는 조심스럽게 접근해야 합니다.

스크롤·전환 효과도 CSS 선에서

  • scrollbar-width: none으로 스크롤 기능은 유지하면서 스크롤바만 숨길 수 있고, scroll-behavior: smooth만으로 앵커 이동을 부드럽게 만들 수 있습니다. prefers-reduced-motion 사용자를 위한 배려도 잊지 마세요.
  • 고정 헤더 때문에 앵커 이동 후 제목이 가려지는 흔한 문제는 scroll-margin-block-start 한 줄로 해결됩니다.
  • View Transitions API는 두 DOM 상태 사이의 전환을 브라우저가 알아서 애니메이션해주고, 미지원 환경에서는 기존 방식으로 자연스럽게 폴백됩니다.

텍스트와 색상 다루기

  • clamp(min, fluid, max)로 브레이크포인트별 분기 없이 글자 크기·여백을 자연스럽게 조절할 수 있습니다.
  • text-wrap: balance(제목용)와 text-wrap: pretty(본문용)는 줄바꿈을 훨씬 자연스럽게 만들어줍니다.
  • CSS Custom Highlight API는 <span>을 삽입하지 않고도 임의의 텍스트 범위를 강조할 수 있어 검색 결과나 에디터 오버레이에 특히 유용해요.
  • light-dark()로 라이트·다크 두 색상을 한 선언에 정의하고, color-mix()로 반투명 색상을 손쉽게 만들 수 있습니다. accent-color 하나면 체크박스·라디오·프로그레스바 강조색을 한 번에 바꿀 수 있고요.

JS 없이 되는 UI들

  • <dialog>는 모달을 Top Layer에 띄우고 포커스 트랩, Escape 닫기까지 알아서 처리해줍니다.
  • Popover API는 비모달 메뉴·패널을 위한 것으로, 바깥 클릭·Escape 닫기를 브라우저가 담당합니다.
  • 여러 <details>에 같은 name을 주면 아코디언이 상태 관리 JS 없이 완성됩니다.
  • inert 속성으로 특정 DOM 영역을 포커스·포인터·접근성 트리에서 통째로 제외시킬 수도 있습니다.

정리하며

핵심은 하나입니다 — 뭔가를 직접 구현하기 전에, 브라우저가 이미 제공하지 않는지 먼저 확인해보자는 것. 다만 :has()나 Container Query처럼 안정적인 기능도 있지만, CSS Grid Lanes나 Scroll Snap Events처럼 아직 Experimental 단계인 기능도 섞여 있으니 @supports로 감싸거나 기존 구현을 폴백으로 남겨두는 점진적 향상 전략은 꼭 챙기시길 바랍니다.


원문: https://news.hada.io/topic?id=32793