diff --git a/src/elements/teaser/readme.md b/src/elements/teaser/readme.md index d81da225bb..4b87c9be20 100644 --- a/src/elements/teaser/readme.md +++ b/src/elements/teaser/readme.md @@ -34,12 +34,31 @@ Using the `alignment` property, it is possible to change the text position respe Possible values are `after-centered` (default), `after` and `below`. ```html - ... + ... ``` By default, the image dimensions are set using the width and the aspect ratio. Default values are `300px` and `4/3`. Consumers can change these values on their slotted image element. +### Flexible Layouts + +If using the teaser in a flexible layout like CSS grid or flex together with `alignment=below`, +the CSS variable `--sbb-teaser-align-items` with `stretch` as value can be used +to achieve the image width taking the full available space. On the image itself, the width must be set to `100%`. + +```html +
+ + + ... + + + + ... + +
+``` + ## Accessibility It's important to set the `accessibilityLabel` on the ``, which describes the `sbb-teaser` for screen-reader users. diff --git a/src/elements/teaser/teaser.scss b/src/elements/teaser/teaser.scss index 370f03a3fa..dce1da9c02 100644 --- a/src/elements/teaser/teaser.scss +++ b/src/elements/teaser/teaser.scss @@ -65,6 +65,7 @@ align-items: var(--sbb-teaser-align-items); gap: var(--sbb-teaser-gap); max-width: 100%; + width: 100%; } .sbb-teaser__text { @@ -73,13 +74,11 @@ } ::slotted([slot='image']) { + width: sbb.px-to-rem-build(300); will-change: transform; display: block; - object-fit: cover; - width: sbb.px-to-rem-build(300); filter: brightness(var(--sbb-teaser-brightness, 1)); transition: var(--sbb-teaser-animation-duration) var(--sbb-animation-easing); - aspect-ratio: 4/3; @include sbb.hover-mq($hover: true) { .sbb-teaser:hover & { @@ -90,6 +89,15 @@ } } +::slotted(sbb-image[slot='image']) { + --sbb-image-aspect-ratio: 4 / 3; +} + +::slotted(img[slot='image']) { + aspect-ratio: 4/3; + object-fit: cover; +} + .sbb-teaser__image-wrapper { flex-shrink: 0; overflow: hidden; diff --git a/src/elements/teaser/teaser.stories.ts b/src/elements/teaser/teaser.stories.ts index dada79b337..fec1a00ad2 100644 --- a/src/elements/teaser/teaser.stories.ts +++ b/src/elements/teaser/teaser.stories.ts @@ -1,14 +1,16 @@ import { withActions } from '@storybook/addon-actions/decorator'; import type { InputType } from '@storybook/types'; -import type { Meta, StoryObj, ArgTypes, Args, Decorator } from '@storybook/web-components'; +import type { Args, ArgTypes, Decorator, Meta, StoryObj } from '@storybook/web-components'; import type { TemplateResult } from 'lit'; import { html } from 'lit'; import { repeat } from 'lit/directives/repeat.js'; import { sbbSpread } from '../../storybook/helpers/spread.js'; +import images from '../core/images.js'; import placeholderImage from './assets/placeholder.png'; import readme from './readme.md?raw'; +import '../image.js'; import './teaser.js'; const loremIpsum: string = `Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor @@ -141,6 +143,25 @@ const TemplateList = (args: Args): TemplateResult => html` `; +const TemplateGrid = ({ description, ...remainingArgs }: Args): TemplateResult => html` +
+ ${repeat( + new Array(4), + () => html` + + + ${description} + + `, + )} +
+`; + export const AfterCentered: StoryObj = { render: TemplateDefault, argTypes: defaultArgTypes, @@ -243,6 +264,12 @@ export const WithSlots: StoryObj = { args: { ...defaultArgs, 'chip-content': 'Chip content' }, }; +export const Grid: StoryObj = { + render: TemplateGrid, + argTypes: defaultArgTypes, + args: { ...defaultArgs, alignment: 'below' }, +}; + const meta: Meta = { decorators: [ (story) => html`
${story()}
`, diff --git a/src/elements/teaser/teaser.visual.spec.ts b/src/elements/teaser/teaser.visual.spec.ts index 9fc693a29e..34101c0059 100644 --- a/src/elements/teaser/teaser.visual.spec.ts +++ b/src/elements/teaser/teaser.visual.spec.ts @@ -12,10 +12,10 @@ import { import { waitForImageReady } from '../core/testing.js'; import './teaser.js'; +import '../image.js'; -const imageBase64 = await loadAssetAsBase64( - import.meta.resolve('../core/testing/assets/placeholder-image.png'), -); +const imageUrl = import.meta.resolve('../core/testing/assets/placeholder-image.png'); +const imageBase64 = await loadAssetAsBase64(imageUrl); describe(`sbb-teaser`, () => { const loremIpsum: string = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer enim elit, ultricies in tincidunt @@ -140,6 +140,31 @@ describe(`sbb-teaser`, () => { ); }); } + + it( + 'grid with sbb-image', + visualDiffDefault.with(async (setup) => { + await setup.withFixture(html` +
+ ${repeat( + new Array(2), + () => html` + + + This is a paragraph + + `, + )} +
+ `); + await waitForImageReady(setup.snapshotElement.querySelector('sbb-image')!); + }), + ); }); } });