HTML label과 input 연결 방법
입력창 옆에 텍스트를 놓았다고 브라우저가 둘의 관계를 자동으로 이해하지는 않는다.label과 입력 요소를 연결해야 화면에 보이는 텍스트가 해당 입력 요소의 접근 가능한 이름으로 계산된다.
가장 분명한 방법은 label의 for와 input의 id를 같은 값으로 지정하는 것이다.
연결이 만드는 동작
연결된 label은 입력 요소가 어떤 값을 받는지 설명한다.
스크린 리더는 입력 요소에 포커스가 갔을 때 연결된 이름을 함께 전달할 수 있다.
사용자가 label을 클릭하거나 터치하면 연결된 입력 요소도 포커스되거나 활성화된다.
작은 checkbox와 radio의 조작 영역을 label 텍스트까지 넓힐 수 있어 마우스와 터치 사용성도 좋아진다.
단순히 입력창 앞에 일반 텍스트를 두는 방식에는 이런 프로그램 관계와 기본 동작이 없다.
for와 id의 명시적 연결
명시적 연결에서는 for 값이 같은 문서에 있는 labelable 요소의 id와 정확히 일치해야 한다.
<label for="email">이메일</label>
<input
id="email"
name="email"
type="email"
autocomplete="email"
required
/>이 코드에서 연결을 만드는 값은 for="email"과 id="email"이다.name="email"은 폼을 제출할 때 값의 키로 사용되며 label 연결을 만들지 않는다.
id는 문서 안에서 고유해야 한다.for는 문서에서 해당 id를 가진 첫 번째 요소를 기준으로 하므로, id가 중복되면 의도와 다른 요소에 연결되거나 연결이 끊길 수 있다.id와 class의 기본 차이는 HTML id와 class 차이에서 이어서 볼 수 있다.
label 안의 암시적 연결
입력 요소를 label 안에 넣으면 for와 id 없이도 암시적으로 연결할 수 있다.
<label>
<input name="newsletter" type="checkbox" />
새 글 알림 받기
</label>간단한 checkbox 한 개처럼 label과 입력 요소가 한 덩어리로 배치될 때 읽기 편하다.
다만 명시적 연결이 보조 기술과 외부 도구에서 더 넓게 지원되고, label과 입력창을 형제 요소로 두면 Grid나 Flexbox 배치도 자유롭다.
컴포넌트에서 고유한 id를 안정적으로 만들 수 있다면 명시적 연결을 기본으로 삼는 편이 좋다.
필요하다면 중첩과 for·id를 동시에 사용할 수도 있지만 for는 반드시 내부의 해당 입력 요소를 가리켜야 한다.
그룹과 보조 설명
여러 radio가 하나의 질문에 답한다면 fieldset과 legend로 그룹의 이름을 제공한다.
각 radio에는 다시 개별 label을 연결한다.
<fieldset>
<legend>알림 방식</legend>
<input id="notify-email" name="notification" type="radio" value="email" />
<label for="notify-email">이메일</label>
<input id="notify-sms" name="notification" type="radio" value="sms" />
<label for="notify-sms">문자 메시지</label>
</fieldset>입력 형식이나 오류 조건처럼 이름보다 긴 설명은 label에 모두 넣지 않아도 된다.
별도 텍스트를 aria-describedby로 연결하면 입력 요소의 접근 가능한 설명으로 전달할 수 있다.
<label for="password">비밀번호</label>
<input id="password" name="password" type="password" aria-describedby="password-help" />
<p id="password-help">영문과 숫자를 포함해 8자 이상 입력합니다.</p>label은 입력의 핵심 이름을, 설명은 입력 방법과 제약을 맡는다.aria-describedby는 label을 대체하지 않는다.
자주 틀리는 패턴
placeholder는 입력 예시나 짧은 힌트로만 사용한다.
값을 입력하면 사라지고 항상 보이지 않으므로 label 대신 사용하면 안 된다.
display: none이나 visibility: hidden으로 label을 숨기면 보조 기술에서도 함께 숨겨진다.
화면에는 이름을 표시하기 어렵다면 검증된 visually hidden 스타일이나 문맥에 맞는 접근 가능한 이름 방식을 별도로 검토해야 한다.
label 안에는 연결 대상 외의 링크나 버튼을 넣지 않는 편이 좋다.
별도 상호작용 요소가 label의 활성화 동작과 충돌할 수 있기 때문이다.
input type="hidden"은 label 대상이 아니다.
일반 button은 내부 텍스트가 이름을 제공하고, submit·reset input은 value가 이름을 제공하므로 불필요한 label을 붙이지 않는다.
버튼과 링크의 의미 차이는 HTML button과 a 태그 차이에서 정리했다.
참고 자료























