본문으로 건너뛰기

키보드로 다니기

HTML·CSS 목차누구나 쓸 수 있는 HTML레슨 40 / 93

목차

키보드로 다니는 사람은 Tab 키로 링크 · 단추 · 폼 칸을 하나씩 옮겨 다닙니다. 지금 키보드 입력을 받는 요소를 포커스(focus)라고 하고, 브라우저는 그 둘레에 포커스 표시를 그립니다. Tab 차례는 HTML에 적은 차례이고, 라디오 묶음은 한 번만 멈춥니다.

마우스를 쓰기 어려운 사람, 화면 읽기 프로그램을 쓰는 사람, 키보드가 더 빠른 사람이 이렇게 다닙니다. 이 사람들은 Tab을 누르기 전에 다음에 어디로 갈지, 누른 뒤에 지금 어디인지 알아야 합니다. 이 레슨에서는 Tab 차례를 읽는 법, 라디오 묶음 안에서 옮기는 법, 포커스 표시를 지키는 법을 봅니다.

6단계 중 1단계. Tab을 누르면 HTML의 첫 링크 '조리 순서'에 포커스가 갑니다.

1Tab 차례는 HTML에 적은 차례

<a href="#steps">조리 순서</a>
<label for="nick">이름</label>
<input id="nick" />
<button>후기 남기기</button>
결과 화면
잰 값개발자 도구에서 본 값
  • 지금 포커스의 읽는 이름이름
  • 지금 포커스의 역할textbox

Tab을 두 번 누르면 포커스는 링크 '조리 순서' 다음 글자 칸에 갑니다. 글자 칸의 읽는 이름은 라벨 글 '이름'입니다. 한 번 더 누르면 단추 '후기 남기기'입니다. 라벨 글자는 멈추는 곳이 아닙니다 — Tab은 링크 · 단추 · 폼 칸처럼 키보드로 쓰는 요소에만 멈춥니다. 단추처럼 칠한 div가 이 차례에 들지 않는 것은 앞 레슨 링크와 단추 가르기에서 봤습니다.

멈추는 차례는 화면의 위치가 아니라 HTML에 적은 줄의 차례입니다(브라우저 규칙 3). Shift+Tab은 같은 차례를 거꾸로 갑니다. 그래서 키보드로 다니기 좋은 페이지는 HTML의 차례부터 읽는 차례대로 씁니다.

2라디오 묶음은 한 번만 멈추고, 안은 방향키로

<input
  type="radio"
  name="size"
  id="one"
  value="1"
/>
<label for="one">1인분</label>
<input
  type="radio"
  name="size"
  id="two"
  value="2"
/>
<label for="two">2인분</label>
<button>담기</button>
결과 화면
잰 값개발자 도구에서 본 값
  • #two의 :checked켜짐
  • 지금 포커스의 읽는 이름담기

name이 같은 라디오 둘은 한 묶음입니다. 첫 Tab은 묶음에 한 번 들어가고(아무것도 고르지 않았으면 첫 라디오, 골랐으면 고른 라디오), 방향키(→ · ↓)를 누르면 옆 라디오로 옮기면서 그 칸을 고릅니다. 잰 값의 :checked 켜짐은 '2인분'이 골라졌다는 뜻입니다. 다음 Tab은 묶음을 떠나 단추 '담기'로 갑니다. 그래서 Tab 차례에서 라디오 묶음은 칸이 몇 개든 한 자리입니다.

3포커스 표시 — 지금 자리를 보이는 윤곽선

<a href="#steps">조리 순서</a>
결과 화면
잰 값개발자 도구에서 본 값
  • 지금 포커스의 읽는 이름조리 순서
  • a의 outline-styleauto

