Skip to content

Commit

Permalink
Serve alternative images for card viewmodes. DDFFORM-667
Browse files Browse the repository at this point in the history
Card images are displayed in different aspect ratios, based on context.
This is handled by object-fit centering, but generally speaking, we want
different cropped images to be served.
We get around this, by allowing to pass along alternative SRCs, that are
presented as containers, set to display none and using background images.
By doing it this way, and letting CSS decide when the display is allowed,
the browser is smart enough only to load the image when necessary.
  • Loading branch information
rasben committed May 27, 2024
1 parent dbc6110 commit 3beb5b3
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 6 deletions.
Binary file added public/images/card_large.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/card_medium.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/card_original.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/card_x_large.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 9 additions & 2 deletions src/stories/Library/card/Card.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ComponentStory, ComponentMeta } from "@storybook/react";
import { withDesign } from "storybook-addon-designs";
import Card from "./Card";
import ImageCredited from "../image-credited/ImageCredited";
import CardImages from "./CardImages";

export default {
title: "Library / Card ('news card')",
Expand Down Expand Up @@ -30,7 +30,14 @@ export default {
},
image: {
defaultValue: (
<ImageCredited src="https://images.unsplash.com/photo-1585779034823-7e9ac8faec70?q=80&w=3024&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" />
<CardImages
src="images/card_original.jpg"
alternativeSrcs={[
{ name: "x-large", src: "images/card_x_large.jpg" },
{ name: "large", src: "images/card_large.jpg" },
{ name: "medium", src: "images/card_medium.jpg" },
]}
/>
),
},
placeholderText: {
Expand Down
47 changes: 47 additions & 0 deletions src/stories/Library/card/CardImages.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { FC } from "react";

type ImageCreditedProps = {
src: string;
alternativeSrcs?: { name: string; src: string }[];
alt?: string;
};

const ImageCredited: FC<ImageCreditedProps> = ({
src,
alternativeSrcs,
alt = "",
}) => {
// Card images are displayed in different aspect ratios, based on context.
// This is handled by object-fit centering, but generally speaking, we want
// different cropped images to be served.
// We get around this, by allowing to pass along alternative SRCs, that are
// presented as containers, set to display none and using background images.
// By doing it this way, and letting CSS decide when the display is allowed,
// the browser is smart enough only to load the image when necessary.
return (
<figure className="image-credited">
{src ? (
<div className="image-credited__image">
{alternativeSrcs
? alternativeSrcs.map((alternativeSrc) => (
<div
className="card__override-images"
style={{
display: "none",
backgroundImage: `url(${alternativeSrc.src})`,
}}
data-card-style={alternativeSrc.name}
/>
))
: ""}

<img src={src} alt={alt} loading="lazy" />
</div>
) : (
<div className="image-credited__no-image" />
)}
</figure>
);
};

export default ImageCredited;
28 changes: 28 additions & 0 deletions src/stories/Library/card/card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,38 @@
}
}

.card__override-images {
display: none;
height: 100%;
width: 100%;
background-size: contain;
}

@mixin cardStyle($style_name) {
.card__override-images[data-card-style="#{$style_name}"] {
// Overwrite inline styling.
&[style] {
display: block !important;
}

// Hide the initial image.
~ img {
display: none;
}
}
}

%card-variant--large,
.card[data-variant="large"] {
@extend %card-variant--default;

@include cardStyle("large");
}

%card-variant--x-large,
.card[data-variant="x-large"] {
@include media-container--card;
@include cardStyle("x-large");

width: 200px;

Expand All @@ -106,6 +130,8 @@

%card-variant--small,
.card[data-variant="small"] {
@include cardStyle("small");

width: 206px;

// stylelint-disable-next-line no-descending-specificity -- Stylelint wants us to re-order the file, but it actually would make it less readable.
Expand Down Expand Up @@ -136,6 +162,8 @@

%card-variant--medium,
.card[data-variant="medium"] {
@include cardStyle("medium");

width: 200px;

@include media-query__name($breakpoint__large-card) {
Expand Down
15 changes: 11 additions & 4 deletions src/stories/Library/slider/Slider.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { withDesign } from "storybook-addon-designs";

import Slider from "./Slider";
import Card from "../card/Card";
import ImageCredited from "../image-credited/ImageCredited";
import CardImages from "../card/CardImages";

export default {
title: "Library / Slider",
Expand All @@ -29,9 +29,16 @@ export default {

const Template: ComponentStory<typeof Slider> = (args) => <Slider {...args} />;

const imageUrl =
"https://images.unsplash.com/photo-1568667256549-094345857637?q=80&w=2815&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D";
const image = <ImageCredited src={imageUrl} />;
const image = (
<CardImages
src="images/card_original.jpg"
alternativeSrcs={[
{ name: "x-large", src: "images/card_x_large.jpg" },
{ name: "large", src: "images/card_large.jpg" },
{ name: "medium", src: "images/card_medium.jpg" },
]}
/>
);

const card = (
<Card
Expand Down

0 comments on commit 3beb5b3

Please sign in to comment.