label 요소가 하는 일
<label>은 폼 필드에 이름을 붙여요. 필드의 id를 값으로 준 for로 연결하면 두 가지 일이 일어나요. 필드에 포커스가 가면 스크린 리더가 라벨을 알려 주고, 라벨 텍스트를 클릭하면 필드에 포커스가 가요. 아래 두 텍스트를 모두 클릭해 보세요.
"City"를 클릭하면 커서가 그 필드에 들어가요. "Country"를 클릭하면 아무 일도 없고, 두 번째 필드에 포커스한 스크린 리더는 이름 없이 "편집 텍스트"라고만 들려줘요. 둘은 똑같아 보이지만 라벨이 붙은 건 하나뿐이에요.
라벨을 연결하는 두 가지 방법
for와 id를 쓰거나, 필드를 라벨 안에 넣으세요.
for와 id | 감싸기 | |
|---|---|---|
id 필요 | 예, 페이지에서 유일해야 함 | 아니요 |
| 라벨과 필드를 떨어뜨릴 수 있음 | 예(표 셀, 그리드) | 아니요, 필드가 안에 있음 |
| 깨지기 쉬운 경우 | 오타나 중복된 id | 라벨 하나에 필드 두 개를 넣을 때 |
for는 필드의 name이 아니라 id와 일치해야 해요. 둘이 같은 단어인 경우가 많아서, 누군가 한쪽을 바꿀 때까지 실수가 드러나지 않아요. 둘 다(감싸기와 for) 해도 괜찮고 흔한 방식이에요.
라벨은 <input>(type="hidden" 제외), <select>, <textarea>, <button>, <meter>, <output>, <progress>에 연결할 수 있어요. 라벨 하나는 필드 하나에 이름을 붙여요. 필드 하나에 라벨이 여러 개일 수도 있지만, 분명한 라벨 하나가 모두에게 더 쉬워요.
체크박스와 라디오의 넓은 클릭 영역
작은 컨트롤에서 라벨이 가장 중요해요. 라벨 어디를 클릭해도 상자가 바뀌어서, 클릭 영역이 13픽셀 정사각형이 아니라 텍스트 한 줄 전체가 돼요. 라벨을 꾸미면 영역을 더 넓힐 수도 있어요.
상자에서 떨어진 각 행의 padding 부분을 클릭해 보세요. 첫 번째 행은 체크가 바뀌고, 두 번째 행은 상자 자체를 맞히지 않으면 아무 일도 없어요. 체크박스는 HTML 체크박스에서 더 다뤄요.
힌트와 오류 메시지
라벨은 필드 이름처럼 짧아야 해요. 추가 설명과 오류 메시지는 별도 요소에 넣고 aria-describedby로 연결하세요. 그러면 스크린 리더가 라벨을 먼저 읽고 그 뒤에 설명을 읽어요.
필드를 비운 채로, 그다음 AB로, 그다음 ada99로 Create를 눌러 보세요. aria-describedby 덕분에 스크린 리더는 "Username, 필수, 편집 텍스트, 3 to 16 lowercase letters or digits, Enter a username."처럼 알려 줘요. required 속성이 이미 "필수"라고 알려 주니 별표는 aria-hidden이에요. "별표"라고 듣는 건 아무 도움이 안 돼요.
숨긴 라벨
어떤 필드에는 텍스트 라벨 말고 다른 시각적 단서가 있어요. 검색 버튼 옆의 검색창 같은 경우예요. 그래도 라벨은 필요해요. 화면에서는 숨기되 스크린 리더를 위해 페이지에 남겨 두세요.
display: none이나 visibility: hidden으로 숨기지 마세요. 스크린 리더에서도 숨기고, 숨긴 라벨을 여전히 이름으로 쓰는 브라우저와 스크린 리더가 전부는 아니에요. 다른 방법은 input에 aria-label="Search courses"를 주는 거예요. 라벨 요소 없이 이름을 붙여요. 그래도 자리가 있다면 보이는 라벨이 최선이에요. 필드가 무엇을 위한 건지 보이면 모두에게 도움이 돼요.
자주 하는 실수
for가id대신name을 가리킴. 아무것도 연결되지 않아요.- 중복된 id.
for는 그 id를 가진 첫 번째 요소에 연결되는데, 페이지의 다른 폼에 있는 필드일 수도 있어요. - 라벨 대신 placeholder. 입력하면 사라지고 믿을 만한 이름이 아니에요.
- 라벨 하나에 필드 두 개. 라벨은 필드 하나에만 이름을 붙이고, 두 번째는 라벨 없이 남아요.
- 체크박스 라벨 안의 링크. "약관에 동의합니다"에서 "약관"이 링크인 경우예요. 줄의 일부는 상자를 바꾸고 일부는 페이지를 열어서 실수로 누르기 쉬워요. 링크는 라벨 밖에 두세요.
display: none으로 라벨을 숨김. 화면에서만 숨기는 클래스를 쓰세요.- 필드 옆의 텍스트가
<label>이 아님. 똑같아 보이지만 아무 일도 하지 않아요. 필드를 감싸는 폼은 HTML 폼을 보세요.
자주 묻는 질문
HTML에서 label 태그는 무슨 일을 하나요?
폼 필드에 이름을 붙여요. 필드에 포커스가 가면 스크린 리더가 라벨을 읽어 주고, 라벨을 클릭하면 필드에 포커스가 가거나 체크박스와 라디오 버튼이라면 체크가 바뀌어요.
label의 for 속성은 무엇인가요?
for는 라벨이 속한 필드의 id를 담아요. <label for="email">Email</label> <input id="email">처럼요. name이 아니라 id와 정확히 일치해야 해요.
input을 label 안에 넣어야 하나요, for를 써야 하나요?
현재 브라우저와 스크린 리더에서는 둘 다 동작해요. 감싸면 id가 필요 없고, for와 id를 쓰면 별도의 표 셀처럼 마크업에서 라벨과 필드를 다른 곳에 둘 수 있어요. 많은 팀이 감싸면서 for도 함께 써요.
placeholder가 label을 대신할 수 있나요?
없어요. placeholder는 독자가 입력하는 순간 사라지고, 명암비가 낮은 경우가 많고, 필드 이름으로 확실하게 읽히지도 않아요. 보이는 <label>을 쓰고, placeholder는 쓰더라도 예시 값에만 쓰세요.
라벨을 숨기면서 스크린 리더에는 남기려면 어떻게 하나요?
<label>은 남기고, 1픽셀로 줄여 잘라 내는 클래스로 화면에서만 숨기세요. display: none은 스크린 리더에서도 숨겨요. 라벨을 둘 자리가 전혀 없는 필드라면 필드에 aria-label을 쓰는 방법도 있어요.