프로필 로고
2026-04-05

data-active 속성 패턴

data-active 커스텀 데이터 속성으로 컴포넌트 상태를 DOM에 노출해 CSS 속성 선택자·디버깅·테스트가 같은 정보원을 공유하게 만드는 React 패턴. className 방식과의 비교, aria-* 속성과의 차이, 장단점을 정리한다.

  • React
  • DOM
  • CSS
  • HTML
  • 접근성

data-active는 컴포넌트 상태를 DOM 속성으로 노출하여 스타일과 로직을 의미 있게 분리하는 React 패턴이다.

HTML 요소

  1. HTML 요소는 브라우저가 HTML 문서를 파싱할 때 DOM 트리 안의 노드 객체로 변환된다.

  2. 이 노드는 JavaScript의 객체이며, ElementHTMLElement 클래스의 인스턴스이다.

  3. 즉, 화면에 보이는 <button> 태그는 사실 메모리상에 존재하는 객체와 1:1로 연결되어 있다.

  4. 객체이기 때문에 프로퍼티를 가질 수 있고, HTML의 속성(attribute)은 이 객체의 정보로 저장된다.

  5. data-* 속성도 마찬가지로 객체에 정보로 저장되며, element.dataset을 통해 JS에서 접근할 수 있다.

    const btn = document.querySelector("button");
    btn.dataset.active;          // "true"
    btn.dataset.active = "false"; // DOM에도 즉시 반영됨
  6. 따라서 마크업에 적은 data-active="true"는 단순한 텍스트가 아니라, 실제 DOM 객체의 살아있는 상태 정보이다.

  7. 이 구조 덕분에 HTML, JS, CSS가 같은 정보를 공유하면서도 각자의 방식으로 읽고 활용할 수 있다.

배경

  1. HTML에는 요소에 커스텀 정보를 저장할 수 있는 data-* 속성이 존재한다.

  2. 이 속성은 JavaScript나 CSS가 특정 상태를 추적하거나 스타일에 반응해야 할 때 활용된다.

  3. UI 컴포넌트에서는 탭, 버튼, 메뉴 아이템 같은 요소가 "활성 상태"인지를 표현해야 하는 경우가 많다.

  4. 이때 상태를 className 문자열로만 관리하면 의미가 흐려지고 스타일과 로직이 뒤섞이는 문제가 있다.

개념

  1. data-active는 요소가 활성 상태인지를 마크업 수준에서 표현하는 커스텀 데이터 속성이다.

  2. React에서는 컴포넌트의 state 값을 DOM 속성에 그대로 반영하는 패턴으로 자주 사용된다.

  3. 예를 들어 탭에서 선택된 항목을 구분할 때 다음과 같이 작성한다.

    <button data-active={isActive}>탭 1</button>
  4. 이렇게 하면 isActivetrue일 때 DOM에 data-active="true"가 실제로 붙는다.

CSS 연결

  1. CSS에서는 속성 선택자를 사용해 해당 상태에 스타일을 적용한다.

    [data-active="true"] {
      background-color: blue;
      color: white;
    }
  2. 상태가 마크업에 그대로 노출되어 있기 때문에 별도의 클래스 토글 없이도 CSS가 상태에 반응할 수 있다.

className 방식과의 비교

  1. 기존 방식은 조건부로 className을 바꾸어 스타일을 적용했다.

    // className 방식
    <button className={isActive ? "active" : ""}>탭</button>
     
    // data-active 방식
    <button data-active={isActive}>탭</button>
  2. className 방식은 문자열을 조작해야 해서 상태와 스타일의 관계가 한눈에 드러나지 않는다.

  3. 반면 data-active 방식은 상태값이 그대로 속성에 반영되므로 의미가 명확하다.

  4. 또한 상태는 컴포넌트가, 스타일링은 CSS가 담당하므로 역할 분리가 깔끔해진다.

aria-* 속성과의 차이

  1. aria-* 속성은 스크린 리더 같은 보조 기술에 의미를 전달하는 접근성 속성이다.

  2. 반면 data-active는 접근성 의미를 부여하지 않고, 순수하게 시각적·논리적 상태 표현 용도로만 쓰인다.

  3. 따라서 접근성까지 고려해야 한다면 aria-selected 같은 속성을 함께 사용해야 한다.

마크업 수준 표현의 의미

  1. "마크업 수준에서 표현한다"는 것은 상태가 JavaScript 변수 안에만 머무르지 않고 실제 DOM 속성으로 노출됨을 의미한다.

  2. 즉, 브라우저 개발자 도구에서 요소를 클릭하면 현재 상태가 그대로 보이는 상태가 된다.

  3. 상태가 마크업에 드러나 있기 때문에 CSS, 디버깅 도구, 테스트 코드가 모두 같은 정보원을 공유할 수 있다.

마크업 수준 표현의 장점

  1. 상태가 DOM에 드러나므로 DevTools에서 즉시 확인할 수 있어 디버깅이 쉽다.

  2. CSS 속성 선택자만으로 상태별 스타일을 적용할 수 있어, JS에서 클래스 문자열을 조립할 필요가 없다.

  3. 테스트 코드에서도 속성 기반으로 요소를 찾을 수 있어, 시각 상태와 검증 로직이 일치한다.

  4. 상태와 마크업이 같은 위치에 표현되어 선언적이며, 컴포넌트의 의도가 한눈에 드러난다.

마크업 수준 표현의 단점

  1. DOM 속성값은 항상 문자열로 변환되므로 boolean이나 숫자 같은 타입 정보가 손실된다.

    <button data-active={false} />
    // 실제 DOM: <button data-active="false">  (속성이 제거되지 않음)
  2. 따라서 CSS에서 [data-active]만 쓰면 "false" 상태에도 매칭되므로, [data-active="true"]처럼 값까지 명시해야 한다.

  3. 잦은 상태 변경이 있는 경우 DOM 속성 업데이트가 발생하므로, 메모리 변수만 갱신하는 것보다 미세하게 비용이 더 든다.

  4. 무분별하게 사용하면 DOM이 의미 없는 데이터 속성으로 지저분해지고, 마크업의 가독성이 떨어질 수 있다.