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
| Attribute | Values |
|---|---|
data-ratio | square|video|portrait|wide |
data-fit | cover|contain |
data-radius | sm|md|lg|circle |
data-full-width | present or absent |
data-bordered | present or absent |
data-placeholder | present 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
| Option | Type | Default | Description |
|---|---|---|---|
ratio | 'square'|'video'|'portrait'|'wide' | undefined | Crops to a fixed aspect ratio. |
fit | 'cover'|'contain' | undefined | How the image fills its box. |
radius | 'sm'|'md'|'lg'|'circle'|'none' | 'none' | Corner rounding. |
fullWidth | boolean | false | Stretches to the container width. |
bordered | boolean | false | Draws a hairline border. |
placeholder | boolean | false | Tints 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
| Prop | Type | Default | Description |
|---|---|---|---|
src | string | required | |
alt | string | required | Required; pass "" for decorative images. |
ratio | 'square'|'video'|'portrait'|'wide' | undefined | Crops to a fixed aspect ratio. |
fit | 'cover'|'contain' | undefined | How the image fills its box. |
radius | 'sm'|'md'|'lg'|'circle'|'none' | 'none' | Corner rounding. |
fullWidth | boolean | false | Stretches to the container width. |
bordered | boolean | false | Draws a hairline border. |
placeholder | boolean | false | Tints the box while the file loads. |
loading | 'lazy'|'eager' | 'lazy' | Native lazy loading. |
className | string | undefined |
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.
| Ratio | Aspect | Good for |
|---|---|---|
square | 1:1 | Thumbnails, cards in a grid |
video | 16:9 | Hero images, step photos |
portrait | 3:4 | Phone-shot food photography |
wide | 21:9 | Page 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.