HTML details와 summary로 접근 가능한 FAQ 만들기

2026.09.06·수정 2026.09.14·약 22분·작성: 해비·블로그 소개

이 글에서 만드는 것

HTML의 details와 summary로 질문 세 개를 접고 펼치는 FAQ를 만듭니다. 구조는 index.html, 여백과 초점 표시는 styles.css에 나누어 작성합니다. 기본 동작을 브라우저에 맡기고 초기 상태와 키보드 조작을 직접 확인합니다.

목차

완성 결과와 실습 준비

흰 항목 세 개가 세로로 놓이고, 질문 왼쪽에는 브라우저 기본 열림 표시가 보입니다. 질문을 누르면 바로 아래 답변이 나타납니다. 항목에 name을 지정하지 않았으므로 첫 질문을 연 뒤 두 번째 질문을 열어도 첫 답변은 그대로 남습니다. 아래 확인 표의 빈 사각형은 기록용 표시이며 클릭하는 체크박스는 아닙니다.

HTML details와 summary로 접근 가능한 FAQ 만들기 핵심 개념 도식
summary는 질문, details 내부는 답변 영역입니다. 기본 HTML 요소로 펼침과 접힘을 제공합니다.

시작·완성 예제 ZIP 내려받기 — starter에는 질문 한 개가 있습니다. 두 질문을 추가하며 구조를 반복한 뒤 complete와 비교하세요.

텍스트 편집기와 브라우저를 준비하고 같은 폴더에 index.html, styles.css를 둡니다. HTML을 직접 열어 실행할 수 있으며 서버·빌드 도구·JavaScript는 필요하지 않습니다. 문서 뼈대가 낯설다면 HTML 시맨틱 문서와 폼 입문을 먼저 확인하세요.

1. 질문 하나를 먼저 만들기

details는 추가 정보를 접고 펼치는 영역입니다. 질문에 해당하는 summary를 첫 번째 자식으로 두고 그 뒤에 답변을 적습니다. 답변에는 문단뿐 아니라 목록이나 링크도 넣을 수 있습니다. 각 질문을 별도의 details로 묶어 어떤 질문이 어떤 답변을 여는지 분명하게 만드세요.

<details>
  <summary>HTML만으로 FAQ를 접고 펼칠 수 있나요?</summary>
  <p>네. 기본 접힘과 펼침은 details와 summary 요소로 구현할 수 있습니다.</p>
</details>

이 조각을 main 안에 넣어 한 질문의 동작부터 확인합니다. summary 글자를 클릭하면 연결된 답변이 나타나고 다시 클릭하면 사라집니다. 기본 상호작용이 있는 summary 안에 같은 동작을 하는 button을 또 넣거나, 별도 클릭 코드를 추가할 필요는 없습니다. 질문은 짧고 구체적으로 쓰고 답변의 핵심 정보를 질문 제목에만 의존하지 않도록 작성하세요.

2. open 속성과 독립된 열림 상태

<details open>
  <summary>처음부터 열어 둘 수도 있나요?</summary>
  <p>open 속성이 있으면 답변이 열린 상태로 시작합니다.</p>
</details>

open은 불리언 속성이므로 값의 문자열보다 속성의 존재가 중요합니다. open=”false”로 적어도 속성이 남아 있어 열린 상태입니다. 닫힌 상태로 시작하려면 open 속성을 제거하세요. 사용자가 조작할 때 브라우저가 이 열림 상태를 관리합니다. 이번 완성 예제는 세 항목 모두 open을 생략하여 닫힌 상태로 시작합니다.

WHATWG details 정의에는 같은 name을 가진 항목을 배타적 그룹으로 구성하는 방법도 나옵니다. 이 글에서는 여러 답변을 비교해 읽을 수 있도록 그룹을 만들지 않습니다. 한 번에 하나만 여는 동작과 여러 개를 동시에 여는 동작을 요구사항에 맞게 구분하세요.

3. CSS 파일에서 여백과 초점 표시하기

<link rel="stylesheet" href="styles.css">

link는 HTML의 head 안에 넣습니다. href는 현재 HTML 기준 상대 경로이므로 두 파일의 위치와 styles.css 철자를 맞춰야 합니다. FAQ 동작은 HTML이 담당하고 CSS는 화면 표현을 담당합니다. CSS 연결을 잠시 끊어도 질문을 여닫을 수 있어야 합니다.

details {
  padding: 16px 18px;
  border: 1px solid #cccccc;
  background: #fff;
}
summary:focus-visible {
  outline: 3px solid #333333;
  outline-offset: 3px;
}

