Image

import "@taprootio/espalier/image";

<esp-image>

A responsive image with a native <picture> and an optional focal-point-aware banner mode.

esp-image accepts two authoring shapes:

  1. Project a light-DOM <picture> — the recommended form for published / server-rendered markup. Provide a real <picture> (or a bare <img>) as a child and esp-image projects it through a <slot>, adding only the layout box, border, and lightbox wiring. Because the image lives in the served HTML it is discoverable by the preload scanner and visible to crawlers, and it is fetched exactly once.
  2. Declare esp-image-option children — the editor / fallback form. esp-image builds a shadow <picture> and srcset from them. Use local-image when an editor needs a blob preview.

Source precedence is local-image → a projected <picture> / <img>esp-image-option children. In every mode the host reserves its layout box up front from original-width / original-height, when supplied.

Once upgraded, the component measures its own width and updates sizes so a card or gallery column does not over-fetch. The sizes attribute covers the server-rendered initial fetch and the brief window before measurement:

For a long projected lazy-image list, defer-offscreen keeps the served sizes hint until an image approaches the viewport. This avoids replacing a small fallback selection with a larger candidate before the image can be seen. Eager projected images and every non-projected source keep the normal immediate measured-size behavior.

Banner mode gives all three source modes the same focal position, scrim, texture, and semantic overlay stack. ratio applies at wide widths and compact-ratio below the component-relative compact threshold.

banner-scheme sets the banner's polarity and defaults to the active scheme: a light page lightens the image behind dark text, a dark page darkens it behind light text. Fix either polarity explicitly when a banner must not follow the page scheme:

Every procedural preset supports fine, medium, and coarse scales.

Dots

A uniform tiled ink screen (shown at fine):

Halftone

The dot screen ramping toward the content edge (shown at medium):

Paper

Soft fractal-noise mottle, like printed stock (shown at coarse):

Grain

High-frequency film grain that also kills banding (shown at fine):

Grunge

Thresholded turbulence, a distressed ink wash (shown at medium):

Scanlines

Hairline rules along the block axis (shown at coarse):

Duotone

The photo mapped onto two theme-derived hues:

Consumer texture tokens

Any background-image value — a tile the application serves, a data URI, or a gradient — can be wired directly through the public consumer-image token path (the optional @taprootio/espalier/textures/banner-textures.css stylesheet ships .esp-texture-paper/-grain/-grunge classes with the tiles inlined as data URIs, so nothing needs asset configuration):

Registered textures

Wiring those tokens on every banner is verbose and not reusable. The application's texture vocabulary lives on esp-root: register the look once — registerImageTexture(name, definition) from the module, or the root's registerTexture static in script-only contexts — and any banner under the root selects it by name. Live banners re-render on registration, so markup order and registration order never race, and the root's registeredTextures() enumerates the presets for an editor's texture picker:

Slots

<esp-image> has the following slots:

Default

A projected native image, or esp-image-option children. When projecting, alt lives on the consumer's <img>; caption remains the lightbox text.

overlay

Semantic banner content above the image and decorative layers.

Attributes

<esp-image> has the following attributes:

original-height

original-height has a default value of 0.

Original image height, used with originalWidth to reserve the intrinsic aspect ratio and report portrait orientation.

original-width

original-width has a default value of 0.

Original image width, used with originalHeight to reserve the intrinsic aspect ratio and report portrait orientation.

low-res

low-res has a default value of "".

Fallback image URL used as the internal <img src> when responsive options build a shadow <picture>.

local-image

local-image has a default value of "".

Local preview URL, commonly a blob: URL. It takes priority over projected content and responsive options so an editor can show a new upload at once.

caption

caption has a default value of "".

Lightbox caption in every mode, and internal image alternative text for local-image and responsive-option modes.

sizes

sizes has a default value of "100vw".

Initial/server-side responsive-image size hint. After upgrade the component replaces this with its measured rendered width.

loading

loading has a default value of "eager".

Native loading strategy for internally rendered images. Projected images retain the consumer's own loading attributes.

defer-offscreen

defer-offscreen has a default value of false.

For lazy projected images, defer measured sizes upgrades until the image approaches the viewport. A 200px prefetch margin keeps the full-size candidate ready before it is visible. Eager projections and internally rendered images keep their normal immediate measurements.

banner

banner has a default value of false.

Enable borderless banner defaults and the decorative/content layer stack.

banner-scheme

banner-scheme has a default value of "auto".

Banner polarity. dark darkens the image behind light text; light lightens it behind dark text. auto (the default) follows the active scheme, so a light page lightens and a dark page darkens.

