포커스 표시기('포커스 링'으로 표시되는 경우가 많음)는 페이지에서 현재 포커스가 설정된 요소를 식별합니다. 마우스를 사용할 수 없는 사용자의 경우 이 표시기가 마우스 포인터의 독립형 역할을 하므로 매우 중요합니다.
브라우저의 기본 포커스 표시기가 디자인과 충돌하는 경우 CSS를 사용하여 스타일을 다시 지정할 수 있습니다. 키보드 사용자를 염두에 두어야 합니다.
:focus
를 사용하여 항상 포커스 표시기를 표시합니다.
:focus
의사 클래스는 입력 기기 (마우스, 키보드, 스타일러스 등) 또는 요소에 포커스를 지정하는 데 사용되는 메서드와 관계없이 요소에 포커스가 있을 때마다 적용됩니다. 예를 들어 아래 <div>
에는 포커스 가능하게 만드는 tabindex
가 있습니다. :focus
상태를 위한 맞춤 스타일도 있습니다.
div[tabindex="0"]:focus {
outline: 4px dashed orange;
}
마우스를 사용하여 클릭하든 키보드를 사용하여 탭하든 <div>
는 항상 동일하게 보입니다.
안타깝게도 브라우저는 포커스를 적용하는 방식과 일치하지 않을 수 있습니다. 요소가 포커스를 받는지 여부는 브라우저와 운영체제에 따라 다를 수 있습니다.
예를 들어 아래 <button>
에는 :focus
상태의 맞춤 스타일도 있습니다.
button:focus {
outline: 4px dashed orange;
}
macOS의 Chrome에서 마우스로 <button>
를 클릭하면 맞춤 포커스 스타일이 표시됩니다. 그러나 macOS의 Safari에서 <button>
를 클릭하면 맞춤 포커스 스타일이 표시되지 않습니다. 이는 Safari에서 요소를 클릭해도 포커스를 받지 않기 때문입니다.
포커스 동작이 일관되지 않으므로 포커스 스타일이 사용자에게 허용되는지 확인하기 위해 다른 기기에서 약간의 테스트가 필요할 수 있습니다.
:focus-visible
를 사용하여 포커스 표시기를 선택적으로 표시합니다.
새로운 :focus-visible
유사 클래스는 요소가 포커스를 받고 브라우저는 휴리스틱을 통해 포커스 표시기를 표시하는 것이 사용자에게 도움이 된다고 판단할 때마다 적용됩니다. 특히 가장 최근의 사용자 상호작용이 키보드를 통해 이루어졌고 키 누름에 메타, ALT
/ OPTION
, CONTROL
키가 포함되지 않았다면 :focus-visible
가 일치합니다.
아래 예의 버튼은 포커스 표시기를 선택적으로 표시합니다. 마우스를 사용하여 클릭하는 경우 처음 키보드를 사용하여 탭하는 경우와 결과가 다릅니다.
button:focus-visible {
outline: 4px dashed orange;
}
:focus-within
을 사용하여 포커스가 맞춰진 요소의 상위 요소 스타일 지정
:focus-within
유사 클래스는 요소 자체가 포커스를 받거나 그 요소 내부의 다른 요소가 포커스를 받을 때 요소에 적용됩니다.
페이지의 한 영역을 강조 표시하여 해당 영역에 사용자의 관심을 유도할 수 있습니다. 예를 들어 아래 양식은 양식 자체가 선택될 때와 라디오 버튼이 선택될 때 모두 포커스를 받습니다.
form:focus-within {
background: #ffecb3;
}
포커스 표시기를 표시하는 경우
경험상 '휴대기기를 사용하는 동안 이 컨트롤을 클릭하면 키보드가 표시될 것으로 예상하나요?'라고 자문해 보는 것이 좋습니다.
답변이 '예'라면 컨트롤은 포커스를 지정하는 데 사용된 입력 기기와 관계없이 항상 포커스 표시기를 표시해야 합니다. <input type="text">
요소를 예로 들 수 있습니다. 사용자는 입력 요소가 원래 포커스를 받은 방식과 관계없이 키보드를 통해 요소에 입력을 보내야 하므로 항상 포커스 표시기를 표시하는 것이 좋습니다.
답이 '아니요'이면 컨트롤은 포커스 표시기를 선택적으로 표시하도록 선택할 수 있습니다. <button>
요소를 예로 들 수 있습니다. 사용자가 마우스나 터치스크린으로 이를 클릭하면 작업이 완료되고 포커스 표시기가 필요하지 않을 수 있습니다. 그러나 사용자가 키보드로 탐색하는 경우 포커스 표시기를 표시하여 사용자가 ENTER
또는 SPACE
키를 사용하여 컨트롤을 클릭할지 결정할 수 있도록 하는 것이 좋습니다.
outline: none
사용 자제
브라우저에서 포커스 표시기를 그릴 시점을 결정하는 방식은 솔직히 매우 혼란스럽습니다. CSS를 사용하여 <button>
요소의 모양을 변경하거나 요소에 tabindex
를 지정하면 브라우저의 기본 포커스 링 동작이 시작됩니다.
매우 일반적인 안티패턴은 다음과 같은 CSS를 사용하여 포커스 표시기를 제거하는 것입니다.
/* Don't do this!!! */
:focus {
outline: none;
}
이 문제를 해결하는 더 좋은 방법은 :focus
와 :focus-visible
폴리필의 조합을 사용하는 것입니다. 아래의 첫 번째 코드 블록은 폴리필의 작동 방식을 보여주며, 그 아래의 샘플 앱에서는 폴리필을 사용하여 버튼의 포커스 표시기를 변경하는 예를 제공합니다.
/*
This will hide the focus indicator if the element receives focus via the
mouse, but it will still show up on keyboard focus.
*/
.js-focus-visible :focus:not(.focus-visible) {
outline: none;
}
/*
Optionally: Define a strong focus indicator for keyboard focus.
If you choose to skip this step, then the browser's default focus
indicator will be displayed instead.
*/
.js-focus-visible .focus-visible {
…
}