반복되는 각 심벌에 접근 가능한 이름이 있는 자체 외부 SVG를 지정하고, 내부 그림만 재사용하세요. 이 가이드에서는 Mac에서 레이블이 있는 작은 그래픽 목록을 만들고, 페이지 레이아웃, SVG 좌표, 접근 가능한 이름 지정을 서로 분리하는 방법을 보여 줍니다.
간단한 그래픽의 경우 MDN은 보조 기술이 하나의 이미지로 취급할 수 있도록 바깥쪽 SVG에 role="img"와 레이블을 넣을 것을 권장합니다. 여기서 사용하는 실용적인 패턴은 각 발생 항목마다 하나의 래퍼를 두고, 각 래퍼가 고유한 레이블을 참조하게 하는 것입니다. ARIA: img 역할
각 인스턴스의 접근성 레이블은 어디에 넣어야 하나요?
특정 발생 항목을 나타내는 요소에 이름을 지정하세요. 여러 개의 개별 그래픽이 하나의 심벌을 재사용한다면, 각 외부 svg에 고유한 aria-labelledby 참조 또는 aria-label을 지정하세요. 공유 심벌은 재사용 가능한 도형에만 집중하도록 하세요.
이는 정의와 렌더링된 인스턴스의 차이를 따릅니다. SVG use 요소는 그래픽을 참조하고 섀도 트리를 통해 재사용된 콘텐츠를 렌더링합니다. 이렇게 생성된 도형은 페이지 DOM의 일반적인 자식 노드가 아닙니다. 따라서 그림을 재사용해도 HTML 내부 레이블의 개별 편집 가능한 복사본이 만들어지지는 않습니다. 문서 구조 — SVG 2
공유 심벌 내부에 저장된 제목도 별도의 이름 지정 메커니즘 없이는 각 발생 항목에 서로 다른 텍스트를 제공할 수 없습니다. 예를 들어 같은 중립적인 타일 그림이 한 곳에서는 Sample Alpha, 다른 곳에서는 Sample Beta를 나타낼 수 있습니다. 도형이 같더라도 두 이름은 각각의 발생 항목에 지정해야 합니다.
유용한 텍스트가 이미 어디에 있는지에 따라 이름 지정 방법을 선택하세요.
| 상황 | 권장 패턴 |
|---|---|
| 간결한 표시 캡션이 그래픽의 이름을 나타냄 | 외부 SVG에 aria-labelledby를 사용해 해당 캡션의 고유 ID를 참조합니다. |
| 그래픽에 이름이 필요하지만 표시 캡션이 없음 | 각 외부 SVG 안에 고유한 title을 넣고 aria-labelledby로 참조하거나 aria-label을 사용합니다. |
| 그래픽이 이미 모든 의미를 전달하는 텍스트를 장식할 뿐임 | 중복 이름을 추가하지 말고 보조 기술에서 SVG를 숨깁니다. |
| 여러 발생 항목을 각각 발견할 수 있어야 함 | 모두를 하나의 외부 role="img" 이미지로 묶지 않습니다. |
MDN은 표시 텍스트로 SVG의 이름을 지정할 수 있다면 이를 참조할 것을 권장합니다. 이미지 역할 문서에서는 role="img"가 콘텐츠를 하나의 개체로 제시한다고 설명합니다. 따라서 래퍼의 경계가 중요합니다. SVG 접근성 이름 요소, ARIA: img 역할
독립적으로 이름이 지정된 인스턴스 두 개가 있는 전체 페이지 만들기
다음 예제는 합성 텍스트와 단순한 원 및 사각형 그림만 포함하는 완전한 HTML 문서입니다. JavaScript, 외부 스프라이트, 라이브러리 또는 빌드 과정이 필요하지 않습니다. Mac에서 일반 텍스트 코드 편집기로 symbol-labels.html 파일에 저장한 다음 데스크톱 브라우저에서 여세요.
두 발생 항목은 모두 tile-mark를 참조하지만, 각 외부 SVG는 서로 다른 표시 캡션을 참조합니다. 이는 MDN이 문서화한 표시 텍스트 이름 지정 패턴을 사용합니다. href 속성은 현재 SVG 참조 방식이며, MDN은 xlink:href를 더 이상 사용하지 않는 방식으로 문서화합니다. SVG 접근성 이름 요소, SVG use 요소
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Independently labeled SVG instances</title>
<style>
body {
margin: 2rem;
font-family: system-ui, sans-serif;
color: #222;
}
.sprite {
position: absolute;
width: 0;
height: 0;
overflow: hidden;
}
.samples {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 1rem;
max-width: 36rem;
padding: 0;
list-style: none;
}
.sample {
padding: 1rem;
border: 1px solid #777;
}
.sample svg {
display: block;
width: 5rem;
height: 5rem;
margin-bottom: 0.75rem;
}
@media (max-width: 30rem) {
.samples { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<svg class="sprite" xmlns="http://www.w3.org/2000/svg"
aria-hidden="true">
<defs>
<symbol id="tile-mark" viewBox="0 0 48 48">
<rect x="4" y="4" width="40" height="40" rx="6"
fill="none" stroke="currentColor" stroke-width="2" />
<circle cx="24" cy="24" r="9" fill="currentColor" />
</symbol>
</defs>
</svg>
<h1>Sample tiles</h1>
<ul class="samples">
<li class="sample">
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 48 48" role="img"
aria-labelledby="sample-alpha-label">
<use href="#tile-mark" width="48" height="48"
aria-hidden="true" />
</svg>
<span id="sample-alpha-label">Sample Alpha</span>
</li>
<li class="sample">
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 48 48" role="img"
aria-labelledby="sample-beta-label">
<use href="#tile-mark" width="48" height="48"
aria-hidden="true" />
</svg>
<span id="sample-beta-label">Sample Beta</span>
</li>
</ul>
</body>
</html>
의도한 접근 가능한 이름은 Sample Alpha와 Sample Beta입니다. 이는 마크업으로부터 예상되는 결과이며, 브라우저 테스트 결과를 보고하는 것이 아닙니다. 각 래퍼 안의 그림은 보조 기술에서 명시적으로 숨기며, 이름이 지정된 외부 SVG는 계속 노출됩니다. SVG 접근성 매핑은 숨겨진 하위 요소와 노출되는 상위 요소를 구분합니다. SVG 접근성 API 매핑
세 번째 발생 항목을 추가할 때는 href="#tile-mark"를 재사용하고, 새 캡션 ID를 만들고, 해당 항목의 aria-labelledby를 그 ID에 맞게 업데이트하세요. 심벌 참조는 공유하고 레이블 참조는 각 발생 항목에 맞게 지정하세요.
화면 읽기 프로그램을 사용해 읽을 때 표시 캡션을 별도로 만날 수도 있습니다. 타일이 캡션 외에 아무 정보도 더하지 않는다면 장식용 패턴을 사용하세요. 외부 SVG에서 role="img"과 aria-labelledby을 제거한 다음 aria-hidden="true"을 지정하면 됩니다. 표시 캡션은 그대로 둡니다. SVG 매핑은 aria-hidden를 통한 제외 방법을 문서화합니다. SVG 접근성 API 매핑
각 레이아웃 부분은 어떤 브라우저 메커니즘으로 제어하나요?
이 예제에는 카드 배치, 심벌 그리기, 접근 가능한 이름 계산이라는 세 가지 별도의 작업이 있습니다. 하나를 바꿔도 나머지 작업이 자동으로 수행되지는 않습니다.
CSS Grid는 HTML 목록 항목을 배치합니다. display: grid를 선언하면 컨테이너의 직계 자식이 그리드 항목이 되고, grid-template-columns가 열을 정의합니다. 여기서는 미디어 쿼리가 목록을 두 열에서 한 열로 바꿉니다. 이는 카드의 페이지 레이아웃에 영향을 줍니다. 그리드 레이아웃의 기본 개념
SVG 좌표는 각 그래픽 안의 도형을 제어합니다. 심벌의 viewBox="0 0 48 48"은 좌표 사각형을 설정하고, use 요소의 크기는 참조된 심벌 뷰포트의 크기를 정합니다. 이 크기는 HTML 카드 열이나 캡션 간격을 만들지 않습니다. SVG 2는 재사용 그래픽의 레이아웃과 CSS 박스 레이아웃을 명시적으로 구분합니다. 문서 구조 — SVG 2
접근 가능한 이름 지정은 aria-labelledby을 통해 각 외부 SVG를 텍스트와 연결합니다. 이 속성은 텍스트를 그리거나, 캡션을 배치하거나, 그래픽 크기를 조정하지 않습니다. W3C의 이름 지정 지침에서는 이 속성을 접근 가능한 이름을 계산하는 데 사용되는 콘텐츠 참조로 설명합니다. 접근 가능한 이름 및 설명 제공
이렇게 구분하면 유용한 진단 원칙을 세울 수 있습니다. 카드 위치가 잘못되면 Grid를, 그림 위치가 잘못되면 SVG 좌표를, 레이블이 잘못되면 이름 참조를 살펴보세요. x 또는 y를 use에 추가하면 재사용된 그래픽이 SVG 공간 안에서 오프셋됩니다. HTML 캡션은 이동하지 않습니다. 또한 use 크기는 임의의 참조 도형을 확대하는 일반적인 대체 수단이 아닙니다. MDN은 viewBox이 있는 SVG 또는 심벌을 참조할 때 해당 크기가 미치는 효과를 문서화합니다. SVG use 요소
표시 캡션이 없으면 어떻게 하나요?
그래픽에 이름이 필요하지만 디자인에 적절한 표시 텍스트가 없다면 인스턴스별 제목을 사용하세요. 다음은 전체 예제에서 첫 번째 표시 SVG를 대체하는 조각입니다. 기존 tile-mark 심벌을 계속 사용합니다.
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 48 48" role="img"
aria-labelledby="sample-alpha-title">
<title id="sample-alpha-title">Sample Alpha</title>
<use href="#tile-mark" width="48" height="48"
aria-hidden="true" />
</svg>
추가로 각 발생 항목을 만들 때 제목에 다른 ID를 지정하고 상위 요소의 참조를 업데이트하세요. MDN은 title를 SVG 접근성 이름 요소로 문서화하며, SVG 1.1과의 호환성을 위해 이를 첫 번째에 배치할 것을 권장합니다. 제목 텍스트는 그림의 일부로 시각적으로 렌더링되지 않지만, 브라우저는 보통 이를 툴팁으로 표시합니다. SVG 접근성 이름 요소
제목 요소 없이 짧은 이름을 지정하려면 해당 인스턴스의 외부 SVG에서 aria-labelledby을 aria-label="Sample Alpha"로 바꾸세요. 우선순위가 겹치는 이름 지정 속성을 남기지 마세요. W3C는 aria-labelledby이 aria-label보다 우선한다고 문서화합니다. 따라서 참조를 남겨 두면 새 문자열이 이름이 되지 않을 수 있습니다. 접근 가능한 이름 및 설명 제공
생성된 복제본을 수정해 특정 발생 항목의 제목을 지정하려 하지 마세요. SVG 2는 읽기 전용 인스턴스 섀도 트리를 규정합니다. 현재 SVG 접근성 API 매핑 작업 초안도 ARIA ID 참조가 use 섀도 트리 안의 요소와 일치하는 것을 제한합니다. 이는 문서화된 경계이며, 모든 브라우저가 동일한 방식으로 동작한다는 증거는 아닙니다. 작성된 래퍼에 레이블을 두면 복제본 내 검색에 의존하지 않아도 됩니다. 문서 구조 — SVG 2, SVG 접근성 API 매핑
결과를 확인하고 문제를 해결하려면 어떻게 하나요?
Mac 브라우저에서 표시 결과와 접근 가능한 이름을 각각 확인하세요. 브라우저의 접근성 도구에서 각 외부 SVG를 검사한 다음 VoiceOver로 확인하세요. W3C는 aria-labelledby로 계산된 이름을 보조 기술로 테스트할 것을 구체적으로 권장합니다. 접근 가능한 이름 및 설명 제공
다음 예상 결과를 간단한 승인 체크리스트로 사용하세요.
- 두 그림이 각자의 표시 캡션과 함께 나타납니다.
- 각 외부 SVG에 이미지 역할과 해당 이름이 있습니다.
- 심벌 정의가 의미 있는 추가 그래픽으로 나타나지 않습니다.
- 창 너비를 좁히면 카드 배치가 바뀌고 각 그래픽은 레이블을 유지합니다.
- 두 번째 캡션만 바꾸면 두 번째 그래픽의 계산된 이름만 바뀝니다.
두 그래픽에 같은 이름이 지정되면 먼저 각 그래픽의 aria-labelledby 값을 비교하세요. 그런 다음 각 참조 ID가 의도한 텍스트를 식별하는지 확인하세요. 시각적으로 가까이 있다는 이유로 연결 관계가 성립한다고 가정하지 마세요. 이 속성은 요소를 ID로 명시적으로 참조합니다. 접근 가능한 이름 및 설명 제공
여러 개의 독립된 이미지가 필요한데 전체 그림이 하나의 이미지로 안내된다면 role="img"이 어디에 있는지 살펴보세요. 전체 모음 주위에 이미지 역할 하나를 지정하면 보조 기술은 해당 모음을 하나의 개체로 취급합니다. 각각의 간단한 그래픽에 별도의 이미지 래퍼를 유지하세요. ARIA: img 역할
실제로 HTML img를 통해 SVG 파일을 삽입하고 있다면 각 발생 항목에 해당 요소의 alt 속성을 사용하세요. WHATWG는 alt을 이미지의 동등한 대체 콘텐츠로 정의합니다. 인라인 SVG는 다른 이름 지정 메커니즘을 사용하며, 대체 텍스트 속성으로 alt을 지원하지 않습니다. HTML 표준: img 요소, HTML에서의 SVG 소개
이 레이아웃 작업에서는 그림 정의 하나를 공유하고 각 발생 항목마다 이름을 결정하세요. 독자가 접해야 하는 내용에 맞춰 래퍼를 선택하고, 적절한 텍스트와 연결한 다음, 시각적 레이아웃과 별개로 결과 접근 가능 이름을 확인하세요.
출처
- 문서 구조 — SVG 2 — W3C.
- SVG 접근성 API 매핑 — W3C.
- 접근 가능한 이름 및 설명 제공 — W3C.
- HTML 표준: img 요소 — WHATWG.
- SVG use 요소 — MDN Web Docs.
- SVG 접근성 이름 요소 — MDN Web Docs.
- ARIA: img 역할 — MDN Web Docs.
- 그리드 레이아웃의 기본 개념 — MDN Web Docs.
- HTML에서의 SVG 소개 — MDN Web Docs.