Image

Content image — responsive by default, with optional aspect-ratio cropping.

import { ... } from '@corndev/ui'

HTML

No JavaScript required — these classes are the whole component.

<img class="corn-image" data-ratio="video" data-radius="md"
     src="/roast-chicken.jpg" alt="Roast chicken" loading="lazy" />

Classes

Class
.corn-image

Attributes

AttributeValues
data-ratiosquare|video|portrait|wide
data-fitcover|contain
data-radiussm|md|lg|circle
data-full-widthpresent or absent
data-borderedpresent or absent
data-placeholderpresent or absent

Vanilla JS

Optional. createImage only adds and removes the classes and attributes above, so the HTML is equivalent. Reach for it when you need to change options at runtime.

import { createImage } from '@corndev/ui';
import '@corndev/ui/theme';

const el = document.querySelector('#target');
const instance = createImage(el, { /* options */ });

Options

OptionTypeDefaultDescription
ratio'square'|'video'|'portrait'|'wide'undefinedCrops to a fixed aspect ratio.
fit'cover'|'contain'undefinedHow the image fills its box.
radius'sm'|'md'|'lg'|'circle'|'none''none'Corner rounding.
fullWidthbooleanfalseStretches to the container width.
borderedbooleanfalseDraws a hairline border.
placeholderbooleanfalseTints the box while the file loads.

React

Image — from @corndev/ui-react.

The React version renders the <img> for you and takes src/alt, and defaults loading to lazy. The vanilla version only applies classes — write the tag yourself.

Props

PropTypeDefaultDescription
srcstringrequired
altstringrequiredRequired; pass "" for decorative images.
ratio'square'|'video'|'portrait'|'wide'undefinedCrops to a fixed aspect ratio.
fit'cover'|'contain'undefinedHow the image fills its box.
radius'sm'|'md'|'lg'|'circle'|'none''none'Corner rounding.
fullWidthbooleanfalseStretches to the container width.
borderedbooleanfalseDraws a hairline border.
placeholderbooleanfalseTints the box while the file loads.
loading'lazy'|'eager''lazy'Native lazy loading.
classNamestringundefined

When to use which

Image is for content — a recipe photo, a hero, a thumbnail. For a person, use Avatar, which is sized from the type scale and defaults to a circle.

Aspect ratios

Without a ratio the image keeps its natural proportions and simply never overflows its container (max-width: 100%; height: auto). With a ratio it fills the box and crops via object-fit: cover, which is what you want for a grid of recipe cards where the source photos are all different shapes.

RatioAspectGood for
square1:1Thumbnails, cards in a grid
video16:9Hero images, step photos
portrait3:4Phone-shot food photography
wide21:9Page banners

Loading

The React component sets loading="lazy" by default; pass loading="eager" for an image above the fold, where lazy loading delays the largest paint.

In plain HTML this is yours to set — the vanilla helper only applies classes:

<img class="corn-image" data-ratio="video" src="/hero.jpg" alt="" loading="eager" />

Placeholder

placeholder tints the box with --corn-bg-tertiary while the file loads, so an image-led page does not flash its background at the reader. Pair it with a ratio, which reserves the space and stops the layout shifting when the image arrives.