Skip to content

CdsImage

An image that knows how to wait. The component reserves space in the layout according to the given proportions, loads the file when the picture enters the viewport, and shows a placeholder while it is on its way. Over the image you can lay a gradient and any content — a caption, a tag, a button.

Storybook GitLab Figma
Test coverage: 95% — good coverage
API in specs
39 / 39 props, events, slots and exposed members with a test
Test cases
51 unit · 0 browser
Known bugs
1 pinned by an it.fails test
Code coverage
95.3% lines · 86.5% branches measured in v4.0.0-alpha.13
A11y (axe)
4 recommendations in 14 stories measured in v4.0.0-alpha.11

For a photo of a person or a company logo in a round frame take CdsAvatar, for interface pictograms — CdsIcon. If the proportions have to be set not for a picture but for an arbitrary block — a video, a map, an iframe — use CdsResponsive, and a slideshow of several images is assembled by CdsCarousel.

Anatomy ​

The first diagram is a loaded image: the container holds the size and the proportions, the img tag sits inside, and an optional gradient lies on top. The second one is the same place while the file has not arrived yet: a blurred placeholder from lazy-src and the content of the placeholder slot.

Variations ​

Size and proportions ​

The minimum needed to show a picture is src and one size constraint: width, height, max-width or max-height. The alt prop describes the image for readers with screen readers and goes into the aria-label of the container.

The aspect-ratio prop reserves the space for the image before it loads — the neighboring content will not jump. The value is accepted both as the fraction 16/9 and as the number 1.7778. Without it the component waits for the file and takes the proportions from its own dimensions — and if the file fails to open, the space for the picture collapses.

Filling the container ​

By default the image fits into the container as a whole (object-fit: contain) and leaves margins when the proportions do not match. The cover prop does the opposite: it fills the frame and crops the excess — this way photos of different sizes line up into an even grid.

The position prop sets which part of the frame stays visible when cropping. It accepts any object-position value, including pairs like left top and percentages.

Loading ​

The image starts loading when it enters the viewport — markup below the fold does not drag dozens of files along with it. The observation thresholds are configured by the options prop (the IntersectionObserver options), and eager turns the waiting off and loads the picture right away — which is what you should do with the images of the first screen.

While the file is on its way, the component shows lazy-src — a thumbnail of the same frame, stretched and blurred — and the content of the placeholder slot. The color prop sets the color of the backdrop under them. The loadstart and load events report the progress of the loading.

Loading error ​

If the file failed to open, the component shows the error slot and reports it with the error event. Without that slot the placeholder stays in place of the picture — so for an error it is better to give your own fallback with a clear text.

Gradient ​

The gradient prop lays a CSS gradient over the image — the value is passed as the arguments of linear-gradient(). Usually you need it to keep the text over a photo readable on any frame.

Content over the image ​

The default slot renders above the image and stretches over the whole container: you can put a caption, a tag or a button inside. Set the layout with utilities on the component itself (items-end, justify-center) or through content-class.

Responsive sources ​

The srcset and sizes props go straight into the img tag — the browser picks the file for the pixel density and the width of the place itself. When a narrow screen needs not just a smaller file but a different frame, add <source> elements into the sources slot: the component wraps the image into <picture>. Narrow the window — in the example the wide panorama gives way to a vertical frame.

Slots ​

SlotDescription
defaultContent over the image
placeholderWhat to show while the image is loading
errorWhat to show when the image failed to load
sources<source> elements; wraps the image into <picture>

Guidelines ​

Scenarios ​

Catalog cards ​

Listing covers come from different sources and almost never match in size. A shared aspect-ratio and cover bring them to one frame, color holds a neutral backdrop while the file is loading, and the default slot leaves a tag in the corner of the cover.

Page cover ​

A wide header with text over a photo: height sets the height of the band, cover and position crop the shot to fit it, and gradient darkens the bottom so that the title and the button stay readable. Such a picture needs eager — it is on the first screen and has no reason to wait for the viewport.

A click on a thumbnail changes the src of the large image. The thumbnails get a shared aspect-ratio and cover, so the row stays even, and color holds the backdrop of the large frame while the new file is loading. If the frames also have to be flipped — with arrows or a swipe — take the ready-made “Gallery with thumbnails” scenario of CdsCarousel.

API ​

Props

NameTypeDefaultDescription
absoluteboolean | undefined—Positions the image with position: absolute, filling its parent.
altstring | undefined—Alternative text of the image (the alt attribute).
aspectRatiostring | number | undefined—Aspect ratio of the content. For example 1.7778 (16/9) or '4/3'.
colorstring | undefined—Background color of the placeholder shown while loading.
contentClassany—CSS class applied to the content wrapper.
coverboolean | undefined—Scales the image so that it covers the whole container (object-fit: cover).
crossorigin"" | "anonymous" | "use-credentials" | undefined—Value of the crossorigin attribute.
draggableboolean | "true" | "false" | undefined—Controls whether the image can be dragged (the draggable attribute).
eagerboolean | undefined—Loads the image immediately instead of waiting for it to enter the viewport.
gradientstring | undefined—CSS gradient laid over the image. For example 'to top, rgba(0,0,0,.4), transparent'.
heightstring | number | undefined—Component height
imageClassany—CSS class applied to the inner <img> element.
inlineboolean | undefined—Renders the component as an inline block (inline-flex) instead of a block one.
lazySrcstring | undefined—Source of the low-quality placeholder image shown until the main one loads.
maxHeightstring | number | undefined—Maximum component height
maxWidthstring | number | undefined—Maximum component width
minHeightstring | number | undefined—Minimum component height
minWidthstring | number | undefined—Minimum component width
optionsIntersectionObserverInit | undefined{}IntersectionObserver options for lazy loading.
positionstring | undefined—Value of object-position that places the image inside the container.
referrerpolicy"origin" | "no-referrer" | "no-referrer-when-downgrade" | "origin-when-cross-origin" | "same-origin" | "strict-origin" | "strict-origin-when-cross-origin" | "unsafe-url" | undefined—Value of the referrerpolicy attribute.
sizesstring | undefined—Value of the sizes attribute for responsive images.
srcstring | CdsImageSrcObject | undefined''Image source. A string or an object with src/srcset/lazySrc/aspect.
srcsetstring | undefined—Set of image sources for different resolutions (the srcset attribute).
themestring | undefined—Component theme
transitionstring | boolean | (TransitionProps & { component?: Component | undefined; }) | null | undefined'fade-transition'Transition animation
widthstring | number | undefined—Component width

Events

NameTypeDescription
error[value: string | undefined]Fires when the image fails to load.
load[value: string | undefined]Fires after the image has loaded successfully.
loadstart[value: string | undefined]Fires when the image starts loading.

Slots

NameTypeDescription
defaultanyContent shown over the image.
erroranyContent shown when the image fails to load.
placeholderanyContent shown while the image is loading.
sourcesanyExtra <source> elements for the <picture> tag.

Exposed

NameTypeDescription
currentSrcstringActual address of the loaded image — taking srcset and the density chosen by the browser into account.
imageHTMLImageElement | undefinedReference to the img DOM element.
naturalHeightnumber | undefinedNatural height of the loaded image in pixels.
naturalWidthnumber | undefinedNatural width of the loaded image in pixels.
state"error" | "loading" | "idle" | "loaded"Loading state of the image: idle, loading, success or error.