From 117b38c9830caded8cfeae9beddbdee737db79f8 Mon Sep 17 00:00:00 2001 From: Marius Bleuer Date: Mon, 22 Apr 2024 09:35:28 +0200 Subject: [PATCH 1/5] fix: enabling a flexible aspect ratio through the use of a css variable --- src/components/image/image.scss | 2 +- src/components/image/image.ts | 6 ++++++ src/components/image/readme.md | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/image/image.scss b/src/components/image/image.scss index 0189465a37..22095daf86 100644 --- a/src/components/image/image.scss +++ b/src/components/image/image.scss @@ -54,7 +54,7 @@ // aspect ratios 'free', '1-1', '1-2', '2-1', '2-3', '3-2', '3-4', '4-3', '4-5', '5-4', '9-16', '16-9' .image__figure--ratio-free .image__wrapper { - aspect-ratio: auto; + aspect-ratio: var(--image-aspect-ratio, auto); } .image__figure--ratio-1-1 .image__wrapper { diff --git a/src/components/image/image.ts b/src/components/image/image.ts index c7515ca941..fa0381219c 100644 --- a/src/components/image/image.ts +++ b/src/components/image/image.ts @@ -275,6 +275,12 @@ export class SbbImageElement extends LitElement { * Set an aspect ratio * default is '16-9' (16/9) * other values: 'free', '1-1', '1-2', '2-1', '2-3', '3-2', '3-4', '4-3', '4-5', '5-4', '9-16' + * If the aspectRatio value is set to 'free', the component sets the CSS declaration to + * aspect-ratio: var(--image-aspect-ratio, auto);. This allows you to enter the value for + * the CSS variable --image-aspect-ratio from outside the component. The CSS variable finds + * its way into the shadow DOM. If the CSS variable is not explicitly set, its value will + * fallback to "auto". This way you can have, for example, an image component with an aspect + * ratio of 4/3 in smaller viewports and 16/9 in larger viewports. */ @property({ attribute: 'aspect-ratio' }) public aspectRatio: InterfaceImageAttributes['aspectRatio'] = '16-9'; diff --git a/src/components/image/readme.md b/src/components/image/readme.md index bfee211e7a..29b0ab6a3a 100644 --- a/src/components/image/readme.md +++ b/src/components/image/readme.md @@ -25,5 +25,5 @@ The size can be set with `pictureSizesConfig`. | `performanceMark` | `performance-mark` | public | `string \| undefined` | | With performance.mark you can log a timestamp associated with the name you define in performanceMark when a certain event is happening. In our case we will log the performance.mark into the PerformanceEntry API once the image is fully loaded. Performance monitoring tools like SpeedCurve or Lighthouse are then able to grab these entries from the PerformanceEntry API and give us additional information and insights about our page loading behaviour. We are then also able to monitor these values over a long period to see if our performance increases or decreases over time. Best to use lowercase strings here, separate words with underscores or dashes. | | `pictureSizesConfig` | `picture-sizes-config` | public | `string \| undefined` | | With the pictureSizesConfig object, you can pass in information into image about what kind of source elements should get rendered. mediaQueries accepts multiple Media Query entries which can get combined by defining a conditionOperator. Type is: stringified InterfaceImageAttributesSizesConfig-Object An example could look like this: { "breakpoints": \[ { "image": { "height": "675", "width": "1200" }, "mediaQueries": \[ { "conditionFeature": "min-width", "conditionFeatureValue": { "lyneDesignToken": true, "value": "sbb-breakpoint-large-min" }, "conditionOperator": false } ] }, { "image": { "height": "549", "width": "976" }, "mediaQueries": \[ { "conditionFeature": "min-width", "conditionFeatureValue": { "lyneDesignToken": true, "value": "sbb-breakpoint-small-min" }, "conditionOperator": false } ] }, { "image": { "height": "180", "width": "320" }, "mediaQueries": \[ { "conditionFeature": "max-width", "conditionFeatureValue": { "lyneDesignToken": true, "value": "sbb-breakpoint-micro-max" }, "conditionOperator": "and" }, { "conditionFeature": "orientation", "conditionFeatureValue": { "lyneDesignToken": false, "value": "landscape" }, "conditionOperator": false } ] } ] } | | `borderRadius` | `border-radius` | public | `'default' \| 'none' \| 'round'` | `'default'` | Border radius of the image. Choose between a default radius, no radius and a completely round image. | -| `aspectRatio` | `aspect-ratio` | public | `InterfaceImageAttributes['aspectRatio']` | `'16-9'` | Set an aspect ratio default is '16-9' (16/9) other values: 'free', '1-1', '1-2', '2-1', '2-3', '3-2', '3-4', '4-3', '4-5', '5-4', '9-16' | +| `aspectRatio` | `aspect-ratio` | public | `InterfaceImageAttributes['aspectRatio']` | `'16-9'` | Set an aspect ratio default is '16-9' (16/9) other values: 'free', '1-1', '1-2', '2-1', '2-3', '3-2', '3-4', '4-3', '4-5', '5-4', '9-16' If the aspectRatio value is set to 'free', the component sets the CSS declaration to aspect-ratio: var(--image-aspect-ratio, auto);. This allows you to pass in the value for the CSS variable --image-aspect-ratio from outside the component. The CSS variable will find its way into the Shadow DOM. If the CSS variable is is not explicitly set, its value will fallback to 'auto'. That way you can e.g. have an image component with an aspect ratio of 4/3 in smaller viewports and 16/9 in larger ones. | | `disableAnimation` | `disable-animation` | public | `boolean` | `false` | Whether the fade animation from blurred to real image should be disabled. | From f68844807512f8b8ffc6195aa67e3718fafb4645 Mon Sep 17 00:00:00 2001 From: Marius Bleuer Date: Mon, 22 Apr 2024 09:39:53 +0200 Subject: [PATCH 2/5] fix: even if there is not alt text, the attribute must always be present for assistive technolgies --- src/components/image/image.e2e.ts | 2 +- src/components/image/image.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/image/image.e2e.ts b/src/components/image/image.e2e.ts index fa31448834..fd14b825cc 100644 --- a/src/components/image/image.e2e.ts +++ b/src/components/image/image.e2e.ts @@ -41,7 +41,7 @@ describe(`sbb-image with ${fixture.name}`, () => { - + diff --git a/src/components/image/image.ts b/src/components/image/image.ts index fa0381219c..18baa01d81 100644 --- a/src/components/image/image.ts +++ b/src/components/image/image.ts @@ -507,7 +507,7 @@ export class SbbImageElement extends LitElement { ]; })} ${this.alt Date: Mon, 22 Apr 2024 10:56:08 +0200 Subject: [PATCH 3/5] fix: updating read.me --- src/components/image/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/image/readme.md b/src/components/image/readme.md index 29b0ab6a3a..980e78f234 100644 --- a/src/components/image/readme.md +++ b/src/components/image/readme.md @@ -25,5 +25,5 @@ The size can be set with `pictureSizesConfig`. | `performanceMark` | `performance-mark` | public | `string \| undefined` | | With performance.mark you can log a timestamp associated with the name you define in performanceMark when a certain event is happening. In our case we will log the performance.mark into the PerformanceEntry API once the image is fully loaded. Performance monitoring tools like SpeedCurve or Lighthouse are then able to grab these entries from the PerformanceEntry API and give us additional information and insights about our page loading behaviour. We are then also able to monitor these values over a long period to see if our performance increases or decreases over time. Best to use lowercase strings here, separate words with underscores or dashes. | | `pictureSizesConfig` | `picture-sizes-config` | public | `string \| undefined` | | With the pictureSizesConfig object, you can pass in information into image about what kind of source elements should get rendered. mediaQueries accepts multiple Media Query entries which can get combined by defining a conditionOperator. Type is: stringified InterfaceImageAttributesSizesConfig-Object An example could look like this: { "breakpoints": \[ { "image": { "height": "675", "width": "1200" }, "mediaQueries": \[ { "conditionFeature": "min-width", "conditionFeatureValue": { "lyneDesignToken": true, "value": "sbb-breakpoint-large-min" }, "conditionOperator": false } ] }, { "image": { "height": "549", "width": "976" }, "mediaQueries": \[ { "conditionFeature": "min-width", "conditionFeatureValue": { "lyneDesignToken": true, "value": "sbb-breakpoint-small-min" }, "conditionOperator": false } ] }, { "image": { "height": "180", "width": "320" }, "mediaQueries": \[ { "conditionFeature": "max-width", "conditionFeatureValue": { "lyneDesignToken": true, "value": "sbb-breakpoint-micro-max" }, "conditionOperator": "and" }, { "conditionFeature": "orientation", "conditionFeatureValue": { "lyneDesignToken": false, "value": "landscape" }, "conditionOperator": false } ] } ] } | | `borderRadius` | `border-radius` | public | `'default' \| 'none' \| 'round'` | `'default'` | Border radius of the image. Choose between a default radius, no radius and a completely round image. | -| `aspectRatio` | `aspect-ratio` | public | `InterfaceImageAttributes['aspectRatio']` | `'16-9'` | Set an aspect ratio default is '16-9' (16/9) other values: 'free', '1-1', '1-2', '2-1', '2-3', '3-2', '3-4', '4-3', '4-5', '5-4', '9-16' If the aspectRatio value is set to 'free', the component sets the CSS declaration to aspect-ratio: var(--image-aspect-ratio, auto);. This allows you to pass in the value for the CSS variable --image-aspect-ratio from outside the component. The CSS variable will find its way into the Shadow DOM. If the CSS variable is is not explicitly set, its value will fallback to 'auto'. That way you can e.g. have an image component with an aspect ratio of 4/3 in smaller viewports and 16/9 in larger ones. | +| `aspectRatio` | `aspect-ratio` | public | `InterfaceImageAttributes['aspectRatio']` | `'16-9'` | Set an aspect ratio default is '16-9' (16/9) other values: 'free', '1-1', '1-2', '2-1', '2-3', '3-2', '3-4', '4-3', '4-5', '5-4', '9-16' If the aspectRatio value is set to 'free', the component sets the CSS declaration to aspect-ratio: var(--image-aspect-ratio, auto);. This allows you to enter the value for the CSS variable --image-aspect-ratio from outside the component. The CSS variable finds its way into the shadow DOM. If the CSS variable is not explicitly set, its value will fallback to "auto". This way you can have, for example, an image component with an aspect ratio of 4/3 in smaller viewports and 16/9 in larger viewports. | | `disableAnimation` | `disable-animation` | public | `boolean` | `false` | Whether the fade animation from blurred to real image should be disabled. | From 44d1b2e1643f30812c41784b638357d4ff1d0e86 Mon Sep 17 00:00:00 2001 From: Marius Bleuer Date: Mon, 22 Apr 2024 13:52:19 +0200 Subject: [PATCH 4/5] fix: prefixing new variable and adding cssprop documentation --- src/components/image/image.scss | 2 +- src/components/image/image.ts | 14 ++++++++------ src/components/image/readme.md | 8 +++++++- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/components/image/image.scss b/src/components/image/image.scss index 22095daf86..146b21bd2b 100644 --- a/src/components/image/image.scss +++ b/src/components/image/image.scss @@ -54,7 +54,7 @@ // aspect ratios 'free', '1-1', '1-2', '2-1', '2-3', '3-2', '3-4', '4-3', '4-5', '5-4', '9-16', '16-9' .image__figure--ratio-free .image__wrapper { - aspect-ratio: var(--image-aspect-ratio, auto); + aspect-ratio: var(--sbb-image-aspect-ratio, auto); } .image__figure--ratio-1-1 .image__wrapper { diff --git a/src/components/image/image.ts b/src/components/image/image.ts index 18baa01d81..c3c5130a72 100644 --- a/src/components/image/image.ts +++ b/src/components/image/image.ts @@ -59,6 +59,14 @@ const breakpointMap: Record = { /** * It displays an image. + * + * @cssprop [--sbb-image-aspect-ratio=auto] - When the aspectRatio property + * on the component is set to 'free', the CSS declaration of the aspect + * ratio is set to var(--sbb-image-aspect-ratio, auto). Since CSS + * variables find their way into the shadow DOM, we can use the + * --sbb-image-aspect-ratio variable to override the aspect ratio at will. + * This way we can have, for example, an image component with an aspect + * ratio of 4/3 in smaller viewports and 16/9 in larger viewports. */ @customElement('sbb-image') export class SbbImageElement extends LitElement { @@ -275,12 +283,6 @@ export class SbbImageElement extends LitElement { * Set an aspect ratio * default is '16-9' (16/9) * other values: 'free', '1-1', '1-2', '2-1', '2-3', '3-2', '3-4', '4-3', '4-5', '5-4', '9-16' - * If the aspectRatio value is set to 'free', the component sets the CSS declaration to - * aspect-ratio: var(--image-aspect-ratio, auto);. This allows you to enter the value for - * the CSS variable --image-aspect-ratio from outside the component. The CSS variable finds - * its way into the shadow DOM. If the CSS variable is not explicitly set, its value will - * fallback to "auto". This way you can have, for example, an image component with an aspect - * ratio of 4/3 in smaller viewports and 16/9 in larger viewports. */ @property({ attribute: 'aspect-ratio' }) public aspectRatio: InterfaceImageAttributes['aspectRatio'] = '16-9'; diff --git a/src/components/image/readme.md b/src/components/image/readme.md index 980e78f234..f36e5dba36 100644 --- a/src/components/image/readme.md +++ b/src/components/image/readme.md @@ -25,5 +25,11 @@ The size can be set with `pictureSizesConfig`. | `performanceMark` | `performance-mark` | public | `string \| undefined` | | With performance.mark you can log a timestamp associated with the name you define in performanceMark when a certain event is happening. In our case we will log the performance.mark into the PerformanceEntry API once the image is fully loaded. Performance monitoring tools like SpeedCurve or Lighthouse are then able to grab these entries from the PerformanceEntry API and give us additional information and insights about our page loading behaviour. We are then also able to monitor these values over a long period to see if our performance increases or decreases over time. Best to use lowercase strings here, separate words with underscores or dashes. | | `pictureSizesConfig` | `picture-sizes-config` | public | `string \| undefined` | | With the pictureSizesConfig object, you can pass in information into image about what kind of source elements should get rendered. mediaQueries accepts multiple Media Query entries which can get combined by defining a conditionOperator. Type is: stringified InterfaceImageAttributesSizesConfig-Object An example could look like this: { "breakpoints": \[ { "image": { "height": "675", "width": "1200" }, "mediaQueries": \[ { "conditionFeature": "min-width", "conditionFeatureValue": { "lyneDesignToken": true, "value": "sbb-breakpoint-large-min" }, "conditionOperator": false } ] }, { "image": { "height": "549", "width": "976" }, "mediaQueries": \[ { "conditionFeature": "min-width", "conditionFeatureValue": { "lyneDesignToken": true, "value": "sbb-breakpoint-small-min" }, "conditionOperator": false } ] }, { "image": { "height": "180", "width": "320" }, "mediaQueries": \[ { "conditionFeature": "max-width", "conditionFeatureValue": { "lyneDesignToken": true, "value": "sbb-breakpoint-micro-max" }, "conditionOperator": "and" }, { "conditionFeature": "orientation", "conditionFeatureValue": { "lyneDesignToken": false, "value": "landscape" }, "conditionOperator": false } ] } ] } | | `borderRadius` | `border-radius` | public | `'default' \| 'none' \| 'round'` | `'default'` | Border radius of the image. Choose between a default radius, no radius and a completely round image. | -| `aspectRatio` | `aspect-ratio` | public | `InterfaceImageAttributes['aspectRatio']` | `'16-9'` | Set an aspect ratio default is '16-9' (16/9) other values: 'free', '1-1', '1-2', '2-1', '2-3', '3-2', '3-4', '4-3', '4-5', '5-4', '9-16' If the aspectRatio value is set to 'free', the component sets the CSS declaration to aspect-ratio: var(--image-aspect-ratio, auto);. This allows you to enter the value for the CSS variable --image-aspect-ratio from outside the component. The CSS variable finds its way into the shadow DOM. If the CSS variable is not explicitly set, its value will fallback to "auto". This way you can have, for example, an image component with an aspect ratio of 4/3 in smaller viewports and 16/9 in larger viewports. | +| `aspectRatio` | `aspect-ratio` | public | `InterfaceImageAttributes['aspectRatio']` | `'16-9'` | Set an aspect ratio default is '16-9' (16/9) other values: 'free', '1-1', '1-2', '2-1', '2-3', '3-2', '3-4', '4-3', '4-5', '5-4', '9-16' | | `disableAnimation` | `disable-animation` | public | `boolean` | `false` | Whether the fade animation from blurred to real image should be disabled. | + +## CSS Properties + +| Name | Default | Description | +| -------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--sbb-image-aspect-ratio` | `auto` | When the aspectRatio property on the component is set to 'free', the CSS declaration of the aspect ratio is set to var(--sbb-image-aspect-ratio, auto). Since CSS variables find their way into the shadow DOM, we can use the --sbb-image-aspect-ratio variable to override the aspect ratio at will. This way we can have, for example, an image component with an aspect ratio of 4/3 in smaller viewports and 16/9 in larger viewports. | From ade920a7b7b61ee14c92157876339cb5065a7a5f Mon Sep 17 00:00:00 2001 From: Marius Bleuer Date: Mon, 22 Apr 2024 13:53:48 +0200 Subject: [PATCH 5/5] fix: adding comment to explain the need for the alt attribute --- src/components/image/image.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/image/image.ts b/src/components/image/image.ts index c3c5130a72..f5a95c6ad4 100644 --- a/src/components/image/image.ts +++ b/src/components/image/image.ts @@ -465,6 +465,12 @@ export class SbbImageElement extends LitElement { const pictureSizeConfigs = this._preparePictureSizeConfigs(); + /** + * The alt attribute should always be present for the img element. + * If it has an empty string as its value, it is simply ignored + * by assistive technologies. If we leave it out completely, + * they might try to interpret the img element. + */ return html`