Dev Thinking
21완료

접근성 – 시맨틱 HTML, 자동 검사

2025-09-29
5분 읽기

공식문서 기반의 Next.js 입문기

들어가며

4-3편에서는 에러 핸들링을 통해 견고한 앱을 만들었습니다. notFound()error.tsx로 실패 시점을 포착하고 사용자 복구를 안내하는 패턴을 완성했죠. 이번에는 이 앱을 누구나 불편함 없이 사용할 수 있게 하는 접근성을 다룹니다.

접근성은 시각 장애인, 마우스나 터치가 어려운 사용자, 일시적인 부상자, 나이가 많은 사용자까지 고려합니다. 스크린 리더 사용자에겐 콘텐츠 구조가, 키보드 사용자에겐 포커스 관리가, 저시력 사용자에겐 색상 대비가 필수적입니다. 이런 고려는 비장애인에게도 더 큰 터치 타겟이나 명확한 레이블로 이어져 모두에게 도움이 됩니다.

Next.js에서는 접근성을 기본 사양으로 만듭니다. 시맨틱 HTML로 기계가 콘텐츠를 이해하게 하고, 자동 검사로 개발 단계에서 품질을 유지합니다. 인보이스 생성 폼을 기준으로 접근성 원칙을 적용하고 자동 검사로 품질을 유지하는 패턴을 살펴보겠습니다.

접근성 – 시맨틱 HTML과 자동 검사 원칙

Next.js에서는 접근성을 기본 사양으로 만듭니다. 시맨틱 HTML로 기계가 콘텐츠를 이해하게 하고, 자동 검사로 개발 단계에서 품질을 유지합니다.

접근성이 왜 중요한지 생각해보겠습니다. 웹 앱은 기계가 읽을 수 있어야 합니다. 스크린 리더나 키보드 내비게이션이 HTML 구조를 이해하고 사용자에게 전달할 수 있어야 합니다.

시맨틱 HTML의 실행 방식

시맨틱 HTML은 의미 있는 태그 사용을 의미합니다. <div> 대신 <button>, <span> 대신 <label>을 써서 기계가 콘텐츠의 목적을 파악하게 하는 전략입니다.

Next.js의 기본 컴포넌트들은 시맨틱 태그를 우선합니다. next/image는 자동으로 alt 속성을 강제하고, 폼 요소는 의미 있는 태그를 사용하도록 유도합니다. 기본 HTML로는 표현하기 어려운 상황에서 ARIA 속성을 보완적으로 사용합니다.

이 구조가 중요한 이유는 접근성이 개발자의 선택이 아닌 기본 사양이 되게 하기 때문입니다. 시맨틱 HTML을 사용하면 자연스럽게 더 많은 사용자를 만날 수 있습니다.

기능 구현 및 비교

인보이스 생성 폼을 기준으로, 리액트에서 접근성을 처리하는 한계를 먼저 보여드린 뒤 Next.js로 동일한 목표를 구현해보겠습니다.

리액트 단독 구성 – 수동 접근성 관리

CSR에서는 접근성 구현이 수동적입니다. 시맨틱 태그를 직접 사용하고 ARIA 속성을 추가해야 합니다.

export function InvoiceForm() {
  // 상태 관리 생략
  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="customerName">
        고객명
        <input
          id="customerName"
          name="customerName"
          type="text"
          aria-describedby="customerName-error"
        />
      </label>
      {errors.customerName && (
        <div id="customerName-error" role="alert" aria-live="polite">
          {errors.customerName}
        </div>
      )}
      <button type="submit">생성하기</button>
    </form>
  );
}

리액트 방식의 한계

CSR에서 접근성 구현은 자동 검사가 없어 실수가 누적됩니다. 매번 수동으로 테스트해야 하고, 접근성 라이브러리도 직접 설정해야 합니다. 이런 한계는 접근성 검증이 개발자의 의지에 달려 있어 일관된 품질을 유지하기 어렵게 만듭니다.

Next.js 구성 – 시맨틱 HTML + 자동 검사

Next.js에서는 시맨틱 HTML과 자동 검사를 기본으로 제공합니다. 핵심은 서버 액션과 useActionState로 접근성 있는 에러 표시를 자동화하는 점입니다.

// app/invoices/components/InvoiceForm.tsx
"use client";
 
import { useActionState } from "react";
 
export function InvoiceForm({ action }: InvoiceFormProps) {
  const [state, formAction] = useActionState(action, {});
 
  return (
    <form action={formAction}>
      <label htmlFor="customerName">
        고객명
        <input
          id="customerName"
          name="customerName"
          type="text"
          aria-describedby="customerName-error"
        />
      </label>
      {state.errors?.customerName && (
        <div id="customerName-error" role="alert" aria-live="polite">
          {state.errors.customerName}
        </div>
      )}
      <button type="submit">생성하기</button>
    </form>
  );
}

