ids

command
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2026 License: BSD-3-Clause Imports: 8 Imported by: 0

Documentation

Overview

Command ids reports duplicate id attributes, and the references they make ambiguous.

page.html:14:3: id="submit" is used 3 times (also at 22:5, 31:5)
page.html:14:3:   1 label for=, 1 aria-controls and 1 fragment link name it
page.html:40:3: for="gone" names no id in this document

A duplicate id is not one broken thing, it is a list of them, and which ones depends on what points at the id. So the report names them: every reference in the document is collected along with every id, and the two are matched at the end. That is the shape a report can have and a rewrite cannot - see examples/gip/labels, where the same join is what makes the finding possible.

The reason duplicates survive in a codebase is worth stating, because it is the one mechanism that does not break: a CSS "#id" selector matches every element with that id, so the page looks right. Everything else takes the first and silently ignores the rest - getElementById, a fragment link, a label's for, and every ARIA reference. So the visual check passes and the keyboard user is the one who finds it.

The attributes that name an id are a list rather than a rule, and this is the list: for, form, list, headers, aria-activedescendant, aria-controls, aria-describedby, aria-details, aria-errormessage, aria-flowto, aria-labelledby and aria-owns, plus an href or an xlink:href whose value is a fragment. Six of them - headers, aria-controls, aria-describedby, aria-flowto, aria-labelledby and aria-owns - hold several ids separated by spaces rather than one, which is a detail a program has to get right to report on them at all.

Every one of those values is read decoded, because an id is what it decodes to: id="café" and id="café" are one id spelled two ways, and a fragment link to either names both. The library reports attributes as raw source, so comparing what it hands back would miss the duplicate and report the link as broken in the same document.

Two more findings fall out of having the index:

A reference naming no id at all - a for pointing at a control that was renamed, an aria-labelledby left behind by a refactor. It is the same defect as a duplicate seen from the other side.

An id that is not a valid id: one with whitespace in it, or an empty one. HTML says an id must have at least one character and no whitespace, and the reason to report it is concrete rather than pedantic: a fragment link cannot address it, and a CSS "#id" selector cannot name it.

One thing reported as advice rather than as a defect: two ids differing only in case. That is legal - ids are case-sensitive, and so is a "#id" selector, which is why "#Main" does not match id="main" - and it is the kind of legal that costs somebody an afternoon.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL