Skip to content

ExpressiveCSS

Browse documentation

Shapes

Cut images, videos, and buttons to rounded expressive shapes with one class.

View as Markdown

Images and videos

On an <img>, <video> or <canvas>, the class also sets aspect-ratio: 1 and object-fit: cover, so the browser crops the picture to a square instead of stretching the shape. Set the width and the height follows.

A pug wrapped in a blanket A river between mountains A portrait of a woman
<img class="shape-scallop-9" width="160" src="pug.jpg" alt="A pug wrapped in a blanket">
<video class="shape-bloom-4" width="240" src="clip.mp4" controls></video>

Native video controls sit at the edges of the box, where most shapes cut them off. Use custom controls, or keep controls off for decorative loops.

Buttons

The shapes are drawn for a square box, so pair them with icon buttons, FABs, or a button with equal width and height. A wide button stretches the shape.

<button class="icon-button filled large shape-spark" type="button" aria-label="Favorite">
  <span class="material-symbols" aria-hidden="true">favorite</span>
</button>
<button class="btn shape-flare" type="button" style="width: 96px; height: 96px">New</button>

The mask would clip the usual focus outline, so a focused shape draws its ring inside its own edge. The ring is a 3px band in the secondary color with a 2px gap. Press Tab to see it. Forced-colors mode paints the band in Highlight. Clicks and taps on the cut-away parts of the box pass through to the page behind.

Notes

The class adds contain: paint, which clips overflowing content and makes the element the containing block for absolutely positioned children. The mask cuts shadows and borders along with the rest of the element. Wrap the element if it needs a shadow that follows the shape, and apply filter: drop-shadow() to the wrapper.

For a selective Sass build, include "shapes" in $utilities.

Corner scale

Rounded corners come from the Material 3 md.sys.shape.corner scale. Component shape tokens on that scale read these values, so one override changes every component on that step. Set a component token, such as --md-comp-card-container-shape, to change one component. Off-scale corners stay literal.

TokenValue
--md-sys-shape-corner-none0px
--md-sys-shape-corner-extra-small4px
--md-sys-shape-corner-small8px
--md-sys-shape-corner-medium12px
--md-sys-shape-corner-large16px
--md-sys-shape-corner-large-increased20px
--md-sys-shape-corner-extra-large28px
--md-sys-shape-corner-extra-large-increased32px
--md-sys-shape-corner-extra-extra-large48px
--md-sys-shape-corner-full9999px
<style>
  /* Cards, menu items and every other medium corner become 8px. */
  :root { --md-sys-shape-corner-medium: 8px; }
</style>

Cut corners

Material shapes come in a rounded and a cut family. Set corners="cut" on the root or on any subtree to turn its corners into straight bevels of the same size. This covers cards, dialogs, sheets, menus, fieldsets, buttons, chips, alerts, snackbars, tooltips, popovers and outlined fields. Set corners="round" to put a subtree back. The switch sets --md-sys-shape-corner-family to bevel or round.

Add .corner-cut to cut a single element, together with its own radius or a .corner-* class. Round indicators such as radios, switches, avatars and .circle stay round, because a cut 50% radius is a diamond. Cut corners use CSS corner-shape. Browsers without it, including Firefox 157, keep rounded corners.

A cut card
<main corners="cut">…</main>
<div class="bordered corner-large corner-cut">One cut panel</div>

No matching pages

  • Source color

    The seed every generated ramp derives from. Pick one and browse the docs — the whole theme follows. Error does not: it is a fixed hue.

    Default source: Mist Iris.

    ExpressiveCSS presets: Lagoon, Harbor, Breeze, Cobalt, Iris.

    Bold

    Soft

    Mist

    Glow