항목 전체에는 사방 경계선을 적용하고, 키보드로 질문에 초점이 갈 때는 outline을 표시합니다. outline은 주변 내용을 밀어내는 박스 테두리와 다르므로 포커스가 생겨도 항목 크기를 바꾸지 않습니다. 브라우저 기본 삼각형 표시는 유지합니다. 표시를 지우고 새 아이콘을 만들기 전에 기본 상태가 충분히 전달되는지 확인하세요.

완성 코드: 두 파일을 같은 폴더에 저장하기

아래 두 블록은 complete 폴더의 파일 전체입니다. 먼저 starter에서 과제를 수행하고, 동작이나 계산이 다를 때 해당 선언을 비교하세요. HTML 안에 CSS를 붙여 넣지 않고 styles.css를 연결합니다.

index.html

실습 파일

파일 경로를 확인하고 같은 프로젝트 안에 저장하세요. 이미지 등 소스 목록에 없는 파일과 실행 안내는 실습 ZIP에 포함되어 있습니다.

시작본의 주석에 과제를 작성한 뒤 완성본과 비교하세요. 시작본은 질문이 하나뿐입니다. 완성본은 처음 닫힌 질문 세 개를 독립적으로 토글할 수 있습니다.

수정 전

index.html

<!doctype html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>자주 묻는 질문</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <main>
      <h1>자주 묻는 질문</h1>
      <p class="intro">
        아래 질문을 열어 HTML 기본 요소만으로 FAQ가 어떻게 접히고 펼쳐지는지 확인해
        보세요.
      </p>

      <section class="faq" aria-labelledby="faq-title">
        <h2 id="faq-title">FAQ</h2>

        <details>
          <summary>HTML만으로 FAQ를 접고 펼칠 수 있나요?</summary>
          <p>네. 기본 접힘과 펼침은 details와 summary 요소로 구현할 수 있습니다.</p>
        </details>

        <!-- 실습: 첫 질문을 참고해 summary 위치와 open 속성 질문 두 개를 추가하세요. -->
      </section>
      <table>
        <caption>
          FAQ 동작 확인 표
        </caption>
        <thead>
          <tr>
            <th scope="col">확인 항목</th>
            <th scope="col">확인 방법</th>
            <th scope="col">체크</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">질문 3개</th>
            <td>FAQ 영역에 details 항목이 3개 있는지 확인합니다.</td>
            <td>□</td>
          </tr>
          <tr>
            <th scope="row">접힘과 펼침</th>
            <td>각 summary를 눌러 답변이 열리고 닫히는지 확인합니다.</td>
            <td>□</td>
          </tr>
          <tr>
            <th scope="row">키보드 포커스</th>
            <td>키보드로 summary에 이동했을 때 테두리가 보이는지 확인합니다.</td>
            <td>□</td>
          </tr>
        </tbody>
      </table>
    </main>
  </body>
</html>

styles.css

body {
  margin: 0;
  font-family:
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    'Segoe UI',
    sans-serif;
  line-height: 1.6;
  color: #222;
  background: #f7f7f7;
}

main {
  max-width: 760px;
  margin: 0 auto;
  padding: 40px 20px;
}

.intro {
  margin-bottom: 28px;
}

.faq {
  display: grid;
  gap: 12px;
  margin: 28px 0;
}

details {
  padding: 16px 18px;
  border: 1px solid #cccccc;
  background: #fff;
}

summary {
  cursor: pointer;
  font-weight: 700;
}

summary:focus-visible {
  outline: 3px solid #333333;
  outline-offset: 3px;
}

details p {
  margin: 12px 0 0;
}

table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 28px;
  background: #fff;
}

th,
td {
  padding: 12px;
  border: 1px solid #cccccc;
  text-align: left;
  vertical-align: top;
}

th {
  background: #eeeeee;
}

수정 방법

index.html

수정 위치: 첫 번째 details 다음의 실습 주석을 확인하세요.

이유: 각 FAQ 항목은 details의 첫 자식으로 summary를 두어야 키보드로 질문을 열고 닫을 수 있습니다. boolean open 속성은 값이 아니라 존재 여부로 열림을 결정합니다.

재현과 기대 결과: 시작본은 질문이 하나뿐입니다. 완성본은 처음 닫힌 질문 세 개를 독립적으로 토글할 수 있습니다.

index.html에서 아래 차이가 있는 위치를 수정하세요. -는 삭제할 줄, +는 추가할 줄이며 표시는 실제 코드에 넣지 않습니다.

본문의 확인 절차로 변경 결과를 확인합니다.

--- 수정 전/index.html
+++ 수정 후/index.html
@@ -22,8 +22,22 @@
           <p>네. 기본 접힘과 펼침은 details와 summary 요소로 구현할 수 있습니다.</p>
         </details>
 
