Direct answer: of the 25 homepages, 19 have :focus rules (1,014 rules) and 21 contain outline:none somewhere, with 17 writing it inside a :focus rule (130 rules). 15 sites declare a replacement: 14 are structural (12 use box-shadow, two use outline/border), one changes colour only; four suppress without a replacement (35 rules) and six have no :focus rule at all. Six sites use :focus-visible (12 rules).
This study reads style declarations only; it does not render pages, compare contrast or execute JavaScript.
Method: putting outline:none back into its rule
On 2026-11-08 between 23:42 and 23:43 we re-requested the same 25 homepages, reading inline <style> blocks and the first three external stylesheets; requests were serial, 0.5 s apart, with a 15-second timeout. The parser strips comments and pairs selectors with declaration blocks; the outer @media wrapper is skipped while its inner rules are counted. Declarations only, no rendering.
| Measure | Definition | Boundary |
|---|---|---|
| Any outline:none | outline:none or outline:0 anywhere in the CSS text | Includes non-:focus rules and inline styles |
| outline:none in :focus | Selector contains :focus / :focus-visible / :focus-within and declares outline none/0 | :hover and :active excluded |
| Replacement | A :focus rule declaring outline (not none), box-shadow, border, background, text-decoration, filter, transform or text-shadow | Colour alone counts as weak |
| Structural replacement | At least one of those structural properties | Rendering and contrast not judged |
| Suppress only | outline:none inside :focus and no replacement declaration on the site | Judged per site, not per rule |
Result: 19 sites with :focus, 15 with a replacement
| Measure | Sites | Rules |
|---|---|---|
| :focus rules | 19 | 1,014 |
| :focus-visible rules | 6 | 12 |
| Any outline:none | 21 | 343 |
| outline:none in :focus | 17 | 131 |
| Replacement declared | 15 | 890 |
| Structural replacement | 14 | 758 |
| Colour only | 1 | 132 |
| Suppress only | 4 | 34 |
| No :focus rule | 6 | 0 |
Replacements are uneven. Twelve sites use box-shadow (E01, E02, E03, E06, E09, E14, E16, E17, E22, E23, E25 and E30) and two use structural properties such as outline or border (E04, E12); E13 changes colour only and is counted as weak. E11, E19, E24 and E26 suppress without a replacement, 35 rules in total, and E08, E18, E20, E27, E28 and E29 have no :focus rule; E18 and E20 returned no external CSS and no inline focus rule, which is a fetch boundary. Note also that the replacements on E04 and E12 cover only utility classes (a skip link and screen-reader text), while input:focus on the same site may still suppress the outline, so the site-level flag overstates coverage.
Why this differs from the previous run
The earlier run read external CSS only and counted text occurrences: 18 sites with :focus rules and 20 with outline:none. This run also includes inline <style> and parses rules: 19 and 21. The difference comes mainly from inline styles — all 68 focus rules on E25 sit in one inline <style> block with zero external CSS, while E17 has 17 inline blocks and E24 has nine. The two runs may also have fetched different stylesheets, so only the aggregate definitions are compared, not site by site.
| Measure | Earlier 22:42 | This run 23:42 |
|---|---|---|
| Style sources | First three external stylesheets | Inline <style> + first three external stylesheets |
| Parsing | Text occurrences | Selector plus declarations |
| Sites with :focus rules | 18 | 19 |
| Sites with outline:none | 20 | 21 |
| Of those, inside :focus | Not measured | 17 |
What this means for acceptance
- Do not stop at the keyword. When you see outline:none, ask whether the same :focus rule declares a replacement; 15 sites do and four do not.
- Parse inline styles too. All of E25's focus rules live in inline
<style>; reading external CSS alone would miss the whole site. - box-shadow is the most common replacement (12 of 15), but a declaration is not proof. Tab through each page and confirm the focus position is visible on light and dark backgrounds.
- Fix suppress-only sites first. E11, E19, E24 and E26 remove the outline across 35 rules without adding anything.
- No :focus rule is not automatically a defect. Six sites may rely on the browser's default ring; confirm manually before reporting it. See the website development service.
Limits
- Declarations only: no rendering and no contrast measurement, so visibility is not proven.
- Style scope: inline
<style>and the first three external stylesheets;@importand script-injected styles are excluded. - Parser boundary: the outer
@mediablock is skipped while inner rules count; CSS nesting is unsupported; pseudo-elements are not separated. - Fetch boundary: E18 and E20 returned no external CSS; some sites may have served different stylesheets across runs.
- Site-level flag: a site counts as having a replacement if any focus rule declares one, without checking that it covers the elements whose outline was removed.
- 25-site pilot: the same equipment-company sample; no industry claim.
Data and reproduction
Anonymised data: equipment-homepage-focus-indicator-2026.csv (25 rows × 13 columns: status, CSS files, focus rules, focus-visible, any outline:none, outline:none in :focus, replacement/structural/colour-only/box-shadow/suppress-only rule counts, time). The repository keeps docs/research/2026-11-homepage-focus-indicator.csv.
Parser: scripts/focus_indicator_probe.py; unit tests: scripts/test_content_focus_indicator.py (11, offline). Run:
python -m unittest scripts.test_content_focus_indicator
Related: homepage semantics and keyboard access (skip link, tabindex, focus counts), the homepage link structure pilot (2,739 links), and the homepage navigation pilot.
Sources and definitions
- Sample: 25 of the 30 homepages in study 4 that were cached as 200 — the same set as the 22:42 keyboard recheck.
- Fetch: 2026-11-08 23:42–23:43 Asia/Shanghai, serial, 0.5 s apart, 15-second timeout.
- Styles: inline
<style>plus the first three external stylesheets. - Definitions: any outline:none, outline:none in :focus, replacement, structural replacement and suppress only, as in the table above.
Frequently asked questions
Why 20 sites last time and 21 now?
The definitions differ: the earlier run read external CSS only and counted text occurrences; this run also includes inline