Tab으로 링크에 오면 크롬은 링크 둘레에 윤곽선(outline)을 그립니다. 이것이 포커스 표시입니다. 윤곽선은 CSS 속성 outline이 정하고, 크롬 기본 스타일의 모양은 auto(브라우저가 정한 고리 모양 — 크롬 기준)입니다. 포커스 표시는 키보드로 다니는 사람에게 마우스 커서와 같습니다. 이것이 없으면 Tab을 누를 때마다 지금 어디인지 처음부터 찾아야 합니다.

예제

레시피 페이지 위쪽입니다. Tab을 누를 때마다 포커스가 가는 차례를 읽는 이름으로 먼저 적어 본 뒤 결과 화면을 펴 보세요.

<a href="index.html">목록</a>
<a>후기</a>
<h1>김치볶음밥</h1>
<div class="btn">재료 담기</div>
<label for="nick">이름</label>
<input id="nick" />
<button>후기 남기기</button>
결과 화면 보기
결과 화면
잰 값개발자 도구에서 본 값
  • 지금 포커스의 읽는 이름후기 남기기
  • 지금 포커스의 역할button
  1. 목록 — href 있는 링크
  2. 이름 — 글자 칸(이름은 라벨 글)
  3. 후기 남기기 — 단추

href 없는 a '후기', 제목, div '재료 담기'는 건너뜁니다. 세 번 누르면 '후기 남기기'에 닿습니다. 예상과 다르면 그곳이 배울 곳입니다.

자주 틀리는 곳

틀린 생각: CSS로 보이는 차례를 바꾸면 Tab 차례도 따라 바뀐다.

<p class="row">
  <a href="#one">첫째</a>
  <a href="#two">둘째</a>
</p>
.row {
  display: flex;
  flex-direction: row-reverse;
}
결과 화면
잰 값개발자 도구에서 본 값
  • 지금 포커스의 읽는 이름첫째

CSS 판의 두 줄은 12단원에서 배우는 배치입니다. 지금은 '보이는 차례를 거꾸로 놓는 줄'로만 읽으세요. 화면에는 '둘째'가 왼쪽에 놓이지만, Tab을 한 번 누르면 오른쪽의 '첫째'로 갑니다. 보이는 차례와 Tab 차례가 엇갈려 키보드로 다니는 사람의 포커스가 오른쪽에서 왼쪽으로 튑니다.

맞는 규칙: Tab 차례는 HTML의 차례입니다. 보이는 차례를 바꿀 때는 HTML의 차례도 같이 맞춥니다 — 12단원 주축과 교차축에서 다시 봅니다.

틀린 생각: 차례가 마음에 들지 않으면 tabindex에 번호를 매겨 맞춘다.

<a href="index.html">목록</a>
<a
  href="#review"
  tabindex="1"
>
  후기
</a>
결과 화면
잰 값개발자 도구에서 본 값
  • 지금 포커스의 읽는 이름후기

tabindex="1"처럼 0보다 큰 번호를 적은 요소는 페이지의 다른 모든 요소보다 먼저 포커스를 받습니다. 첫 Tab이 둘째 줄 '후기'로 가고, 페이지가 커질수록 번호를 단 요소와 안 단 요소의 차례가 뒤엉킵니다.

맞는 규칙: 0보다 큰 tabindex는 쓰지 않습니다. 차례는 HTML의 줄 차례를 고쳐 맞춥니다.

틀린 생각: 포커스 표시가 보기 싫으면 지워도 된다.

<a href="#steps">조리 순서</a>
a:focus {
  outline: none;
}
결과 화면
잰 값개발자 도구에서 본 값
  • 지금 포커스의 읽는 이름조리 순서
  • a의 outline-stylenone

a:focus는 '포커스가 간 링크'를 고르는 선택자입니다(8단원에서 자세히). 포커스는 여전히 링크에 있지만 윤곽선이 그려지지 않아, 키보드로 다니는 사람은 지금 자리를 볼 수 없습니다.

맞는 규칙: 포커스 표시는 지우지 않습니다. 모양이 마음에 들지 않으면 지우는 대신 다른 모양으로 바꿔 그립니다 — 8단원 마우스와 키보드 상태에서 봅니다.

