CSS 유틸리티

[CSS :open] details·dialog·select의 열림 상태를 JS 없이 칠하는 가상클래스

열고 닫히는 네이티브 요소들의 지금 열렸는가를 단 하나의 CSS 가상클래스로 통일. 색/회전/백드롭이 전부 :open 으로 그려집니다.

CSS :opendetails/summarydialogselect@supportsprefers-reduced-motion
라이브 데모
새 탭에서 열기
데모 불러오는 중…

제작 과정

한 줄 요약 - details/dialog/select처럼 열고 닫히는 요소가 지금 열려 있는지를 CSS :open 하나로 잡아 색/애니메이션을 입히는 데모입니다.

이럴 때 필요해요

예전엔 열림 상태를 다루는 방법이 요소마다 제각각이었습니다. details는 [open] 속성으로 잡혔지만, dialog는 JS로 클래스를 토글해야 했고, select 드롭다운이 펼쳐진 순간은 CSS로 아예 잡을 수가 없었어요. 열림에 따라 스타일을 바꾸려고 작은 자바스크립트 상태를 여기저기 두던 일을, 이제 한 가상클래스(특정 상태일 때만 적용되는 CSS 선택자)로 끝낼 수 있습니다.

어떻게 동작하나

  1. details를 펼치면 details:open 이 즉시 매칭돼 카드 배경/테두리/셰브론 회전이 한꺼번에 바뀝니다 (자바스크립트 0줄).

  2. dialog는 버튼이 showModal()로 띄우기만 하고, 열린 모습 자체(등장 애니메이션, 뒤 배경 어두워짐)는 dialog:open 과 dialog:open::backdrop 이 칠합니다.

  3. select는 드롭다운이 떠 있는 그 순간에만 select:open 이 적용돼 테두리가 강조되고, 닫히면 원래대로 돌아옵니다.

핵심은 이거예요

상태를 관리하는 게 아니라 브라우저가 이미 아는 열림/닫힘을 CSS가 그대로 읽어 그린다는 점입니다. :open 하나가 details/dialog/select/날짜/색상 피커까지 전부 커버하므로, 요소마다 다르던 방식을 한 줄로 통일할 수 있어요.

놓치기 쉬운 것

  • 아직 새 기능이라 @supports selector(:open)로 지원 여부를 확인하고, details는 옛 [open] 폴백을 같이 두면 구형 브라우저에서도 안전합니다.

  • dialog는 display:none 에서 켜지므로 전환을 매끄럽게 하려면 등장 애니메이션을 :open 에 걸어줍니다.

  • 모션에 민감한 사용자를 위해 prefers-reduced-motion 에서 애니메이션을 꺼주세요.

이런 곳에 써요

  • FAQ 아코디언, 설정 패널 같은 펼침/접힘 UI의 열린 상태 강조

  • 모달과 그 뒤 배경(백드롭)을 JS 상태 없이 일관되게 스타일링

소스 코드

· 데모 페이지에서 자동 추출
import type { Metadata } from "next";
import { OpenPseudoClassDemo } from "./-components/OpenPseudoClassDemo";

export const metadata: Metadata = {
  title: ":open 가상클래스 (데모)",
  description:
    "details·dialog·select의 '열림' 상태를 JS 없이 CSS :open 하나로 칠하는 가상클래스 데모. @supports 폴백 포함.",
  robots: { index: false, follow: false },
};

export default function Page() {
  return (
    <main className="flex min-h-[100dvh] items-center justify-center bg-white">
      <OpenPseudoClassDemo />
    </main>
  );
}
11조회수

댓글