diff --git a/docs/_data/topbar.json b/docs/_data/topbar.json index 2ffaf7654a..1a7adbb775 100644 --- a/docs/_data/topbar.json +++ b/docs/_data/topbar.json @@ -13,6 +13,11 @@ "applies": "`.s-topbar`", "description": "Forced dark theme" }, + { + "class": ".s-topbar--skip-link", + "description": "Applied to an anchor tag for bypassing the top-level navigation links and jump to the main content on a page. [See WCAG Technique G1](https://www.w3.org/WAI/WCAG22/Techniques/general/G1)", + "applies": "Child of `.s-topbar`" + }, { "class": ".s-topbar--container", "description": "Add **atomic** `classes` here to customize internal content width; defaults to `.wmx12`", @@ -68,4 +73,4 @@ "applies": "`.s-topbar--searchbar`", "description": "On mobile, this class shows the search input below the topbar. Toggle this class with a button" } -] \ No newline at end of file +] diff --git a/docs/_includes/header.html b/docs/_includes/header.html index 0ad3a4d78c..3de1dc4b13 100644 --- a/docs/_includes/header.html +++ b/docs/_includes/header.html @@ -1,4 +1,5 @@
+ Skip to main content
diff --git a/docs/product/components/topbar.html b/docs/product/components/topbar.html index aae2d223e2..c46e03b332 100644 --- a/docs/product/components/topbar.html +++ b/docs/product/components/topbar.html @@ -35,6 +35,7 @@
{% highlight html %}
+ Skip to main content
@@ -58,6 +59,26 @@ {% render 'topbar.html', hideNavigation: true, hideSearch: true, showMenu: true %}
+ + {% header "h3", "Skip Link" %} +

All topbars must include a skip link. + Usually a skip link should be the first focusable element of a page (with the expection of cookie consent dialogs). + Skip links are a mechanism to bypass blocks of content that are repeated on multiple web pages and comply with WCAG SC 2.4.1.

+ + {% tip, "info", "mb24" %} + Note: Skip links become visible only when focused via keyboard navigation and they are announced by screen readers. In the example below hit Tab on your keyboard to see it appearing when in focus. + {% endtip %} +
+{% highlight html %} +
+ Skip to main content +
+
+{% endhighlight %} +
+ {% render 'topbar.html', hideNavigation: true, hideSearch: true %} +
+
@@ -90,21 +111,24 @@

{{ variation | split: "__" | last | capitalize }}

{% highlight html %}
- + Skip to main content +
+ - + - + +
{% endhighlight %}
@@ -126,31 +150,34 @@

Input only

{% highlight html %}
- - + Skip to main content +
+ + - - New - + + New + - + - + +
{% endhighlight %}
@@ -163,6 +190,7 @@

Input only

{% highlight html %}
+ Skip to main content
{% endhighlight %} diff --git a/lib/components/topbar/topbar.less b/lib/components/topbar/topbar.less index 873ddd0c39..21a102a1c3 100644 --- a/lib/components/topbar/topbar.less +++ b/lib/components/topbar/topbar.less @@ -1,4 +1,6 @@ .s-topbar { + --_tb-bt: var(--theme-topbar-accent-border, 3px solid var(--theme-primary)); + --_tb-h: var(--theme-topbar-height, calc(var(--su-static48) + var(--su-static8))); // CHILD COMPONENT CUSTOM PROPERTIES // Item --_tb-item-bg: unset; @@ -109,6 +111,21 @@ } // CHILD ELEMENTS + &:has(> &--skip-link:focus) { + .s-topbar { + &--container { + height: var(--_tb-h); + } + &--skip-link { + border-bottom: var(--_tb-bt); + } + } + + border-top: none; + display: block; + height: auto; + } + & a&--logo { &:focus-visible { .focus-styles(true); @@ -401,6 +418,20 @@ padding: var(--_tb-searchbar-p); } + & &--skip-link { + &:not(:focus) { + &:extend(.v-visible-sr); + } + + background-color: var(--theme-secondary-100); + border-bottom: var(--_tb-bt); + display: block; + outline: none; + padding: var(--su12); + text-align: center; + } + + .s-navigation { .s-navigation--item { &:not(.is-selected) { @@ -427,13 +458,12 @@ } } - // STATIC COMPONENT STYLES align-items: center; background-color: var(--theme-topbar-background-color, var(--white)); border-bottom: var(--theme-topbar-bottom-border, var(--su-static1) solid var(--black-225)); - border-top: var(--theme-topbar-accent-border, 3px solid var(--theme-primary)); + border-top: var(--_tb-bt); display: flex; - height: var(--theme-topbar-height, calc(var(--su-static48) + var(--su-static8))); + height: var(--_tb-h); min-width: auto; position: relative; width: 100%; diff --git a/lib/components/topbar/topbar.visual.test.ts b/lib/components/topbar/topbar.visual.test.ts index d0ecf2cb53..219aaf0f35 100644 --- a/lib/components/topbar/topbar.visual.test.ts +++ b/lib/components/topbar/topbar.visual.test.ts @@ -122,6 +122,7 @@ const topbarChildren = ({ unsetItem?: boolean; }) => { return ` + Skip to main content
${hamburger ? (hamburger === "unselected" ? children.hamburger.unselected : children.hamburger.selected) : ""} ${children.logo}