Skip to content

Commit

Permalink
fix(sbb-teaser, sbb-teaser-product): allow screen readers to navigate…
Browse files Browse the repository at this point in the history
… the content (#3250)

Co-authored-by: Jeremias Peier <[email protected]>
  • Loading branch information
TomMenga and jeripeierSBB authored Dec 2, 2024
1 parent 2744c8f commit 7ff6552
Show file tree
Hide file tree
Showing 13 changed files with 222 additions and 94 deletions.
6 changes: 5 additions & 1 deletion src/elements/core/base-elements/link-base-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ abstract class SbbLinkBaseElement extends SbbActionBaseElement {

/** Default render method for link-like components. Can be overridden if the LinkRenderVariables are not needed. */
protected override render(): TemplateResult {
return this.renderLink(this.renderTemplate());
}

protected renderLink(renderContent: TemplateResult): TemplateResult {
return html`
<a
class="sbb-action-base ${this.localName}"
Expand All @@ -84,7 +88,7 @@ abstract class SbbLinkBaseElement extends SbbActionBaseElement {
tabindex=${this.maybeDisabled && !this.maybeDisabledInteractive ? '-1' : nothing}
aria-disabled=${this.maybeDisabled ? 'true' : nothing}
>
${this.renderTemplate()}
${renderContent}
${!!this.href && this.target === '_blank'
? html`<sbb-screen-reader-only
>. ${i18nTargetOpensInNewWindow[this.language.current]}</sbb-screen-reader-only
Expand Down
15 changes: 7 additions & 8 deletions src/elements/teaser-product/common/teaser-product-common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
}

.sbb-teaser-product__image-container {
display: block;
overflow: hidden;

// We have to remove the image bottom border-radius when stacked
Expand Down Expand Up @@ -79,11 +78,7 @@
margin-block-start: var(--sbb-spacing-responsive-xxs);
}

.sbb-action-base {
display: block;
position: relative;
text-decoration: none;

.sbb-teaser-product__root {
@include sbb.if-forced-colors {
// Apply a visual border for forced color mode
&::after {
Expand All @@ -98,8 +93,13 @@
}
}

.sbb-teaser-product__container {
.sbb-action-base {
display: block;
position: relative;
text-decoration: none;
}

.sbb-teaser-product__container {
background: var(--sbb-teaser-product-background);
border-radius: 0 0 var(--sbb-teaser-product-border-radius) var(--sbb-teaser-product-border-radius);
padding: var(--sbb-spacing-responsive-s);
Expand Down Expand Up @@ -140,7 +140,6 @@

.sbb-teaser-product__footnote {
grid-area: footnote;
display: block;
padding-block-start: var(--sbb-spacing-responsive-s);
color: var(--sbb-teaser-product-footer-color);

Expand Down
22 changes: 12 additions & 10 deletions src/elements/teaser-product/common/teaser-product-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { property } from 'lit/decorators.js';
import type { SbbActionBaseElement } from '../../core/base-elements.js';
import { slotState } from '../../core/decorators.js';
import {
type AbstractConstructor,
SbbNegativeMixin,
type SbbNegativeMixinType,
type AbstractConstructor,
} from '../../core/mixins.js';

export declare class SbbTeaserProductCommonElementMixinType extends SbbNegativeMixinType {
Expand All @@ -33,15 +33,17 @@ export const SbbTeaserProductCommonElementMixin = <

protected override renderTemplate(): TemplateResult {
return html`
<span class="sbb-teaser-product__image-container"><slot name="image"></slot></span>
<span class="sbb-teaser-product__container">
<span class="sbb-teaser-product__content">
<slot></slot>
</span>
<span class="sbb-teaser-product__footnote">
<slot name="footnote"></slot>
</span>
</span>
<div class="sbb-teaser-product__root">
<div class="sbb-teaser-product__image-container"><slot name="image"></slot></div>
<div class="sbb-teaser-product__container">
<span class="sbb-teaser-product__content">
<slot></slot>
</span>
<div class="sbb-teaser-product__footnote">
<slot name="footnote"></slot>
</div>
</div>
</div>
`;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,22 @@ snapshots["sbb-teaser-product-static renders DOM"] =

snapshots["sbb-teaser-product-static renders Shadow DOM"] =
`<span class="sbb-action-base sbb-teaser-product-static">
<span class="sbb-teaser-product__image-container">
<slot name="image">
</slot>
</span>
<span class="sbb-teaser-product__container">
<span class="sbb-teaser-product__content">
<slot>
<div class="sbb-teaser-product__root">
<div class="sbb-teaser-product__image-container">
<slot name="image">
</slot>
</span>
<span class="sbb-teaser-product__footnote">
<slot name="footnote">
</slot>
</span>
</span>
</div>
<div class="sbb-teaser-product__container">
<span class="sbb-teaser-product__content">
<slot>
</slot>
</span>
<div class="sbb-teaser-product__footnote">
<slot name="footnote">
</slot>
</div>
</div>
</div>
</span>
`;
/* end snapshot sbb-teaser-product-static renders Shadow DOM */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,31 @@ snapshots["sbb-teaser-product renders DOM"] =
/* end snapshot sbb-teaser-product renders DOM */

snapshots["sbb-teaser-product renders Shadow DOM"] =
`<a
class="sbb-action-base sbb-teaser-product"
href="https://www.sbb.ch"
>
<span class="sbb-teaser-product__image-container">
<slot name="image">
</slot>
</span>
<span class="sbb-teaser-product__container">
<span class="sbb-teaser-product__content">
<slot>
</slot>
</span>
<span class="sbb-teaser-product__footnote">
<slot name="footnote">
`<div class="sbb-teaser-product__wrapper">
<a
class="sbb-action-base sbb-teaser-product"
href="https://www.sbb.ch"
>
<sbb-screen-reader-only>
</sbb-screen-reader-only>
</a>
<div class="sbb-teaser-product__root">
<div class="sbb-teaser-product__image-container">
<slot name="image">
</slot>
</span>
</span>
</a>
</div>
<div class="sbb-teaser-product__container">
<span class="sbb-teaser-product__content">
<slot>
</slot>
</span>
<div class="sbb-teaser-product__footnote">
<slot name="footnote">
</slot>
</div>
</div>
</div>
</div>
`;
/* end snapshot sbb-teaser-product renders Shadow DOM */

Expand All @@ -59,8 +65,16 @@ snapshots["sbb-teaser-product renders A11y tree Firefox"] =
"children": [
{
"role": "link",
"name": "Content Footnote",
"name": "",
"value": "https://www.sbb.ch/"
},
{
"role": "text leaf",
"name": "Content"
},
{
"role": "text leaf",
"name": "Footnote"
}
]
}
Expand All @@ -76,7 +90,15 @@ snapshots["sbb-teaser-product renders A11y tree Chrome"] =
"children": [
{
"role": "link",
"name": "Content Footnote"
"name": ""
},
{
"role": "text",
"name": "Content"
},
{
"role": "text",
"name": "Footnote"
}
]
}
Expand Down
44 changes: 31 additions & 13 deletions src/elements/teaser-product/teaser-product/teaser-product.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
);
--sbb-teaser-product-animation-easing: var(--sbb-animation-easing);
--sbb-teaser-product-border-radius: var(--sbb-border-radius-4x);

// Simulate link color optically
@include sbb.if-forced-colors {
--sbb-title-text-color-normal-override: LinkText !important;
--sbb-teaser-product-content-color: LinkText !important;
--sbb-teaser-product-footer-color: LinkText !important;
}
}

:host(:hover) {
Expand All @@ -16,14 +23,20 @@
}
}

.sbb-teaser-product {
&:focus-visible {
:host(:not([data-focus-origin='mouse'], [data-focus-origin='touch'])) & {
@include sbb.focus-outline;
::slotted(:is(img, sbb-image)) {
will-change: filter;
transition-property: filter;
transition-duration: var(--sbb-teaser-product-animation-duration);
transition-timing-function: var(--sbb-animation-easing);
filter: brightness(var(--sbb-teaser-product-brightness, 1));
}

border-radius: var(--sbb-teaser-product-border-radius);
}
}
.sbb-teaser-product__wrapper {
position: relative;
}

.sbb-teaser-product__root {
pointer-events: none;

@include sbb.if-forced-colors {
&::after {
Expand All @@ -34,10 +47,15 @@
}
}

::slotted(:is(img, sbb-image)) {
will-change: filter;
transition-property: filter;
transition-duration: var(--sbb-teaser-product-animation-duration);
transition-timing-function: var(--sbb-animation-easing);
filter: brightness(var(--sbb-teaser-product-brightness, 1));
.sbb-teaser-product {
position: absolute;
inset: 0;

&:focus-visible {
:host(:not([data-focus-origin='mouse'], [data-focus-origin='touch'])) & {
@include sbb.focus-outline;

border-radius: var(--sbb-teaser-product-border-radius);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import type {
StoryContext,
StoryObj,
} from '@storybook/web-components';
import { nothing, type TemplateResult } from 'lit';
import { html } from 'lit';
import { html, nothing, type TemplateResult } from 'lit';

import { sbbSpread } from '../../../storybook/helpers/spread.js';
import sampleImages from '../../core/images.js';

import readme from './readme.md?raw';

import './teaser-product.js';
import '../../button/button-static.js';
import '../../image.js';
Expand Down Expand Up @@ -78,7 +78,7 @@ const defaultArgs: Args = {
withFooter: true,
slottedImg: false,
href: 'https://www.sbb.ch',
'accessibility-label': undefined,
'accessibility-label': 'Benefit from up to 70% discount, Follow the link to benefit.',
};

const content = (): TemplateResult => html`
Expand Down
18 changes: 17 additions & 1 deletion src/elements/teaser-product/teaser-product/teaser-product.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import type { CSSResultGroup } from 'lit';
import type { CSSResultGroup, TemplateResult } from 'lit';
import { customElement } from 'lit/decorators.js';
import { html } from 'lit/static-html.js';

import { SbbLinkBaseElement } from '../../core/base-elements.js';
import { SbbTeaserProductCommonElementMixin, teaserProductCommonStyle } from '../common.js';

import style from './teaser-product.scss?lit&inline';

import '../../screen-reader-only.js';

/**
* Displays a text and a footnote, combined with an image, to tease a product
*
Expand All @@ -19,6 +22,19 @@ export
@customElement('sbb-teaser-product')
class SbbTeaserProductElement extends SbbTeaserProductCommonElementMixin(SbbLinkBaseElement) {
public static override styles: CSSResultGroup = [teaserProductCommonStyle, style];

protected override render(): TemplateResult {
// We render the content outside the anchor tag to allow screen readers to navigate through it
return html`
<div class="sbb-teaser-product__wrapper">
${this.renderLink(
// For SEO we add the accessibility hidden as hidden content of the link
html`<sbb-screen-reader-only>${this.accessibilityLabel}</sbb-screen-reader-only>`,
)}
${this.renderTemplate()}
</div>
`;
}
}

declare global {
Expand Down
Loading

0 comments on commit 7ff6552

Please sign in to comment.