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-frontpage is 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 existing preprocess_page_title behaviour already hides the title on any front page, Canvas or not, and this rule matches that policy. It is scoped to main, so an h1 in 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: none and visibility: hidden would 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-one passing
  • on a non-front page (body class="gin-login path-user") an h1 in main is 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
Edited by Rajab Natshah

Merge request reports

Loading