Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sbb-image): support overlapping sbb-chip-label #3200

Merged
merged 56 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
865623d
refactor(sbb-image): extract 'caption' and 'copyright' feature
TomMenga Oct 30, 2024
d8835a1
style(image): extract mixin
TomMenga Nov 4, 2024
8b2f2be
refactor(sbb-teaser-hero, sbb-teaser-product): adapt sbb-image usages
TomMenga Nov 6, 2024
9c3105e
Merge branch 'refs/heads/main' into feat/sbb-image-cleanup
TomMenga Nov 6, 2024
a4ba481
refactor(sbb-teaser): adapt sbb-image usages
TomMenga Nov 6, 2024
4f1fcba
refactor(sbb-image): convert 'aspect-ratio' and 'border-radius' to cl…
TomMenga Nov 6, 2024
838819a
refactor(sbb-image): update tests
TomMenga Nov 7, 2024
826fdaa
refactor(sbb-image): update snapshots
TomMenga Nov 7, 2024
cdfa330
test(sbb-image): fix visual spec
TomMenga Nov 11, 2024
42b1ac1
Merge branch 'refs/heads/main' into feat/sbb-image-cleanup
TomMenga Nov 11, 2024
d398703
test(sbb-image): fix visual spec
TomMenga Nov 11, 2024
c3512d4
style(sbb-image): cleanup
TomMenga Nov 12, 2024
9711435
style(image-mixin): fix figure layout
TomMenga Nov 13, 2024
eb26631
test(sbb-image): fix visual spec
TomMenga Nov 13, 2024
94152d7
fix: review feedbacks
TomMenga Nov 20, 2024
2f247be
Merge branch 'refs/heads/main' into feat/sbb-image-cleanup
TomMenga Nov 20, 2024
d6debce
fix: review feedbacks
TomMenga Nov 20, 2024
540e46c
Merge branch 'refs/heads/main' into feat/sbb-image-cleanup
TomMenga Nov 22, 2024
64e88ed
fix: pr feedbacks
TomMenga Nov 29, 2024
faf94b0
Merge branch 'refs/heads/main' into feat/sbb-image-cleanup
TomMenga Nov 29, 2024
39c1469
fix: pr feedbacks pt.2
TomMenga Nov 29, 2024
56fc8ae
test(sbb-flip-card): fix visual spec
TomMenga Nov 29, 2024
b463ea1
Merge branch 'refs/heads/main' into feat/sbb-image-cleanup
TomMenga Dec 2, 2024
ae475d6
Merge branch 'refs/heads/main' into feat/sbb-image-cleanup
TomMenga Dec 2, 2024
1a6c954
fix: pr feedbacks pt.1
TomMenga Dec 3, 2024
a55826a
refactor(sbb-image): removed dependency from teaser-hero
TomMenga Dec 3, 2024
55a12dc
docs(sbb-image): only suggest to use 'figure' when needed
TomMenga Dec 3, 2024
09a5bb0
docs(sbb-teaser-hero): only suggest to use 'figure' when needed
TomMenga Dec 3, 2024
eadd675
docs(sbb-teaser-product, sbb-teaser-product-static): only use 'figure…
TomMenga Dec 3, 2024
714be9c
fix: pr feedbacks pt.2
TomMenga Dec 3, 2024
b7ed26c
fix: pr feedbacks pt.3
TomMenga Dec 3, 2024
ba3bee8
fix: pr feedbacks pt.4
TomMenga Dec 3, 2024
68b0175
fix: pr feedbacks pt.5
TomMenga Dec 3, 2024
d74e7a0
fix(sbb-teaser-product): fix visual spec
TomMenga Dec 4, 2024
b321a86
fix(sbb-teaser-hero): fix support of img slotting
TomMenga Dec 4, 2024
fecce08
fix: pr feedbacks pt.6
TomMenga Dec 4, 2024
7610558
chore: empty commit
TomMenga Dec 4, 2024
448f856
fix(sbb-teaser-hero): fix visual spec
TomMenga Dec 4, 2024
38f8dd1
fix: move border radius to host
jeripeierSBB Dec 4, 2024
bdc88bb
docs(sbb-image): update readme
TomMenga Dec 4, 2024
2c92877
fix: pr feedbacks pt.8
TomMenga Dec 4, 2024
2b6341d
fix: pr feedbacks pt.8
TomMenga Dec 4, 2024
7e651a8
docs: improve teaser-hero docs
jeripeierSBB Dec 5, 2024
3ec8827
fix: fix teaser product height styling
jeripeierSBB Dec 5, 2024
61a3a7f
style(img): use generic variables for ratio, fit and position
TomMenga Dec 5, 2024
31fb147
feat(sbb-container): support the use of `figure` as bg image
TomMenga Dec 5, 2024
385cfcd
feat(sbb-lead-container): support the use of `figure` as lead image
TomMenga Dec 9, 2024
1f875ef
feat(sbb-flip-card): support the use of `figure` as image
TomMenga Dec 9, 2024
ab9cb93
feat(sbb-container): support the use of `figure` as bg image pt.2
TomMenga Dec 9, 2024
8e520df
Merge branch 'refs/heads/main' into feat/sbb-image-cleanup
TomMenga Dec 9, 2024
1696197
feat(sbb-lead-container): support the use of `figure` as bg image pt.2
TomMenga Dec 9, 2024
87aacf7
feat: support the use of `figure` as image pt.2
TomMenga Dec 9, 2024
9feca0d
feat(sbb-flip-card): support the use of `figure` as image pt.2
TomMenga Dec 10, 2024
155767d
docs: add overlap chip doc
TomMenga Dec 11, 2024
ee5d129
Merge branch 'refs/heads/main' into feat/sbb-image-cleanup
TomMenga Dec 11, 2024
fcd0dc1
fix: post-merge fix
TomMenga Dec 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 8 additions & 14 deletions src/elements/container/container/container.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
@include sbb.box-sizing;

