클릭 가능한 카드 패턴 및 안티패턴

발행: (2025년 12월 16일 오후 10:04 GMT+9)
4 min read
원문: Dev.to

Source: Dev.to

인터랙티브 요소 중첩 문제

  • HTML 사양 – 하이퍼링크(<a>href가 있음)는 인터랙티브 콘텐츠입니다. HTML Living Standard에 따르면, 인터랙티브 요소는 다른 인터랙티브하거나 포커스 가능한 요소를 자손으로 포함해서는 안 되며, 이는 <button>, <input> 또는 또 다른 <a>와 같은 요소를 하이퍼링크 안에 넣는 것을 금지합니다.
  • 보조 기술 문제 – 스크린 리더와 키보드 탐색 시 겹치는 클릭 영역을 가진 두 개의 다른 링크가 나타납니다. 탭 동작이 예측 불가능해지고, 스크린 리더가 읽어주는 링크 이름이 카드 전체 내용이 됩니다.

작성자: Jamil.

목표는 기본 링크(예: 카드 제목)를 보조 인터랙티브 요소와 분리하면서, CSS를 사용해 기본 링크의 클릭 영역을 카드 전체로 확장하는 것입니다. 내부 링크나 버튼은 스트레치된 링크 위에 배치되어 자체 인터랙션 우선순위를 유지합니다.

HTML 구조

<div class="card">
  <a href="/article/123" class="card__main-link">
    <h3>Article Title</h3>
  </a>

  <img src="thumbnail.jpg" alt="Article Thumbnail">

  <p>Author: <a href="/authors/jamil">Jamil</a>.</p>
</div>

핵심 CSS 속성

요소핵심 CSS 속성기능
.cardposition: relative;절대 위치 자식 요소를 위한 스태킹 컨텍스트를 설정합니다.
.card__main-link::aftercontent: ''; position: absolute; inset: 0; z-index: 1;보이지 않는 링크를 카드 전체에 늘려 기본 클릭 대상 역할을 하게 합니다.
내부 인터랙티브 요소(a, button)position: relative; z-index: 2;이 요소들을 스트레치된 링크 위로 올려 기능과 포커스 순서를 유지합니다.

CSS 구현

/* 1. 부모 요소 컨텍스트 */
.card {
  position: relative;
  /* 기타 스타일 (border, padding 등) */
}

/* 2. 스트레치된 클릭 영역 */
.card__main-link::after {
  content: '';
  position: absolute;
  inset: 0;               /* top: 0; right: 0; bottom: 0; left: 0; */
  z-index: 1;            /* 내부 인터랙티브 요소보다 낮음 */
  pointer-events: auto;  /* 영역이 클릭 가능하도록 함 */
}

/* 3. 내부 인터랙티브 요소 우선순위 */
.card p a,
.card button {
  position: relative;
  z-index: 2;            /* 스트레치된 클릭 영역 위에 배치 */
}

Stretched Link 패턴을 사용하면 디자인 의도(카드를 전체 클릭 가능하게 만들기)와 기술적 준수(중첩 인터랙티브 요소 회피) 사이의 충돌을 해결할 수 있습니다. 올바른 HTML 의미론을 유지하고 스태킹 컨텍스트를 관리함으로써, 개발자와 디자이너는 예측 가능한 사용자 경험을 제공하는 견고하고 완전하게 접근 가능한 컴포넌트를 만들 수 있습니다.

Photo by gabby‑k

Back to Blog

관련 글

더 보기 »

Ugly Sweater CSS: 드로이드

LEGO 스타워즈 어드벤트 캘린더 – CSS 어글리 스웨터 2020년부터 저는 LEGO 피규어 어글리 스웨터의 CSS‑art 버전을 만들고 있습니다. 이전 게시물을 볼 수 있습니다.