Skip to content
Cynosurev0.5.0
SearchStorybookGitHubnpmColour mode: System. Switch to Light

Components / Feedback and display

Image

A picture that never shifts the layout, shows a placeholder while it loads and something sensible when it fails. For a person or an account, use Avatar; for an interface symbol, use Icon.

Default

When to useLink to "When to use"

  • Photos, screenshots and illustrations anywhere in a page: give it a ratio and it holds its space from the first paint.
  • Thumbnails in a grid: one ratio for all, fit="cover" to crop them to the same shape.
  • Pictures that may be missing: uploads, remote addresses and anything else that can fail gets a fallback instead of a broken-image mark.
  • Figures: caption adds a caption that names the picture.

Use something else when:

  • the box holds a video, a map or an embed: AspectRatio
  • it is a person, a team or an account: Avatar
  • it is a symbol in the interface: Icon
  • two pictures are compared: CompareSlider

UsageLink to "Usage"

tsx
Copy
import { Image } from "@arshad-shah/cynosure";

<Image src="/team.jpg" alt="The team at the 2026 offsite" ratio={16 / 9} radius="card" />

<Image src="/logo.png" alt="" width={120} height={40} />

<Image src={url} alt="Uploaded scan" ratio="4/3" fit="contain" caption="Page 1 of 3" />

alt is required. Describe what the picture shows, or pass alt="" when it is decoration: it is then hidden from assistive technology.

With ratio the picture fills a box of that shape, as wide as its container. Without it the picture has its natural size, never wider than its container; pass width and height so its space is reserved before it loads.

Fit and positionLink to "Fit and position"

With a ratio, fit="cover" (the default) fills the box and crops what does not fit, and fit="contain" shows the whole picture. position chooses the part that stays in view, as CSS object-position.

Fit and position

When it failsLink to "When it fails"

The picture is replaced by a quiet box with the image icon and the alt text, in the same space. fallback replaces that box, and onError is still called. Changing src tries again.

Fallback on error

CaptionLink to "Caption"

caption wraps the picture in a figure whose name is the caption.

Caption makes afigure

PropsLink to "Props"

Every prop of Image
PropWhat it doesTypeDefault
srcRequired
Address of the picture. Changing it loads the new picture, also after a failure.string
altRequired
What the picture shows, for people who cannot see it. "" marks it decorative and hides it from them.string
srcSet
Candidate files for different screen densities or widths, as on <img>.string
sizes
With srcSet: how wide the picture is shown, as on <img>.string
width
Natural width in pixels. With height and no ratio, it reserves the picture's space before it loads.number
height
Natural height in pixels.number
ratio
Width divided by height of the box the picture fills (16 / 9, "4/3"), kept at any width with AspectRatio. Without it the picture has its natural size, no wider than its container.string | number
fit
With ratio: cover fills the box and crops, contain shows the whole picture. Default "cover"."cover" | "contain""cover"
position
With ratio: which part stays in view when cropped, as CSS object-position ("top", "20% 80%").string
radius
Rounds the corners from the radius tokens. Default "none".AspectRatioRadius"none"
loading
lazy waits until the picture is near the screen; eager loads it at once. Default "lazy"."lazy" | "eager""lazy"
placeholder
Shown while the picture loads, in place of the Skeleton.ReactNode
fallback
Shown when the picture fails, in place of the box with an icon and the alt text.ReactNode
caption
A caption under the picture: wraps it in a figure named by the caption.ReactNode
onLoad
Called when the picture has loaded.((event: SyntheticEvent<HTMLImageElement>) => void)
onError
Called when the picture fails to load. The fallback is shown as well.((event: SyntheticEvent<HTMLImageElement>) => void)
className
Added to the root element (the figure when there is a caption), for layout.string
style
Layout only (width, margin, placement), on the root element. Restyle through --cy-image-* tokens.CSSProperties

Generated from the type definitions in @arshad-shah/cynosure 0.5.0.