:host {
--sbb-container-background-border-radius: 0;

display: block;
}

Expand All @@ -28,6 +30,12 @@
position: relative;
}

:host(:not([expanded], [background-expanded])) {
@include sbb.mq($from: ultra) {
--sbb-container-background-border-radius: var(--sbb-border-radius-4x);
}
}

.sbb-container {
background-color: var(--sbb-container-background-color);
padding: var(--sbb-container-padding);
Expand Down Expand Up @@ -62,22 +70,8 @@
}

::slotted([slot='image']) {
--sbb-image-border-radius: 0;

position: absolute;
inset: 0;

:host(:not([expanded], [background-expanded])) & {
@include sbb.mq($from: ultra) {
--sbb-image-border-radius: var(--sbb-border-radius-4x);

border-radius: var(--sbb-border-radius-4x);
}
}
}

::slotted(img[slot='image']) {
object-fit: cover;
height: 100%;
width: 100%;
}
54 changes: 37 additions & 17 deletions src/elements/container/container/container.visual.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { waitForImageReady } from '../../core/testing.js';

import '../../button.js';
import '../../card.js';
import '../../chip-label.js';
import '../../image.js';
import '../../title.js';
import './container.js';
Expand All @@ -25,17 +26,35 @@ describe(`sbb-container`, () => {

const images = [
{
name: 'sbb-image',
selector: 'sbb-image',
image: html`<sbb-image slot="image" image-src=${imageUrl}></sbb-image>`,
},
{
name: 'figure-sbb-image',
TomMenga marked this conversation as resolved.
Show resolved Hide resolved
selector: 'sbb-image',
image: html`<figure slot="image" class="sbb-figure">
<sbb-image image-src=${imageUrl}></sbb-image>
<sbb-chip-label class="sbb-figure-overlap-start-end">AI generated</sbb-chip-label>
</figure>`,
},
{
name: 'img',
selector: 'img',
image: html`<img
slot="image"
src=${imageBase64}
alt=''
></img>`,
},
{
name: 'figure-img',
selector: 'img',
image: html`<figure slot="image" class="sbb-figure">
<img src=${imageBase64} alt="" />
<sbb-chip-label class="sbb-figure-overlap-start-end">AI generated</sbb-chip-label>
</figure>`,
},
];

const containerContent = (): TemplateResult => html`
Expand Down Expand Up @@ -88,7 +107,7 @@ describe(`sbb-container`, () => {
describe(`expanded=${expanded}`, () => {
for (const image of images) {
it(
`slotted=${image.selector}`,
`slotted=${image.name}`,
visualDiffDefault.with(async (setup) => {
await setup.withFixture(
html`<sbb-container ?expanded=${expanded}>
Expand Down Expand Up @@ -146,23 +165,24 @@ describe(`sbb-container`, () => {
}),
);

it(
`background-image`,
visualDiffDefault.with(async (setup) => {
await setup.withFixture(
html`
<sbb-container ?background-expanded=${backgroundExpanded}>
${backgroundImageContent}
<sbb-image slot="image" image-src=${imageUrl}></sbb-image>
</sbb-container>
`,
wrapperStyles,
);
for (const image of images) {
it(
`background-image slotted=${image.name}`,
visualDiffDefault.with(async (setup) => {
await setup.withFixture(
html`
<sbb-container ?background-expanded=${backgroundExpanded}>
${backgroundImageContent} ${image.image}
</sbb-container>
`,
wrapperStyles,
);

await setViewport(viewport);
await waitForImageReady(setup.snapshotElement.querySelector('sbb-image')!);
}),
);
await setViewport(viewport);
await waitForImageReady(setup.snapshotElement.querySelector(image.selector)!);
}),
);
}
});
}
});
15 changes: 15 additions & 0 deletions src/elements/container/container/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@ use CSS object-position for slotted `img`, or `--sbb-image-object-position` vari
If an image is present, the container receives a pre-defined padding.
It's possible to override the padding by using the CSS variable `--sbb-container-padding`.

