Focus Ring

포커스 링

The outline that shows where keyboard focus currently is. Removing it with outline: none strands keyboard users.

Also known as: 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);

A focus ring is the visual cue that shows which element is currently selected while tabbing through a page. Because it looks unnecessary for mouse users, `outline: none` often gets applied — but that leaves keyboard and switch-device users with no way to tell where they are.

The `:focus-visible` pseudo-class lets the browser judge whether focus arrived via keyboard or pointer, and draws the ring only for keyboard focus. Mouse clicks stay visually clean while keyboard navigation keeps its indicator.

On the left (`outline: none`), tabbing through buttons leaves no visible trace of which one is selected. On the right (`:focus-visible`), the ring follows focus every step.

When to use

If you're tempted to strip outline on a custom button or card, replace it with :focus-visible instead — never remove it outright.