Clip Path Reveal
Reveals text progressively left-to-right via a CSS clip-path: inset() animation — zero JavaScript, direction and timing configurable.
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. Text has 56 effects, including 4 free. Explore the category →
3 usage examples



How it works
The reveal relies on the CSS property clip-path: inset(). The .text-clip-reveal element starts with clip-path: inset(0 100% 0 0) — the clipping rectangle covers the full width from the right side, making the text completely invisible. The clipRevealAnim keyframe animation slides this rectangle to inset(0) (no clip on any side), revealing the text from left to right.
The animation shorthand on .text-clip-reveal reads 1s ease 0s 1 normal forwards running. The forwards fill-mode is critical — it keeps the final state (inset(0), text fully visible) after the animation ends, preventing a flash back to the initial clipped state.
The mechanism is pure CSS: no JavaScript is needed for the animation itself. To replay programmatically, force a reflow by removing the class, reading offsetWidth, then re-adding it — this resets the browser's animation context.
The reveal direction is controlled by the initial clip-path value: move the 100% to any of the four inset(top right bottom left) parameters to reveal from any edge — right, left, top, or bottom.
Accessibility
- prefers-reduced-motion: absent from code — no media query is included in the effect CSS. For broad audiences, add:
@media (prefers-reduced-motion: reduce) { .text-clip-reveal { animation: none; clip-path: inset(0); } } clip-pathis purely visual: it does not remove text from the DOM or accessibility tree — a screen reader reads the content even while it is visually clipped.- Contrast: white text (
#fff) on a dark background (#0a0a0f) far exceeds WCAG AA (ratio > 18:1). Verify contrast if you customise colours. - No keyboard interaction or focus behaviour in the effect — it is passive (CSS animation on load). No
tabIndexoraria-*attributes are needed for the effect alone. - For scroll-triggered use (IntersectionObserver + class addition), the text is already in the accessibility tree before the class is added: no information is hidden from screen reader users.
Browser compatibility
Requires CSS clip-path — supported in all modern browsers since 2017. Zero external dependencies, zero JavaScript.
If <code>clip-path</code> is unsupported (IE 11), text displays directly without animation — no JS errors, the page remains readable.
The code
HTML structure to paste into your page (CSS + JS available with a premium account):
<div class="demo-preview">
<!-- .text-clip-reveal applies to any text element -->
<span class="demo-text text-clip-reveal">YOUR TEXT</span>
</div>
<!-- Or directly on a heading -->
<h1 class="demo-text text-clip-reveal">Main title</h1>
Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
| Direction — initial inset on .text-clip-reveal | inset(0 100% 0 0) | Starting side of the reveal. inset(0 0 0 100%) = right→left; inset(0 0 100% 0) = top→bottom; inset(100% 0 0 0) = bottom→top. |
| Duration — 1st animation value | 1s | Animation duration. 0.4s for a snappy feel, 2s for cinematic pacing. |
| Easing — 2nd animation value | ease | Speed curve. linear for a mechanical sweep, cubic-bezier(0.25, 1, 0.5, 1) for momentum then deceleration. |
| Delay — 3rd animation value | 0s | Delay before start. Stagger multiple headings at 0s, 0.15s, 0.3s… to create a cascade effect. |
| font-size on .demo-text | 2.5rem | Text size. Use clamp(1.5rem, 5vw, 4rem) for responsive sizing. |
| font-weight on .demo-text | 800 | Text weight. 400 for a light editorial style, 900 for maximum impact. |
| Replay JS | — | To replay without a page reload: el.classList.remove('text-clip-reveal'); void el.offsetWidth; el.classList.add('text-clip-reveal'). Reading offsetWidth forces the reflow that resets the animation context. |
FAQ
.text-clip-reveal class to any text element and the effect fires on load. JavaScript is only needed to replay the animation or trigger it on scroll via IntersectionObserver.clip-path value on .text-clip-reveal. The syntax inset(top right bottom left) indicates which side masks the text at the start: inset(0 100% 0 0) = masked from the right (reveals left→right); inset(100% 0 0 0) = masked from the top (reveals bottom→top); inset(0 0 0 100%) = masked from the left (reveals right→left)..text-clip-reveal class from the initial HTML and set clip-path: inset(0 100% 0 0) via an inline style or a neutral class. An IntersectionObserver then adds .text-clip-reveal when the element enters the viewport — the browser fires the animation at the exact moment of visibility.