Brik Design System
Components

Image

SEO- and CLS-aware img wrapper with aspect-ratio enforcement, lazy loading, and responsive srcset.

Image renders a semantic <figure> + <img> (+ optional <figcaption>). It lazy loads and async-decodes by default, locks the shape to the --aspect-* token family when ratio is set, and passes srcset / sizes through for responsive breakpoints.

It owns the design-system constraints — shape, fit, and semantics. It is not an image-optimization layer: pair it with next/image, @astrojs/image, or a CDN for resizing and format negotiation.

Use it for

  • Content and editorial images that must hold a fixed shape (Frame is the bare aspect-ratio box; Image adds SEO + <figure> semantics)
  • Above-the-fold hero images that need eager, high-priority loading
  • Captioned figures (<figcaption>)
  • Responsive images with srcset / sizes

For avatars use Avatar; for a raw aspect box with no <img> semantics use Frame.

Import

import { Image } from '@brikdesigns/bds';

Variants

Aspect ratio

ratio maps to a slug in the --aspect-* token family and wraps the image in a Frame. The frame reserves layout space before the image loads — the primary defense against cumulative layout shift (CLS).

<Image src="/hero.jpg" alt="Team at work" ratio="16-9" />
<Image src="/portrait.jpg" alt="Dr. Alice Chen" ratio="3-4" />

Omit ratio to render at the image's natural shape. See Frame for the full slug vocabulary (1-1, 3-2, 4-3, 16-9, square, cinema, …).

Fit

When a ratio is set, fit controls how the image fills the frame (object-fit). position sets object-position for cropped fits.

<Image src="/wide.jpg" alt="" ratio="1-1" fit="cover" position="top" />
fitBehavior
cover (default)Fills the frame, cropping overflow
containFits inside the frame, letterboxing
fillStretches to the frame, ignoring the source ratio
noneNo resizing

Caption

caption renders a <figcaption> below the image, inside the same <figure>.

<Image
  src="/portrait.jpg"
  alt="Dr. Alice Chen"
  ratio="3-4"
  caption="Dr. Alice Chen, Lead Orthodontist"
/>

Eager

By default Image is loading="lazy" + decoding="async". For the above-the-fold Largest Contentful Paint image, set eager — it switches to loading="eager" and hints fetchpriority="high". Use it for one image per page at most.

<Image src="/hero.jpg" alt="Homepage hero" ratio="21-9" eager />

Responsive images

srcSet and sizes pass through to the underlying <img>. Supply a ratio (or explicit width + height) so the browser reserves space regardless of which candidate it picks.

<Image
  src="/photo-800.jpg"
  srcSet="/photo-400.jpg 400w, /photo-800.jpg 800w, /photo-1200.jpg 1200w"
  sizes="(max-width: 600px) 100vw, 600px"
  alt="Product photo"
  ratio="3-2"
/>

For automatic candidate generation and format negotiation (WebP/AVIF), let next/image or @astrojs/image emit the <img> and wrap layout concerns with Image's ratio at the Frame level.

SEO checklist

TacticHow Image supports it
CLS preventionratio (or width + height) reserves layout space before load
LCPeager sets loading="eager" + fetchpriority="high" for the hero image
Alt textalt is required — no silent empty default; pass alt="" deliberately for decorative images
Responsive deliverysrcSet + sizes pass-through for consumer-defined breakpoints
Structured data<figure> + <figcaption> markup supports ImageObject schema at the consumer level

Accessibility

  • alt is a required prop. For decorative images, pass alt="" so assistive tech skips them — omitting it is not allowed.
  • Renders semantic <figure> / <figcaption>; the caption is associated with the image through the shared <figure>.
  • Never encode meaning in the image alone — captions and surrounding copy carry the same information for non-visual users.

API

PropTypeDefault
srcstring (required)
altstring (required)
ratioFrameRatio
fitFrameFit'cover'
positionstring
eagerbooleanfalse
srcSetstring
sizesstring
widthnumber | string
heightnumber | string
captionReactNode

Plus standard <figure> HTML attributes. position takes a CSS object-position value ("top", "50% 25%") and only applies together with ratio and a cropping fit. ratio and fit are the same aliases Frame uses — FrameRatio includes four deprecated mode-words listed there.

On this page

💬