Optionally, you can add an overlapping `sbb-chip-label` by wrapping the `sbb-image` in a `figure` tag (see [sbb-image doc](/docs/elements-sbb-image--docs#utility%classes)).

```html
<sbb-container>
<figure class="sbb-figure" slot="image">
<sbb-image
image-src="https://cdn.img.sbb.ch/content/dam/internet/lyne/Bahnhof-Luzern.jpg"
alt="Station of Lucerne from outside"
></sbb-image>
<sbb-chip-label class="sbb-figure-overlap-start-start">...</sbb-chip-label>
</figure>
...
</sbb-container>
```

## Style

By default `sbb-container` uses the `page spacing` defined in the [layout documentation](/docs/styles-layout--docs). Optionally the user can use the `expanded` property (default: `false`) to switch to the `page spacing expanded` layout.
Expand Down
1 change: 1 addition & 0 deletions src/elements/core/styles/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
@forward './mixins/chip';
@forward './mixins/font-face';
@forward './mixins/helpers';
@forward './mixins/image';
@forward './mixins/inputs';
@forward './mixins/layout';
@forward './mixins/link';
Expand Down
115 changes: 115 additions & 0 deletions src/elements/core/styles/core.scss
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,121 @@ input[data-sbb-time-input] {
}
}

img {
aspect-ratio: var(--sbb-image-aspect-ratio);
object-fit: var(--sbb-image-object-fit);
object-position: var(--sbb-image-object-position);
}

// TODO: Move back to the sbb-container components when the global css refactoring happens
sbb-container {
[slot='image']:is(sbb-image, img),
[slot='image'] :is(sbb-image, img) {
--sbb-image-object-fit: cover;

border-radius: var(--sbb-container-background-border-radius);
height: 100%;
position: absolute;
jeripeierSBB marked this conversation as resolved.
Show resolved Hide resolved
}
}

// TODO: Move back to the sbb-flip-card-summary components when the global css refactoring happens
sbb-flip-card-summary {
[slot='image']:is(sbb-image, img),
[slot='image'] :is(sbb-image, img) {
--sbb-image-aspect-ratio: auto;
--sbb-image-object-fit: cover;

border-radius: 0;
display: block;
height: 100%;
}
}

// TODO: Move back to the sbb-lead-container components when the global css refactoring happens
sbb-lead-container {
[slot='image']:is(sbb-image, img, picture),
[slot='image'] :is(sbb-image, img, picture) {
--sbb-image-aspect-ratio: var(--sbb-lead-container-image-ratio);
--sbb-image-object-fit: cover;

border-radius: var(--sbb-lead-container-image-border-radius);
}
}

// Target the slotted `sbb-image` which are generally wrapped by a <figure> (therefore are not reachable with the :slotted)
// Apply the brightness effect on mouse hover
// TODO: Move back to the teaser components when the global css refactoring happens
:is(sbb-teaser, sbb-teaser-hero, sbb-teaser-product) {
--sbb-teaser-image-brightness-hover: var(--sbb-hover-image-brightness);
--sbb-teaser-image-animation-duration: var(
--sbb-disable-animation-duration,
var(--sbb-animation-duration-4x)
);
--sbb-teaser-image-animation-easing: var(--sbb-animation-easing);

&:hover {
@include mediaqueries.hover-mq($hover: true) {
--sbb-teaser-image-brightness: var(--sbb-teaser-image-brightness-hover);
}
}

[slot='image']:is(sbb-image, img),
[slot='image'] :is(sbb-image, img) {
will-change: filter;
filter: brightness(var(--sbb-teaser-image-brightness, 1));
transition: filter var(--sbb-teaser-image-animation-duration)
var(--sbb-teaser-image-animation-easing);
}
}

// TODO: Move back to the teaser components when the global css refactoring happens
:is(sbb-teaser-product, sbb-teaser-product-static) {
:is(sbb-image, img) {
border-radius: 0; // Reset sbb-image border radius in order to control it from teaser product.

--sbb-image-object-fit: cover;
--sbb-image-aspect-ratio: 16 / 9;
}

img {
place-self: stretch;
}
}

// TODO: Move back to the teaser components when the global css refactoring happens
:is(sbb-teaser) {
TomMenga marked this conversation as resolved.
Show resolved Hide resolved
[slot='image']:is(sbb-image, img),
[slot='image'] :is(sbb-image, img) {
transition-property: filter, scale;
will-change: filter, scale;
scale: var(--sbb-teaser-scale, 1);
}

:is(sbb-image, img) {
--sbb-image-object-fit: cover;
--sbb-image-aspect-ratio: 4 / 3;
}
}

// TODO: Move back to the teaser-hero components when the global css refactoring happens
:is(sbb-teaser-hero) {
:is(sbb-image, img) {
--sbb-image-aspect-ratio: 1 / 1;

border-radius: 0;

@include mediaqueries.mq($from: small) {
--sbb-image-aspect-ratio: 16 / 9;
}
}

img {
width: 100%;
display: block;
}
}

// TODO: move to train formation after css refactoring
sbb-train-formation:has(sbb-train[direction-label]) {
--sbb-train-formation-reserve-spacing-display: block;
Expand Down
66 changes: 66 additions & 0 deletions src/elements/core/styles/image.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
@use './mixins/typo';
@use './mixins/image';

.sbb-figure {
@include image.figure;

:is(img, sbb-image, .sbb-image) {
@include image.figure-image;
}

:is(figcaption, .sbb-caption) {
@include image.figure-caption;
}

// Utility classes for placing elements over an image (eg. 'sbb-figure-overlap-start-start')
:is(
TomMenga marked this conversation as resolved.
Show resolved Hide resolved
.sbb-figure-overlap-start-start,
.sbb-figure-overlap-start-end,
.sbb-figure-overlap-end-start,
.sbb-figure-overlap-end-end
) {
@include image.figure-overlap-base;
}

$alignments: start, end;
@each $row-alignment in $alignments {
@each $column-alignment in $alignments {
.sbb-figure-overlap-#{$row-alignment}-#{$column-alignment} {
@include image.figure-overlap($row-alignment, $column-alignment);
}
}
}
}

// Utility classes for the aspect ratio (eg. 'sbb-image-16-9')
$aspects-ratio: (
'free': 'auto',
'1-1': '1 / 1',
'1-2': '1 / 2',
'2-1': '2 / 1',
'2-3': '2 / 3',
'3-2': '3 / 2',
'3-4': '3 / 4',
'4-3': '4 / 3',
'4-5': '4 / 5',
'5-4': '5 / 4',
'9-16': '9 / 16',
'16-9': '16 / 9',
);
@each $name, $ratio in $aspects-ratio {
:is(sbb-image, img).sbb-image-#{$name} {
--sbb-image-aspect-ratio: #{$ratio};
}
}

// Utility classes for the border radius (eg. 'sbb-image-border-radius-none')
$border-radius: (
'default': 'var(--sbb-border-radius-4x)',
'none': '0',
'round': 'var(--sbb-border-radius-infinity)',
);
@each $name, $radius in $border-radius {
:is(img, sbb-image).sbb-image-border-radius-#{$name} {
border-radius: #{$radius};
}
}
34 changes: 34 additions & 0 deletions src/elements/core/styles/mixins/image.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@use './typo';

@mixin figure {
display: grid;
grid-template-rows: auto;
grid-template-columns: 100%;
grid-auto-rows: auto;
margin: 0;
}

@mixin figure-image {
grid-row: 1;
grid-column: 1;
width: 100%;
}

@mixin figure-caption {
grid-row: 2;
grid-column: 1;
padding-block-start: var(--sbb-spacing-fixed-4x);
@include typo.text-xs--regular;
}

@mixin figure-overlap-base {
position: relative;
order: 1; // Alternative to z-index
grid-row: 1;
grid-column: 1;
margin: var(--sbb-spacing-responsive-xxxs);
}

@mixin figure-overlap($row-alignment, $column-alignment) {
place-self: #{$row-alignment} #{$column-alignment};
}
Loading
Loading