fix: #3621201 Visually hide the front page h1 so a Canvas landing page can carry one
Closes #3621201.
Related issue: https://www.drupal.org/i/3621201
Why
A Canvas landing page built on this theme has no h1, so axe-core reports page-has-heading-one. The theme already intends the front page to carry a screen-reader-only heading: vartheme_bs5_preprocess_page_title() adds visually-hidden to the page title on the front page. That never fires on a Canvas landing page, because the site template recipes disable the page-title block there.
With this rule a site template can place a heading at level: 1 carrying the site name in its Canvas tree and get a correct document outline with no visible design change.
The change
CSS only. One rule in scss/base/vartheme.base.scss and the matching lines in the committed css/base/vartheme.base.css. No PHP, no component manifest, no other component styling.
.path-frontpage main h1 {
@include visually-hidden();
}- Selector:
.path-frontpageis Drupal core's own front-page body class, so it is stable and the theme does not have to add it. It is not narrowed to.canvas-page, because the theme's existingpreprocess_page_titlebehaviour already hides the title on any front page, Canvas or not, and this rule matches that policy. It is scoped tomain, so anh1in the header, the admin toolbar or an off-canvas dialog is not caught. - Technique: Bootstrap 5.3's own
visually-hidden()mixin, so the declarations are not restated and the clip technique is the reference one. The element stays in the accessibility tree.display: noneandvisibility: hiddenwould remove it and leave the axe violation in place while appearing to fix it.
Verified
On a running Varbase 11 site with a Canvas front page (body class="canvas-page path-frontpage"), with an h1 present in main:
- computed
display: block,visibility: visible,position: absolute,clip: rect(0px, 0px, 0px, 0px), rendering at 1x1 pixel - the heading is still in the accessibility tree, exposed as
heading "..." [level=1] - document height unchanged with the heading added, so nothing else on the front page moves
- axe-core 4.10.2 over WCAG 2.0 and 2.1 A and AA plus best practice: zero violations, 43 passes,
page-has-heading-onepassing - on a non-front page (
body class="gin-login path-user") anh1inmainis unaffected:position: static,clip: auto, full size
AI policy disclosure
This contribution was produced with AI assistance (Claude Code) and reviewed before submission. See https://www.drupal.org/about/core/policies/core-change-policies/ai-policy
Checkpoints
- File an issue
- Addition/Change/Update/Fix
- Testing to ensure no regression
- Reviewed by a human
- Code review by maintainers
- Release