포커스 표시기는 '포커스 링'으로 표시되는 경우가 많으며 페이지에서 포커스가 있는 요소를 식별합니다. 마우스를 사용할 수 없거나 사용하고 싶지 않은 사용자에게는 이 표시기가 매우 중요합니다. 마우스 포인터의 역할을 하기 때문입니다.
브라우저의 기본 포커스 표시기가 디자인과 충돌하는 경우 CSS를 사용하여 스타일을 변경할 수 있습니다. 사용자를 염두에 두세요.
:focus를 사용하여 항상 포커스 표시기 표시
:focus 의사 클래스는 사용 중인 입력 방법이나 기기 (예: 마우스, 키보드, 스타일러스)와 관계없이 포커스가 있는 요소에 적용됩니다.
예를 들어 다음 <div>에는 포커스 가능하게 만드는 tabindex이 있으며 :focus 상태의 맞춤 스타일이 있습니다.
div[tabindex="0"]:focus {
outline: 4px dashed orange;
}
어떤 기기를 사용하든 포커스가 맞춰진 <div>는 동일하게 표시됩니다.
브라우저가 포커스를 적용하는 방식은 일관되지 않을 수 있습니다. 요소가 포커스를 받는지 여부는 브라우저와 운영체제에 따라 다를 수 있습니다.
예를 들어 다음 <button>에는 :focus 상태의 맞춤 CSS가 있습니다.
button:focus {
outline: 4px dashed orange;
}
macOS에서 Chrome의 마우스로 <button>를 클릭하면 맞춤 포커스 스타일이 표시됩니다. 하지만 macOS의 Safari에서 <button>를 클릭하면 맞춤 포커스 스타일이 표시되지 않습니다. Safari에서는 요소를 클릭해도 포커스가 지정되지 않기 때문입니다.
포커스 동작이 일관되지 않습니다. 다양한 기기에서 다양한 입력으로 페이지를 테스트하여 포커스 스타일이 사용자에게 허용되는지 확인하세요.
:focus-visible를 사용하여 선택적으로 포커스 표시기 표시
:focus-visible 의사 클래스는 요소가 포커스를 받고 브라우저가 휴리스틱을 사용하여 포커스 표시기를 표시하는 것이 사용자에게 유익하다고 판단할 때 적용됩니다. 특히 가장 최근의 사용자 상호작용이 키보드를 사용한 것이고 키 누름에 meta, 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 hides the focus indicator if the element receives focus with a
mouse, but it still shows 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 {
...
}