HTML — One Tag Stands In For a Feature
Getting Rid of Nameless Fields
Goal
You write one signup form and check whether an accessible name is actually computed for every field. There is no browser, but name computation has a single answer from markup alone.
Why it matters
"Did I write a label" can be counted by eye, but that can't catch a field where for and id
don't match. What a machine sees is not the text but the computed result,
and that computation has a defined order — aria-labelledby → aria-label →
label → title → placeholder.
If an earlier step yields a value, the later ones are not looked at. So a single aria-label overwrites the visible label
entirely, and the text written on screen and the voice diverge.
Voice-control users say the visible text, so at that moment they can't operate it.
What to build
It is a single file, /root/work/forms/signup.html. No CSS or JavaScript is needed
— what this lab looks at is whether the connection holds.
The calculator
cd /root/work/forms
python3 /opt/lab/checks/html-form-lab/accname.py signup.html
For each field it shows the name and where that name came from. It also prints broken
aria-labelledby and aria-describedby references.
Steps
- Document skeleton,
form, and a submit button - Three fields · the name comes from
label - A radio group ·
fieldsetandlegend - Rule guidance with
aria-describedby - The error state —
aria-invalidandrole="alert" typeandautocomplete- Required marking — for the eye and for the program
- Save the calculator's result as
08-names.txt - Wrap-up →
09-notes.md
Notes
- The place the form is sent to doesn't need to actually exist. It looks only at the markup.
- If an
idis duplicated, every connection goes only to the first element. The grader blocks that first. - Automated checks catch only some of the problems. The rest mostly come to light if you put the mouse away and fill out the form all the way through with Tab alone.
Set up a form
Create /root/work/forms/signup.html. It must have <!doctype html>, <html lang="ko">, <title>, <meta charset>, and <meta name="viewport">, and inside a <form> with action and method there must be one input field and a submit <button>.
Run mkdir -p /root/work/forms. If you write action and method, the form is still submitted even if JavaScript dies — that is the form's default. Submit with a button. input type="submit" also works, but you can't put an icon or other elements inside the button.
Where does the name come from
Increase the input fields to three or more, and make every field's name come from label. The 출처= value (the Korean word for "source") that the calculator prints must be label for all three fields. If you patch over a name with placeholder or title, it fails.
The for of a label and the id of the input must not differ by even one character. To the eye they sit side by side, but to a machine they are strangers. First see where the name currently comes from with python3 /opt/lab/checks/html-form-lab/accname.py signup.html.
A group has a name of its own
Make two or more radio buttons with the same name, put them inside one <fieldset>, and give the group a name with <legend>. Each radio must also have its own label.
Radios together form one question. Even if each option has a name, nowhere does it say "what you are choosing" — the legend fills that spot. The name must be the same for them to deselect each other.
A rule is a description, not a name
Write the password rule guidance as a separate element and connect it with aria-describedby. The description text must be at least 10 characters, and it must not be the same sentence as the name.
If you shove the rule inside the label, the field's name becomes "Password at least twelve characters including digits and symbols…". A name has to be short to be chosen from a list. Separate long guidance out as a description.
Make the error readable by a program
Give the email field aria-invalid="true", and list two elements, the help text and the error message, in aria-describedby separated by a space. Attach role="alert" to the error message element.
A red border means nothing to someone who can't distinguish colors. aria-describedby accepts several ids — point to both so the rule guidance doesn't disappear when an error appears. Text that appears later is read only if it has role="alert".
Keystrokes are accessibility too
Increase the text-entry fields to four (add a contact field) and give all of them standard autocomplete values. The email field gets type="email" and autocomplete="email", and the password gets new-password.
A value not in the HTML Standard's list of autofill field names is simply ignored by the browser — e-mail does nothing. Use new-password for signup and current-password for login. Only with this distinction does a password manager suggest a new password.
Required must be visible to the eye too
Give required to two or more fields, and put a required marking in those fields' label text too. You must leave at least one optional field, and the name of an optional field must have no required marking.
With aria-required alone, it only informs and the browser's submission blocking isn't turned on. Conversely, with required alone, the eye can't tell which field is required. You need both. If you make everything required, the marking tells you nothing.
Check with the calculator
Run accname.py and save the result as /root/work/forms/08-names.txt. The number of saved lines must equal the number of controls in the current document, and there must be no 출처=placeholder (the first word is the Korean word for "source") or broken-reference warnings.
python3 /opt/lab/checks/html-form-lab/accname.py signup.html | tee 08-names.txt. If you changed the document, you have to save again — the grader compares the saved copy with the current document.
What is a connection and what is text
In /root/work/forms/09-notes.md, write at least three lines (at least 120 characters). The text must contain placeholder, fieldset, and 이름 (the Korean word for "name"). The document itself must also still pass the step 2 criteria.
The core is one thing — a connection is a computation, not text. If you write down in your own words which mistakes create the state "the markup looks fine but there is no name," your hands will remember next time.