Cards✨ Premium

Morphing Shape

Four border-radius corners cycle through soft and extreme values in a continuous loop — an organic living shape, pure CSS, zero JavaScript.

CSSAnimationOrganic

You'll get access to the interactive demo with a free account.

This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Cards has 41 effects, including 6 free. Explore the category →

3 usage examples

Decorative blob — Creative hero page accent — Morphing Shape example 1

① Decorative blob — Creative hero page accent

WhenA creative studio or app landing page places a large colored element behind the main headline to break the rigidity of a grid layout.
WhyA 300×300 px morphing shape in the background creates a distinctive visual anchor without images or canvas — the slow cycle (12 s) reads as 'alive' without stealing attention.
SettingsDimensions 300×300 px; --bg-card in translucent violet (rgba(99,102,241,.10)); border rgba(99,102,241,.3); animation-duration: 12s; z-index: 0 with text content at z-index: 1 on top.
Feature card — Interactive highlight in a grid — Morphing Shape example 2

② Feature card — Interactive highlight in a grid

WhenA 'Why choose X?' section or feature grid displays 3–4 cards; the featured card uses the .card-morph-expand variant to invite clicks.
WhyThe moving organic border draws the eye without a loud color; the click expansion (scale + violet glow) confirms interactivity and reveals feature details.
SettingsDimensions 280×180 px; --border: rgba(99,102,241,.4); --bg-card: #14102a; glow rgba(99,102,241,.4); animation-duration: 8s.
Organic frame — Avatar or portrait on a profile page — Morphing Shape example 3

③ Organic frame — Avatar or portrait on a profile page

WhenAn avatar, profile photo, or author illustration is displayed in a bio or team card; the morphing shape replaces the classic border-radius: 50% circle.
WhyThe effect subtly reframes the image on each cycle and draws attention to the face without flickering — it stays elegant even at small sizes (80–120 px).
Settingsoverflow: hidden on the .card-morph element to clip image corners; dimensions 120×120 px; animation-duration: 10s; remove the border.

How it works

The animation is driven by @keyframes morphShape, which evolves border-radius through four states. CSS shorthand lets you address diagonal corner pairs in a single value: at 0%/100% (20px 60px), corners TL and BR are 20 px, TR and BL are 60 px; at 25% (60px 20px), the roles swap. The result is a diagonal rotation of the roundness.

Keyframes 50% (20px 20px 60px 60px) and 75% (60px 60px 20px 20px) address all four corners individually to shift the rounding from top to bottom then back. The ease-in-out curve over the 8 s infinite loop smooths each transition — the shape appears to breathe rather than snap.

The .card-morph-expand variant adds a click interaction: toggling the .expanded class via JavaScript scales the card to transform: scale(1.1) with a violet glow (box-shadow: rgba(99,102,241,.3) 0 25px 50px), fades the preview view to opacity: 0, and reveals full content positioned at position: absolute; inset: 0 through an opacity and transform: scale() transition.

Accessibility

  • prefers-reduced-motion is absent from the code — the animation loops indefinitely even when the OS requests reduced motion. Add: @media (prefers-reduced-motion: reduce) { .card-morph { animation: none; } }
  • The <div class="card-morph"> carries no role or aria-label. For purely decorative use, add aria-hidden="true"; for interactive use, add role="button" and aria-label.
  • The .card-morph-expand variant responds to clicks but does not define aria-expanded — screen readers cannot track the open/closed state.
  • Text contrast: the default 'Morph' label (#ffffff) on --bg-card: #12121a yields a ratio > 7:1, meeting WCAG AAA.
  • The expand variant intercepts no Enter/Space keydown and has no tabindex — it is not keyboard-accessible in its base form.

Browser compatibility

Requires multi-value border-radius and CSS @keyframes — supported in all modern browsers since 2016.

Chrome 57+✓ Full
Firefox 55+✓ Full
Safari 10.1+✓ Full
Edge 16+✓ Full
Mobile iOS 10.3+✓ Full
Android Chrome 57+✓ Full

Without @keyframes support, the card displays the static --radius-xl: 1rem radius (gently rounded corners) — no JS errors, content remains readable.

The code

HTML structure to paste into your page (CSS + JS available with a premium account):

index.html — structure
<div class="demo-preview">
  <div class="card-demo card-morph">
    Content
  </div>
</div>

<!-- Interactive variant: reveals content on click -->
<div class="card-demo card-morph-expand">
  <div class="card-preview">
    <div class="card-preview-icon"><!-- icon --></div>
  </div>
  <div class="card-full-content">
    <h5>Title</h5>
    <p>Description</p>
  </div>
</div>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
--bg-card #12121a Card background color. Use rgba() for a semi-transparent background that layers over a colored context.
--border rgba(255,255,255,.08) 1 px border color and opacity. Switch to rgba(99,102,241,.4) for a visible indigo outline.
animation-duration in .card-morph 8s Duration of one full cycle. 4s = snappy; 8s = natural; 14s = very slow and meditative.
Min value in @keyframes morphShape 20px Minimum corner radius at the 0%/25%/50%/75% keyframes. Reduce to 4px for a more angular morph.
Max value in @keyframes morphShape 60px Maximum corner radius. Push it to 120px or 50% for an extreme amplitude between near-rectangle and ellipse.
scale() in .card-morph-expand.expanded scale(1.1) Card zoom factor on click (expand variant). Lower to scale(1.04) for a subtle expansion.
box-shadow in .card-morph-expand.expanded rgba(99,102,241,.3) 0 25px 50px Glow color and spread on click. Replace rgba(99,102,241,.3) with your primary brand color.

FAQ

Yes. Add .card-morph:hover { animation-play-state: paused; } to your CSS — the shape freezes instantly on its current position on hover, with no jump.
Add overflow: hidden to the .card-morph element, then place an <img> inside with width:100%; height:100%; object-fit:cover;. The image corners will follow the organic shape at every frame.
Not in the supplied code. Add this rule to respect OS preferences: @media (prefers-reduced-motion: reduce) { .card-morph { animation: none; } }. The card remains visible with its initial --radius-xl: 1rem radius.