포커스 링

Focus Ring

키보드로 포커스를 옮길 때 지금 어디 있는지 보여주는 테두리. outline: none으로 지우면 키보드 사용자가 위치를 잃습니다.

다른 이름: Focus indicator:focus-visible
···
html
<div class="stage">
  <div class="pane">
    <div class="tag">✗ outline: none</div>
    <div class="row">
      <button class="btn b1"></button>
      <button class="btn b2"></button>
      <button class="btn b3"></button>
    </div>
    <div class="key" id="k1">⇥</div>
  </div>
  <div class="pane">
    <div class="tag">✓ :focus-visible</div>
    <div class="row">
      <button class="btn c1"></button>
      <button class="btn c2"></button>
      <button class="btn c3"></button>
    </div>
    <div class="key" id="k2">⇥</div>
  </div>
</div>
css
.stage{width:94%;height:88%;display:flex;gap:4%}
.pane{position:relative;flex:1;border-radius:14px;border:1px solid var(--line);background:var(--surface);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10%;overflow:hidden}
.tag{position:absolute;top:8px;left:10px;font:700 10.5px/1 ui-monospace,monospace;color:var(--muted)}
.row{display:flex;gap:10%}
.btn{width:22%;aspect-ratio:1;border-radius:9px;border:1px solid var(--line);background:var(--bg)}
.key{font:700 14px/1 ui-monospace,monospace;color:var(--muted);opacity:0}
.ring{box-shadow:0 0 0 3px var(--accent)}
js
const setB = [document.querySelector('.c1'), document.querySelector('.c2'), document.querySelector('.c3')];
const k1 = document.getElementById('k1');
const k2 = document.getElementById('k2');
let i = 0;
function tick() {
  setB.forEach(function (b) { b.classList.remove('ring'); });
  setB[i % 3].classList.add('ring');
  k1.style.opacity = '1';
  k2.style.opacity = '1';
  setTimeout(function () { k1.style.opacity = '0'; k2.style.opacity = '0'; }, 500);
  i++;
}
tick();
setInterval(tick, 1100);

포커스 링은 Tab으로 이동할 때 지금 어떤 요소가 선택됐는지 보여주는 시각 신호입니다. 마우스 사용자에게는 필요 없어 보여서 `outline: none`으로 지워버리는 경우가 흔한데, 그러면 키보드·스위치 사용자는 지금 포커스가 어디 있는지 전혀 알 수 없게 됩니다.

`:focus-visible` 의사 클래스를 쓰면 브라우저가 키보드로 왔는지 마우스로 왔는지를 판단해서, 키보드 포커스일 때만 링을 그려줍니다. 마우스 클릭에는 링이 안 보여 시각적으로 깔끔하고, 키보드 이동에는 항상 보여 접근성도 지킵니다.

데모 왼쪽(`outline: none`)은 Tab으로 이동해도 어떤 버튼이 선택됐는지 표시가 없습니다. 오른쪽(`:focus-visible`)은 이동할 때마다 링이 따라다닙니다.

언제 쓰나

커스텀 버튼·카드 컴포넌트를 만들 때 outline을 지우고 싶다면 반드시 :focus-visible로 대체하세요. 완전히 없애면 절대 안 됩니다.