확인 문제

1. 예제의 <a>후기</a>를 <a href="#review">후기</a>⁠로 바꿨습니다. Tab을 누를 때마다 포커스가 가는 차례를 읽는 이름으로 쓰세요.

<a href="index.html">목록</a>
<a href="#review">후기</a>
<h1>김치볶음밥</h1>
<div class="btn">재료 담기</div>
<label for="nick">이름</label>
<input id="nick" />
<button>후기 남기기</button>
힌트

바뀐 2번 줄이 Tab이 멈추는 요소가 되었는지부터 봅니다.

정답

목록 → 후기 → 이름 → 후기 남기기입니다.

결과 화면
잰 값개발자 도구에서 본 값
  • 지금 포커스의 읽는 이름후기
  • href가 생긴 a는 링크라 Tab이 멈춥니다. 두 번 누르면 '후기'에 갑니다.
  • 흔한 오답은 '재료 담기'를 넣은 차례입니다. 단추처럼 칠한 div는 여전히 건너뜁니다(모양이 역할이라는 생각).

2. 레시피 페이지 아래쪽 세 줄입니다. Tab 차례가 목록 → 조리 순서 → 후기 남기기가 되게 줄을 위에서부터 놓으세요. 기호를 차례로 쓰세요.

  • ㉠ <button>후기 남기기</button>
  • ㉡ <a href="#steps">조리 순서</a>
  • ㉢ <a href="index.html">목록</a>
힌트

Tab이 처음 멈출 요소를 맨 위에 놓습니다.

정답

㉢ ㉡ ㉠입니다.

<a href="index.html">목록</a>
<a href="#steps">조리 순서</a>
<button>후기 남기기</button>
결과 화면
잰 값개발자 도구에서 본 값
  • 지금 포커스의 읽는 이름조리 순서

Tab 차례는 HTML의 줄 차례라, 가고 싶은 차례대로 줄을 놓으면 됩니다. tabindex로 번호를 매길 일이 없습니다.

3. 카페 메뉴판의 주문 칸입니다. 페이지를 연 뒤 Tab을 두 번 누르면 포커스가 가는 곳의 읽는 이름은 무엇일까요?

<input
  type="radio"
  name="temp"
  id="hot"
  value="hot"
/>
<label for="hot">따뜻하게</label>
<input
  type="radio"
  name="temp"
  id="ice"
  value="ice"
/>
<label for="ice">차갑게</label>
<button>주문하기</button>
힌트

두 라디오의 name을 견줘 봅니다.

힌트 둘

한 묶음이 Tab 차례에서 몇 자리를 차지하는지 셉니다.

정답

주문하기입니다.

결과 화면
잰 값개발자 도구에서 본 값
  • 지금 포커스의 읽는 이름주문하기
  • name이 같은 두 라디오는 한 묶음이라 Tab이 한 번만 멈춥니다. 첫 Tab은 '따뜻하게', 둘째 Tab은 묶음을 떠나 '주문하기'로 갑니다.
  • 흔한 오답은 '차갑게'입니다. 라디오마다 Tab이 멈춘다고 본 것입니다. 묶음 안은 방향키로 옮깁니다.

컴퓨터에서 해 보기(선택) — 점수에 들지 않습니다. 폰으로만 보고 있다면 건너뛰세요. 3절 코드를 hello.html의 body 안에 붙여 저장하고 엽니다. 페이지를 한 번 누른 뒤 Tab을 눌러 링크 둘레에 포커스 표시가 그려지는지 봅니다. 그다음 head 안에 <style> 요소를 두고(규칙의 모양에서 쓴 자리) 자주 틀리는 곳 셋째의 a:focus 규칙을 넣어 저장 · 새로고침합니다. 다시 Tab을 눌러 무엇이 달라지는지 적어 봅니다. 확인했으면 그 규칙은 지웁니다.

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

HTML·CSS 목차로