LabHub
学习 学习路径 课程

HTML — 一个标签顶一项功能

消灭没有名字的输入框

在 LabHub 中继续学习

한국어 원문으로 표시합니다.

목표

가입 폼을 하나 쓰고, 모든 칸에 접근 가능한 이름이 실제로 계산되는지를 확인합니다. 브라우저는 없지만 이름 계산은 마크업만으로 답이 하나입니다.

왜 중요한가

"label 을 썼는가" 는 눈으로 셀 수 있지만, 그것으로는 forid 가 어긋난 칸을 못 잡습니다. 기계가 보는 것은 글자가 아니라 계산 결과이고, 그 계산에는 정해진 순서가 있습니다 — aria-labelledbyaria-labellabeltitleplaceholder.

앞 단계가 값을 내면 뒤는 보지 않습니다. 그래서 aria-label 하나가 눈에 보이는 label 을 통째로 덮어쓰고, 화면에 적힌 글자와 음성이 갈라집니다. 말로 조작하는 사용자는 보이는 글자를 부르므로 그 순간 조작이 안 됩니다.

만들 것

/root/work/forms/signup.html 하나입니다. CSS 도 자바스크립트도 필요 없습니다 — 이 실습이 보는 것은 연결이 성립하는가 입니다.

계산기

cd /root/work/forms
python3 /opt/lab/checks/html-form-lab/accname.py signup.html

칸마다 이름과 그 이름이 어디에서 나왔는지를 보여 줍니다. 끊긴 aria-labelledbyaria-describedby 도 함께 찍습니다.

단계

  1. 문서 뼈대와 form · 제출 버튼
  2. 칸 세 개 · 이름이 label 에서 나오게
  3. 라디오 묶음 · fieldsetlegend
  4. 규칙 안내를 aria-describedby
  5. 오류 상태 — aria-invalidrole="alert"
  6. typeautocomplete
  7. 필수 표시 — 눈으로도, 프로그램으로도
  8. 계산기 결과를 08-names.txt
  9. 정리 → 09-notes.md

참고

폼 한 벌을 세운다

/root/work/forms/signup.html 을 만드세요. <!doctype html>, <html lang="ko">, <title>, <meta charset>, <meta name="viewport"> 가 있어야 하고, actionmethod 를 가진 <form> 안에 입력 칸 하나와 제출 <button> 이 있어야 합니다.

mkdir -p /root/work/forms. actionmethod 를 적어 두면 자바스크립트가 죽어도 폼은 보내집니다 — 그게 폼의 기본값입니다. 제출은 button 으로 하세요. input type="submit" 도 되지만 버튼 안에 아이콘이나 다른 요소를 넣을 수 없습니다.

이름이 어디에서 나오는가

입력 칸을 세 개 이상으로 늘리고, 모든 칸의 이름이 label 에서 나오게 하세요. 계산기가 찍는 출처= 가 세 칸 모두 label 이어야 합니다. placeholdertitle 로 이름을 때우면 실패합니다.

labelfor 와 입력칸의 id한 글자도 달라선 안 됩니다. 눈으로는 나란히 붙어 있어도 기계에게는 남남입니다. python3 /opt/lab/checks/html-form-lab/accname.py signup.html 로 지금 이름이 어디에서 나오는지 먼저 보세요.

묶음에는 묶음의 이름이 있다

같은 name 을 가진 라디오 버튼을 두 개 이상 만들고, 하나의 <fieldset> 안에 넣은 뒤 <legend> 로 묶음 이름을 주세요. 각 라디오에도 자기 label 이 있어야 합니다.

라디오는 여럿이 모여 질문 하나를 이룹니다. 보기마다 이름이 있어도 '무엇을 고르는 중인지' 는 어디에도 없습니다 — 그 자리를 legend 가 채웁니다. name 이 같아야 서로를 끕니다.

규칙은 이름이 아니라 설명이다

비밀번호 규칙 안내를 별도 요소로 쓰고 aria-describedby 로 연결하세요. 설명 글은 10자 이상이어야 하고, 이름과 같은 문장이면 안 됩니다.

규칙을 label 안에 밀어 넣으면 칸 이름이 '비밀번호 열두 자 이상 숫자와 기호를…' 이 되어 버립니다. 이름은 짧아야 목록에서 고를 수 있습니다. 긴 안내는 설명으로 분리하세요.

오류를 프로그램이 읽게 한다

이메일 칸에 aria-invalid="true" 를 주고, 도움말과 오류 메시지 두 요소aria-describedby 에 공백으로 나열하세요. 오류 메시지 요소에는 role="alert" 를 붙입니다.

빨간 테두리는 색을 구분 못 하는 사람에게 아무것도 아닙니다. aria-describedby 는 여러 id 를 받습니다 — 오류가 떠도 규칙 안내가 사라지지 않게 둘 다 가리키세요. 나중에 나타나는 글자는 role="alert" 가 있어야 읽힙니다.

타자 수도 접근성이다

글자를 치는 칸을 네 개로 늘리고(연락처 칸을 더하세요) 모두에 표준 autocomplete 값을 주세요. 이메일 칸은 type="email"autocomplete="email", 비밀번호는 new-password 입니다.

HTML 표준의 autofill 필드 이름 목록에 없는 값은 브라우저가 그냥 무시합니다 — e-mail 은 아무 일도 하지 않습니다. 가입은 new-password, 로그인은 current-password 입니다. 이 구분이 있어야 비밀번호 관리자가 새 암호를 제안합니다.

필수는 눈으로도 보여야 한다

칸 두 개 이상에 required 를 주고, 그 칸의 label 글자에도 필수 표시를 넣으세요. 선택 칸은 하나 이상 남겨 두어야 하고, 선택 칸의 이름에는 필수 표시가 없어야 합니다.

aria-required 만 쓰면 알려 주기만 할 뿐 브라우저의 제출 막기가 켜지지 않습니다. 반대로 required 만 쓰면 눈으로는 어느 칸이 필수인지 알 수 없습니다. 둘 다 필요합니다. 전부 필수로 만들면 표시가 아무것도 구분해 주지 않습니다.

계산기로 확인한다

accname.py 를 돌려 결과를 /root/work/forms/08-names.txt 로 남기세요. 저장된 줄 수가 지금 문서의 컨트롤 수와 같아야 하고, 출처=placeholder 나 끊긴 참조 경고가 없어야 합니다.

python3 /opt/lab/checks/html-form-lab/accname.py signup.html | tee 08-names.txt. 문서를 고쳤으면 다시 저장해야 합니다 — 채점기가 저장본과 지금 문서를 대조합니다.

무엇이 연결이고 무엇이 글자인가

/root/work/forms/09-notes.md 에 세 줄 이상(120자 이상) 적으세요. 본문에 placeholder, fieldset, 이름 이 들어가야 합니다. 문서 자체도 여전히 2단계 기준을 통과해야 합니다.

핵심은 하나입니다 — 연결은 글자가 아니라 계산이다. 어떤 실수가 '마크업은 멀쩡해 보이는데 이름이 없는' 상태를 만드는지 자기 말로 적어 두면 다음에 손이 기억합니다.