시각적으로 숨기기

Visually Hidden

화면에는 안 보이지만 스크린 리더에는 그대로 읽히도록 요소를 숨기는 CSS 기법. display:none과는 전혀 다릅니다.

다른 이름: .sr-onlyscreen-reader-only text
···
html
<div class="stage">
  <div class="pane">
    <div class="tag">display: none</div>
    <button class="sb"><span class="glass"></span></button>
    <div class="eye ok">눈: 안 보임</div>
    <div class="ear bad">SR: (없음)</div>
  </div>
  <div class="pane">
    <div class="tag">visibility: hidden</div>
    <button class="sb"><span class="glass"></span><span class="ghost">Search</span></button>
    <div class="eye ok">눈: 안 보임</div>
    <div class="ear bad">SR: (없음)</div>
  </div>
  <div class="pane">
    <div class="tag">.sr-only</div>
    <button class="sb"><span class="glass"></span></button>
    <div class="eye ok">눈: 안 보임</div>
    <div class="ear good">SR: "Search"</div>
  </div>
</div>
css
.stage{width:96%;height:90%;display:flex;gap:3%}
.pane{position:relative;flex:1;border-radius:12px;border:1px solid var(--line);background:var(--surface);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8%;padding:16% 4% 6%}
.tag{position:absolute;top:8px;left:8px;right:8px;font:700 9px/1.2 ui-monospace,monospace;color:var(--muted);text-align:center}
.sb{width:30%;aspect-ratio:1;border-radius:9px;border:1px solid var(--line);background:var(--bg);display:grid;place-items:center;position:relative}
.glass{width:44%;height:44%;border:2px solid var(--fg);border-radius:50%;position:relative}
.glass::after{content:'';position:absolute;width:6px;height:2px;background:var(--fg);right:-5px;bottom:-1px;transform:rotate(45deg)}
.ghost{position:absolute;visibility:hidden;font-size:8px}
.eye,.ear{font:700 9.5px/1.2 ui-monospace,monospace;text-align:center}
.eye.ok{color:var(--muted)}
.ear.bad{color:var(--accent-2)}
.ear.good{color:var(--accent-3)}

`display: none`과 `visibility: hidden`은 요소를 접근성 트리에서도 지워버려서 스크린 리더가 아예 존재를 모릅니다. 그런데 종종 시각적으로는 필요 없지만 스크린 리더에는 꼭 필요한 텍스트가 있습니다 — 아이콘만 있는 버튼의 라벨, 표의 반복되는 헤더 설명 같은 것들입니다.

`.sr-only` 클래스(흔히 `.visually-hidden`이라고도 부름)는 요소를 1px×1px로 줄이고 `overflow: hidden`, `clip-path`, `position: absolute`를 조합해 화면에서는 완전히 사라지게 하면서도 `display`나 `visibility`는 건드리지 않아 접근성 트리에는 그대로 남깁니다. `opacity: 0`이나 `width: 0`만으로는 부족합니다 — 레이아웃에 영향을 주거나 일부 브라우저에서 여전히 트리에서 빠질 수 있습니다.

데모는 검색 버튼 라벨을 세 가지 방식으로 숨겼을 때, 화면(눈)과 스크린 리더(귀) 각각에 뭐가 남는지 대조합니다.

언제 쓰나

아이콘 버튼 라벨, 스킵 링크, 폼의 부가 설명처럼 화면엔 필요 없지만 스크린 리더엔 필요한 텍스트에 씁니다. 임시로 숨기고 나중에 다시 보여줄 요소(아코디언, 탭)에는 hidden 속성이나 display: none을 쓰세요 — 그건 정말 없어져야 하는 콘텐츠입니다.