-        <!-- 실습: 첫 질문을 참고해 summary 위치와 open 속성 질문 두 개를 추가하세요. -->
+        <details>
+          <summary>summary는 어디에 써야 하나요?</summary>
+          <p>
+            summary는 details의 첫 번째 자식으로 두어야 하며, 접힘 영역의 제목 역할을
+            합니다.
+          </p>
+        </details>
+
+        <details>
+          <summary>처음부터 열어 둘 수도 있나요?</summary>
+          <p>
+            네. 처음부터 펼친 상태가 필요하면 details에 open 속성을 추가할 수 있습니다.
+          </p>
+        </details>
       </section>
+
       <table>
         <caption>
           FAQ 동작 확인 표

수정 후 탭의 전체 파일과 비교한 뒤 본문의 확인 절차를 실행하세요.

styles.css

이 파일은 변경하지 않습니다. 다른 파일을 수정하는 동안 기존 내용을 유지하세요.

수정 후

index.html

<!doctype html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>자주 묻는 질문</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <main>
      <h1>자주 묻는 질문</h1>
      <p class="intro">
        아래 질문을 열어 HTML 기본 요소만으로 FAQ가 어떻게 접히고 펼쳐지는지 확인해
        보세요.
      </p>

      <section class="faq" aria-labelledby="faq-title">
        <h2 id="faq-title">FAQ</h2>

        <details>
          <summary>HTML만으로 FAQ를 접고 펼칠 수 있나요?</summary>
          <p>네. 기본 접힘과 펼침은 details와 summary 요소로 구현할 수 있습니다.</p>
        </details>

        <details>
          <summary>summary는 어디에 써야 하나요?</summary>
          <p>
            summary는 details의 첫 번째 자식으로 두어야 하며, 접힘 영역의 제목 역할을
            합니다.
          </p>
        </details>

        <details>
          <summary>처음부터 열어 둘 수도 있나요?</summary>
          <p>
            네. 처음부터 펼친 상태가 필요하면 details에 open 속성을 추가할 수 있습니다.
          </p>
        </details>
      </section>

      <table>
        <caption>
          FAQ 동작 확인 표
        </caption>
        <thead>
          <tr>
            <th scope="col">확인 항목</th>
            <th scope="col">확인 방법</th>
            <th scope="col">체크</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">질문 3개</th>
            <td>FAQ 영역에 details 항목이 3개 있는지 확인합니다.</td>
            <td>□</td>
          </tr>
          <tr>
            <th scope="row">접힘과 펼침</th>
            <td>각 summary를 눌러 답변이 열리고 닫히는지 확인합니다.</td>
            <td>□</td>
          </tr>
          <tr>
            <th scope="row">키보드 포커스</th>
            <td>키보드로 summary에 이동했을 때 테두리가 보이는지 확인합니다.</td>
            <td>□</td>
          </tr>
        </tbody>
      </table>
    </main>
  </body>
</html>

styles.css

body {
  margin: 0;
  font-family:
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    'Segoe UI',
    sans-serif;
  line-height: 1.6;
  color: #222;
  background: #f7f7f7;
}

main {
  max-width: 760px;
  margin: 0 auto;
  padding: 40px 20px;
}

.intro {
  margin-bottom: 28px;
}

.faq {
  display: grid;
  gap: 12px;
  margin: 28px 0;
}

details {
  padding: 16px 18px;
  border: 1px solid #cccccc;
  background: #fff;
}

summary {
  cursor: pointer;
  font-weight: 700;
}

summary:focus-visible {
  outline: 3px solid #333333;
  outline-offset: 3px;
}

details p {
  margin: 12px 0 0;
}

table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 28px;
  background: #fff;
}

th,
td {
  padding: 12px;
  border: 1px solid #cccccc;
  text-align: left;
  vertical-align: top;
}

th {
  background: #eeeeee;
}

index.html 전체 코드 보기

styles.css

styles.css 전체 코드 보기

5. 클릭·키보드·좁은 화면 확인하기

먼저 파일을 새로 열어 답변 세 개가 닫혀 있는지 확인합니다. 첫 질문을 클릭해 열고 두 번째 질문도 여세요. 두 답변이 함께 보이면 독립된 항목 구성이 맞습니다. 다시 클릭하면 해당 답변만 닫혀야 합니다.

다음에는 마우스를 놓고 Tab으로 summary에 이동합니다. 초점 외곽선이 보이는 상태에서 Enter 또는 Space를 눌러 답변을 열고 다시 닫아 보세요. Tab을 계속 눌렀을 때 다음 질문으로 이동하는지도 확인합니다. 브라우저와 보조기술 조합에 따라 읽기 안내가 달라질 수 있으므로 실제 사용할 환경에서도 질문 이름과 펼침 상태가 전달되는지 확인하세요.