Behaviour and accessibilityLink to "Behaviour and accessibility"

Behaviour and accessibility, table 1
SituationResult
Before the picture has loadedA Skeleton (or placeholder) covers the box; the box already has its final size
The picture loadsThe placeholder goes, the picture fades in, onLoad is called. Nothing moves
The picture failsThe fallback takes its place in the same box, onError is called
src or srcSet changesLoading starts again, also after a failure
The picture finished before React attached (cached, or in the server's HTML)It is shown, or its fallback is, without waiting for an event. For a picture in the server's HTML the event has passed, so onLoad and onError are not called
  • Name: the img has the alt text as its name. With alt="" nothing has the image role.
  • Fallback: the default fallback shows the alt text on screen, so it is read as text. For a decorative picture it shows only the icon and is hidden from assistive technology. A custom fallback is shown as it is: give it its own text.
  • Placeholder: the Skeleton is hidden from assistive technology and stops moving under reduced motion.
  • Loading: lazy by default, so pictures far below the screen wait. Use loading="eager" for a picture at the top of the page. decoding is async.
  • Root element: with a ratio or a caption it is a block as wide as its container (a div or a figure), so keep it out of paragraphs. Otherwise it is an inline span the size of the picture.
  • Ref: the img element. There is none while the fallback is shown.
  • Native behaviour: dragging and the context menu are the browser's own.
  • Right-to-left: nothing changes. Pictures are not mirrored and position is physical, as in CSS.

TouchLink to "Touch"

Nothing in Image can be pressed. To make a picture a link or a button, put it inside Link or a control with a hit area of its own.

ThemingLink to "Theming"

Tokens: --cy-image-radius (the corners of every Image, whatever its radius prop says), --cy-image-fallback-background, --cy-image-fallback-color, --cy-image-caption-gap and --cy-image-caption-color. The placeholder is themed through the Skeleton tokens.

ts
Copy
createTheme({ components: { image: { radius: "8px", captionGap: "4px" } } });

className and style are for layout only (width, margin, placement).

AspectRatio · Skeleton · Avatar · CompareSlider · Card

These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.

Getting started
Theming
Icons
Accessibility
Code editors and highlighters
Using Cynosure without React
Build-tool adapters
Components
Accordion
AppShell
AspectRatio
Breadcrumbs
Calendar
Card
Container
Disclosure
Divider
DocumentViewport
Grid
Inline
PageHeader
PanZoomCanvas
ScrollArea
SideNav
SortableList
SplitPane
Stack
StatusBar
Tabs
TitleBar
Toolbar
Tree
VirtualList
ZoomControls
Announcer
Avatar
Badge
CodeBlock
DescriptionList
EmptyState
ErrorBoundary
Field
Heading
IconTile
Image
Kbd
List
LoadingDots
Notice
ProgressBar
Prose
Skeleton
Stat
Steps
Table
Text
Button
Checkbox
Checklist
ColorField
ColorSwatches
Combobox
CompareSlider
CopyButton
DateField
FileDrop
IconButton
KeyValueEditor
Link
NumberField
Pagination
PathField
RadioGroup
SearchField
SegmentedControl
Select
SelectionFrame
SignaturePad
Slider
Switch
TagInput
TextArea
TextField
ThemeToggle
TimeField
ButtonBase
ChoiceBase
DialogBase
FileInputBase
HiddenValue
Icon
InputBase
LinkBase
LiveRegion
TextAreaBase
ChatMessage
Choice
DataGrid
DeviceFrame
HighlightedText
HotkeyField
ListRow
OptionList
OverlayFrame
QRCode
RowActions
Section
SiteFooter
SiteHeader
SkipLink
SortButton
VisuallyHidden
CommandPalette
ContextMenu
Dialog
FloatingToolbar
HoverCard
Menu
Menubar
Popover
ProgressOverlay
Sheet
Toast
Tooltip
Changelog