scrim

scrim has a default value of "auto".

Legibility-layer anchor. auto follows overlay presence and position.

scrim-strength

scrim-strength has a default value of "medium".

Preset opacity for the scrim.

texture

texture has a default value of "none".

Optional texture: a built-in procedural preset, or the name of a texture registered with registerImageTexture. Unknown names render as none (and recover if the name is registered later).

texture-scale

texture-scale has a default value of "medium".

CSS pitch or discrete SVG-filter variant for the selected texture.

content-position

content-position has a default value of "bottom-start".

Logical position for semantic banner content.

focus

focus has a default value of { x: 0.5, y: 0.5 }.

Normalized focal point used for cover cropping.

ratio

ratio has a default value of "".

Banner target aspect ratio, as a positive number or number / number.

compact-ratio

compact-ratio has a default value of "".

Aspect ratio used below the component-relative compact threshold.

intent

intent has a default value of undefined.

The element's intent — its meaning: neutral (no pin), or success, warning, danger, info — each pinned to its fixed status family (blue for info), retunable per theme via intents. On token-emitting controls a non-neutral intent pins the filled-action pair to that family, derived over the governing zone's theme; class-styled chrome (badges, callouts, status pills) opts out of inline emission and renders its treatment from CSS classes instead. An intent never repaints the surrounding zone, which is what contexts are for. Removing the attribute restores the element's own default intent.

context

context has a default value of undefined.

A theme-defined color zone. The selected context rebinds designer-facing roles and emits a complete, contrast-enforced semantic token table on this host for descendants to inherit.

Methods

<esp-image> has the following methods:

traverseToClosest

Traverse up the DOM tree to find the closest element that matches the selector. This method is aware of shadow DOM boundaries and will traverse through them to find the element.

CSS Parts

<esp-image> has the following CSS parts:

frame

The stable banner/image frame.

image

The stable media-box wrapper in every source mode.

scrim

The decorative legibility layer.

texture

The procedural and consumer-supplied texture layers.

overlay

The positioned semantic overlay region.

CSS Properties

<esp-image> has the following CSS properties:

--esp-image-border

Border; defaults to 2px solid var(--esp-color-border) or none in banner mode.

--esp-image-border-radius

Corner radius; defaults to var(--esp-size-border-radius) or zero in banner mode.

--esp-image-object-position

Final object-position override.

--esp-image-compact-width

Component-width threshold; defaults to 40rem.

--esp-image-scrim-color

Scrim ink; defaults to the theme background when the banner polarity matches the scheme, else a polarity-pinned derivation.

--esp-image-scrim-opacity

Scrim-strength opacity override.

--esp-image-texture-color

Procedural texture ink; defaults to a theme-derived color following banner-scheme.

--esp-image-texture-opacity

Procedural texture opacity override.

--esp-image-texture-scale

CSS-gradient texture pitch override.

--esp-image-texture-blend-mode

Texture blend-mode override.

--esp-image-texture-image

Consumer-supplied texture background image.

--esp-image-texture-image-opacity

Consumer texture opacity.

--esp-image-texture-repeat

Consumer texture repeat.

--esp-image-texture-position

Consumer texture position.

--esp-image-texture-size

Consumer texture size.

--esp-image-duotone-shadow-color

Duotone shadow stop; defaults to a dark stop derived from the theme primary.

--esp-image-duotone-highlight-color

Duotone highlight stop; defaults to a light stop derived from the theme complementary.

--esp-image-overlay-padding

Overlay content padding.

--esp-image-overlay-color

Overlay text color; defaults to the theme heading color when the banner polarity matches the scheme.

--esp-image-overlay-text-shadow

Overlay text shadow; defaults to a soft polarity-matched halo. Set to none to disable.

--esp-field-background

Background color of the shared field shell. Defaults to var(--esp-color-layer-2).

--esp-field-border-color

Border color of the shared field shell. Defaults to var(--esp-color-border).

--esp-field-border-width

Border width of the shared field shell. Defaults to 1px.

--esp-field-text-color

Text color used inside the shared field shell. Defaults to var(--esp-color-text).

--esp-field-hover-bg

Hover background color of the shared field shell. Derived from --esp-field-background.

--esp-field-focus-bg

Focus background color of the shared field shell. Derived from --esp-field-background.

--esp-field-focus-shadow

Shadow color used for shared field focus treatment. Defaults to var(--esp-color-shadow).

Components API Guides Getting started Styling Espalier Browser support GitHub npm package Taproot I/O