브라우저를 320px 너비로 줄이고 200% 확대도 적용합니다. 긴 질문과 답변이 잘리거나 확인 표 때문에 전체 페이지에 가로 스크롤이 생기지 않는지 봅니다. 글이 늘어날 수 있으므로 details에 고정 높이를 넣지 않습니다. 표의 scope=”col”은 열 제목, scope=”row”는 행 제목을 구분합니다.

6. 자주 막히는 지점

증상 먼저 볼 부분 수정 후 확인
질문을 눌러도 원하는 답변이 안 열립니다. summary가 해당 details 안의 첫 자식인지 확인합니다. 질문 하나만 남겨 열기·닫기를 확인한 뒤 항목을 다시 추가합니다.
처음부터 답변이 열려 있습니다. open 또는 open=”false”가 남아 있는지 확인합니다. 속성을 완전히 지우고 파일을 다시 엽니다.
모양이 기본 스타일로 보입니다. link 경로와 CSS 파일명을 확인합니다. 여백과 회색 경계선이 적용되는지 봅니다.
여러 답변이 동시에 보입니다. 이 예제는 독립된 FAQ 항목입니다. 오류가 아니므로 필요한 답변을 각각 닫습니다.
표의 □를 눌러도 변하지 않습니다. 빈 사각형은 기록용 문자입니다. 동작은 질문에서 확인하고 결과를 별도로 기록합니다.

starter 과제와 다음 학습

  1. 기본 예제의 첫 질문을 참고해 summary 위치와 open 속성을 설명하는 질문 두 개를 추가하세요.
  2. 첫 details에 open을 추가해 초기 상태를 확인하고, open=”false”로 바꾼 뒤에도 열리는지 확인하세요. 최종 파일에서는 open을 제거하세요.
  3. Tab으로 세 질문을 이동하며 Enter 또는 Space로 각각 두 번 토글하세요. 여러 질문을 함께 열어 독립 동작을 확인하세요.

기본 동작을 익혔다면 답변에 목록을 추가하거나 질문을 늘려 보세요. 검색 필터링이나 마지막으로 연 항목을 저장하는 기능은 별도 상태 관리가 필요하므로 다음 단계로 분리합니다. CSS의 적용 원리를 더 익히려면 박스 모델·선택자·캐스케이드 실습에서 파일 연결과 최종 스타일 확인을 이어가세요.

이 글이 도움이 되었나요?

조회 중

웹 퍼블리싱 학습 순서

필수 13개 · 전체 15개

읽음 기록 관리

전체 과정 목차 (15개)
  1. 필수 학습 · HTML 입문: 시맨틱 문서와 접근 가능한 폼 만들기
  2. 필수 학습 · CSS 입문: 박스 모델·선택자·캐스케이드 직접 확인하기
  3. 필수 학습 · CSS Flex와 미디어 쿼리 입문: 반응형 카드 페이지 만들기
  4. 필수 학습 · CSS position 완전 이해: relative·absolute·fixed·sticky 실습
  5. 필수 학습 · HTML details와 summary로 접근 가능한 FAQ 만들기 현재 글
  6. 필수 학습 · CSS Grid 실습: Flex 학습 카드로 열 맞추기와 auto-fit 비교
  7. 필수 학습 · CSS overflow 해결: 긴 텍스트·min-width: 0·말줄임 실습
  8. 필수 학습 · HTML 표 만들기: caption·scope로 비교표를 읽기 쉽게, 모바일에서는 표만 스크롤하기
  9. 필수 선수 · HTML CSS 이미지 문제 해결 실습: 경로·비율·잘림·흐림·CLS
  10. 필수 학습 · Container Query 실습: 같은 카드를 본문과 사이드바에 배치하기
  11. 선택 참고 · CSS Baseline 보는 법: 지원 범위와 폴백을 직접 확인하기
  12. 필수 학습 · CSS z-index가 안 먹힐 때: stacking context와 부모 층 디버깅
  13. 필수 선수 · 웹 접근성 기초 점검: 키보드 순서·초점 표시·확대 화면을 직접 확인하는 체크리스트
  14. 필수 학습 · HTML CSS 종합 실습: 소개·카드·이미지·요금표·문의 폼·FAQ가 있는 반응형 서비스 페이지
  15. 선택 참고 · 프론트엔드 SEO 기초: HTML 구조와 이미지 성능 진단하기

새 글 받아보기

RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.

RSS 피드 구독하기

댓글 남기기