Malevich

Primitives/

Image

Responsive with shape, border, shadow variants.

Image

A responsive image, styled. Uses the native <img> element directly; for source negotiation (AVIF / WebP / JPEG fallback) authors wrap it in <picture>. CSS-only.

When to use

For animated icons paired with state changes, use @malevich/morph-icons. For decorative SVG, embed the SVG directly.

Loading defaults

Per the design decision recorded with this component: eager loading is the default. Authors opt in to lazy loading explicitly via data-lazy="true" and the matching loading="lazy" attribute on the <img>.

<!-- Eager (default) — typical for above-the-fold content -->
<img class="image" src="hero.jpg" alt="…" width="1200" height="600" />

<!-- Lazy — typical for below-the-fold media in long pages -->
<img class="image" src="footer.jpg" alt="…"
     width="800" height="400"
     loading="lazy" data-lazy="true" />

The data-lazy attribute is a marker for tooling and AGENTS.md generation; browsers honor only loading="lazy". Authors pair both.

Variants

Variant Class Use for
Default .image Plain responsive image
Rounded .image.-rounded Card-radius corners
Pill .image.-pill Pill-shape (full radius)
Circle .image.-circle Circular crop (1:1 aspect)
Cover .image.-cover object-fit: cover, fills container
Contain .image.-contain object-fit: contain
Bordered .image.-bordered Hairline border
Shadow .image.-shadow Raised shadow

Modifiers compose: .image.-rounded.-shadow.-bordered.

Anatomy

<!-- Plain -->
<img class="image" src="…" alt="…" width="600" height="400" />

<!-- With source negotiation -->
<picture>
  <source srcset="hero.avif" type="image/avif" />
  <source srcset="hero.webp" type="image/webp" />
  <img class="image -rounded -shadow" src="hero.jpg" alt="…"
       width="1200" height="600" />
</picture>

<!-- With srcset for density / size -->
<img class="image -cover"
     src="card.jpg"
     srcset="card.jpg 1x, card@2x.jpg 2x"
     alt="…"
     width="400" height="400" />

<!-- Avatar-style circle -->
<img class="image -circle -bordered"
     src="user.jpg" alt="Alex K." width="64" height="64" />

Tokens used

From semantic tier

Accessibility

<img> requires a meaningful alt attribute:

The component does not impose any alt-text behavior; it is the author's responsibility. The linter will eventually flag <img class="image"> without alt (v1.1).

To prevent cumulative layout shift (CLS), always set width and height attributes on <img> so the browser reserves the correct aspect ratio. The CSS sets block-size: auto so the rendered size scales while preserving the intrinsic ratio.

Edge cases

Do

Don't