Next.js에서는 eslint-plugin-jsx-a11y가 기본 포함되어 npx next lint로 접근성 문제를 자동 검사합니다. CSR에서는 수동적이었던 접근성 관리가 Next.js에서는 기본 사양으로 강제됩니다.

리액트 vs Next.js 비교표

구분리액트 (CSR + 수동 접근성)Next.js (서버/클라이언트 + 자동 검사)
실행 환경 기본값접근성 검사가 수동, 외부 도구 필요eslint-plugin-jsx-a11y 자동 적용, 빌드 시 검사
데이터 접근 모델클라이언트에서 검증 + 수동 에러 관리서버 액션에서 검증 → useActionState로 에러 전달
번들 관점접근성 라이브러리가 번들에 포함Next.js 기본 기능, 추가 번들 영향 최소
컴포넌트 분리 의미접근성 로직이 비즈니스 로직과 결합서버 액션(검증) + 클라이언트 컴포넌트(UI) 분리
설계의 제약접근성 품질이 개발자 역량에 달려시맨틱 HTML + 자동 검사가 기본 사양으로 강제

참고: 접근성은 Next.js의 "포용적 기본 사양" 전략입니다. 시맨틱 HTML을 사용하면 스크린 리더가 자연스럽게 콘텐츠를 이해하고, 자동 검사가 개발 단계에서 문제를 찾아줍니다.

접근성 구현의 트레이드오프

장점

  • 사용자 범위 확대: 시각/운동/인지 장애가 있는 사용자도 앱을 사용할 수 있어 포용적 서비스 제공
  • SEO 개선: 시맨틱 HTML로 검색 엔진이 콘텐츠를 더 잘 이해하여 검색 순위 상승
  • 법적/윤리적 준수: WCAG 가이드라인 준수로 법적 요구사항 충족 및 사회적 책임 이행

단점

  • 개발 복잡성 증가: ARIA 속성 과도 사용, 키보드 내비게이션 고려 등 추가 구현 부담
  • 검사 시점 놓침: 개발 후반에 접근성 검사를 하면 수정 비용이 기하급수적으로 증가
  • 완벽주의 함정: 100% 접근성 달성이 비현실적이라 적절한 수준 설정의 어려움

균형 맞추기 팁

시맨틱 HTML을 기본으로 사용하고 ARIA는 필요한 경우에만 보완하세요. ESLint 규칙을 개발 초기부터 적용하여 지속적인 검사를 수행하고, WCAG 2.1 AA 수준을 목표로 하되 비즈니스 요구사항과 균형을 맞추세요.

예상 질문

Q. 시맨틱 HTML만으로 충분한가? 충분하지 않습니다. 시맨틱 HTML은 기초이고, ARIA 속성과 키보드 내비게이션이 함께 필요합니다. 하지만 시맨틱 HTML이 없으면 다른 접근성 기법도 효과가 떨어집니다.

Q. Next.js에서 접근성 검사는 어떻게 실행하나? npx next lint 명령으로 실행합니다. eslint-plugin-jsx-a11y가 기본 포함되어 있어 img-alt, label-has-associated-control 같은 규칙을 자동으로 검사합니다.

Q. 서버 액션 에러를 접근성 있게 표시하려면? useActionState로 에러를 받아 aria-live="polite" 속성과 함께 표시하세요. role="alert"와 결합하면 스크린 리더가 에러 메시지를 즉시 읽을 수 있습니다.

Q. 색각 이상 사용자를 고려해야 하나? 네, 필수적입니다. 색상만으로 정보를 전달하지 말고 텍스트나 아이콘을 함께 사용하세요.

Q. 접근성 테스트는 어떻게 하나? ESLint로 기본 검사를 하고, Lighthouse로 종합 점수를 측정하며, 실제 스크린 리더로 테스트하세요.

Q. 접근성을 나중에 추가할 수 있나? 어렵습니다. 처음부터 접근성을 고려한 설계가 효율적입니다.

요약

4-3편의 에러 핸들링을 기반으로, 시맨틱 HTML과 자동 검사로 포용적인 UI를 설계하는 접근성 패턴을 다루었습니다. CSR에서는 접근성 검증이 수동적이었지만, Next.js에서는 eslint-plugin-jsx-a11y로 자동화됩니다.

핵심은 접근성을 기본 사양으로 만드는 전략입니다. 시맨틱 태그 사용과 npx next lint로 개발 단계에서 품질을 유지합니다.

  • 포용성 향상: 모든 사용자가 동일한 경험 가능
  • 개발 효율: 자동 검사로 실수 최소화
  • SEO 이점: 시맨틱 HTML이 검색 엔진 이해도 높임

참조