Transitions✨ Premium

Wipe Transition

The new theme covers the old one from left to right in 0.6 s, cut by clip-path: inset(), while a 3 px glowing line follows the border to the pixel: you see before and after at the same time, and where the limit runs. A second press sends the front back to the left; a 150 ms fade when the user reduces motion.

CSSWipeclip-path

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Transitions has 52 effects, including 9 free. Explore the category →

3 usage examples

Music stand in concert mode — an orchestra's sheet music app — Wipe Transition example 1

① Music stand in concert mode — an orchestra's sheet music app

WhenRight before walking on stage, the second violins are on the Allegretto of Beethoven's 7th, page 4: the player switches the light rehearsal score to the dark stage score.
WhyThe front moves like a page being covered and the line shows how far the switch has got; the staves do not move a single pixel for 0.6 s, so the player does not lose the bar.
SettingsReversed layers: light score #fbf8f1 below, dark score #141210 revealed; 496 × 324 px scene; the same staff SVG in both layers in currentColor; a 'Concert mode' toggle above the layers, bottom left.
High-contrast version — a pension fund's website — Wipe Transition example 2

② High-contrast version — a pension fund's website

WhenA visually impaired member checks their career statement (148 quarters out of 172) and turns on 'High contrast' at the top right: the standard page gives way to a black-on-white version with 2 px borders.
WhyDuring the wipe, the sharp border shows before and after side by side: the member sees it is the same information, in the same place, only easier to read.
SettingsFull-page scene, 540 × 360 px; white revealed layer, black text, 2 px borders, yellow #ffd400 accents on the header and button; toggle above the layers.
Track mode to road mode — an electric motorcycle's dashboard — Wipe Transition example 3

③ Track mode to road mode — an electric motorcycle's dashboard

WhenLeaving the circuit, the rider presses the MODE button on the handlebar switch: the dark track display, red accents, gives way to the light road display, blue accents, at 87 km/h.
WhyThe horizontal wipe reads at a glance and the glowing line stays visible even in full sun; speed and range do not move during the switch.
SettingsEffect direction kept (dark below, light revealed); 460 × 230 px screen with 40 px top corners; 86 px main figure; a physical MODE button under the screen drives the active class.

How it works

The scene .th-wipe-scene (300 × 220 px, 16 px corners, overflow: hidden) overlaps two layers of its exact size with position: absolute; inset: 0: .th-wipe-dark (background #0c0a09) below, .th-wipe-light (background #fff7ed) on top, each with its own version of the title, line of text and chips, centered in a column. At rest, the light layer is clipped from the right across its whole width: clip-path: inset(0 100% 0 0). The .active class brings it back to inset(0) with transition: clip-path .6s cubic-bezier(.4, 0, .2, 1): its visible part grows from the left edge to the right edge, with nothing sliding — the text stays still, only the border moves.

The line is a third layer, .th-wipe-line, as wide as the scene and ignoring the pointer (pointer-events: none), whose ::before pseudo-element draws a 3 px violet-to-pink bar with a 12 px glow on its left edge. It goes from translateX(0) to translateX(100%) — 100% of its own width, so of the scene — with the same duration and curve as the clipping. The movement goes through transform, which the browser animates without recomputing layout. Measured every 80 ms: front and line at the same position to a tenth of a pixel in Chromium 151 and Firefox 153 (192.2 / 192.2 px at 240 ms); in WebKit 26, the line runs 1 to 11 px ahead of the front mid-course.

The script (0.6 KB) arms every .th-wipe-scene declared role="button": click, Enter and Space toggle .active and update aria-pressed. Removing the class plays everything backwards: the front heads back left with its line (measured 67 px in Chromium, 91 px in Firefox 300 ms after the second click). A scene without role="button" is not armed: that is the intended way to drive the switch from your own toggle, as in the examples below. At rest, the line stays visible along the left edge; once the switch is done, it leaves on the right, hidden by the scene. The effect does not read prefers-color-scheme and remembers nothing: you decide the starting state.

Accessibility

  • Keyboard and role: the demo scene is a focusable role="button" (tabindex="0"), named 'Light theme', with aria-pressed. Measured: reached with the Tab key in Chromium and WebKit, toggled by Enter and by Space in all three engines; a 2 px violet outline on keyboard focus. In a real interface, prefer a visible <button> that drives the scene (see the examples): a whole clickable panel is hard to guess.
  • Duplicated content: both layers carry the same text and the light layer is marked aria-hidden. On the demo, the button's name covers the reading; if you drive the scene from a separate button, alternate aria-hidden between the two layers on each switch, as the examples do.
  • Reduced motion: under prefers-reduced-motion: reduce, no wipe and no line (hidden); the light layer arrives with a 150 ms opacity fade. Measured: opacity 0.39 (Chromium) and 0.22 (Firefox) 60 ms after the click, 1 at 300 ms.
  • Contrast: on the light theme, the line of text is #78716c (4.5:1 on #fff7ed) and the chips 4.0:1; on the dark theme, the line is at 5.3:1. The glowing line is only a visual marker: no information depends on its color alone.

Browser compatibility

CSS (animated clip-path: inset(), transform, pseudo-element, :focus-visible) + 0.6 KB of JavaScript, no dependency. Measured in Chromium 151, Firefox 153 and WebKit 26: layers overlapping, same round trip, same keys; line/front sync exact in Chromium and Firefox, a 1 to 11 px gap in WebKit. Unprefixed clip-path with inset() and transitions exists since Chrome 55, Firefox 54 and Safari 12.1. The minimum versions come from inset: 0, which stacks the layers: Chrome and Edge 87, Firefox 66, Safari 14.1 (iOS 14.5).

Chrome 87+✓ Full
Firefox 66+✓ Full
Safari 14.1+✓ Full (line slightly ahead)
Edge 87+✓ Full
Mobile iOS 14.5+✓ Full (line slightly ahead)
Android Chrome 87+✓ Full

Without clip-path, the light layer is never clipped: the scene stays light and only the line crosses it. Without JavaScript, the scene stays dark and does not react; setting active in the HTML serves the light theme directly.

The code

HTML structure to paste into your page (the CSS + JS come with Premium):

index.html — structure
<div class="th-wipe-root">
  <div class="th-wipe-scene" role="button" tabindex="0" aria-pressed="false" aria-label="Light theme">
    <div class="th-wipe-dark">
      <h3>…</h3><p>…</p>
      <div class="th-wipe-chips">…</div>
    </div>
    <div class="th-wipe-light" aria-hidden="true">
      <h3>…</h3><p>…</p>
      <div class="th-wipe-chips">…</div>
    </div>
    <div class="th-wipe-line" aria-hidden="true"></div>
  </div>
</div>
Unlock the full code — $9.90/mo incl. tax

The full HTML + CSS + JS of Wipe Transition, ready to paste — plus all 840 effects. Or $299 once, lifetime access.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Duration and curve (CSS — transition on .th-wipe-light and .th-wipe-line) .6s cubic-bezier(.4, 0, .2, 1) Change both values together, otherwise the line drifts away from the front. 0.9 s for a weighty page, 0.4 s for a quick switch.
Wipe direction (CSS — resting clip-path and translateX) left to right: inset(0 100% 0 0) Right to left: inset(0 0 0 100%) at rest, and the line from translateX(100%) to translateX(0), drawn on the left edge. Top to bottom: inset(0 0 100% 0) and a horizontal line moved with translateY.
Line (CSS — .th-wipe-line::before) 3 px, #8b5cf6 → #ec4899 gradient, 12 px glow 1 px with no glow for a sober look; 6 px for a display seen from afar. Removing .th-wipe-line gives a wipe with no marker.
Colors of both themes (CSS — backgrounds of .th-wipe-dark / .th-wipe-light, then titles, lines, chips) #0c0a09 and #fff7ed Each layer has its own text rules; check 4.5:1 on each one's secondary line.
Trigger (HTML — role="button" on the scene) the whole scene is the button Remove role, tabindex and aria-pressed from the scene, and toggle .active from your own button: the script no longer touches the scene.
Reduced motion (CSS — @media (prefers-reduced-motion: reduce) block) 150 ms fade, line hidden transition: none for an instant change.

FAQ

Because a percentage translateX refers to the element's own width: a 3 px bar could only move 3 px for 100%. A layer as wide as the scene, drawing the bar on its left edge, moves exactly the width of the scene, whatever it is, and follows the front with no hard-coded pixel. Animating left would draw the same path, but recompute layout on every frame.
The wipe turns around wherever it is, with no jump: an interrupted CSS transition heads for the requested state from its current position. Measured with a second click 300 ms after the first, in Chromium 151 and Firefox 153: the front, then at about 230 px out of 300, goes back to the left edge in a little under half a second, faster than a full sweep, and the line stays on the front to a tenth of a pixel. The scene ends dark with aria-pressed="false": the state always follows the last click. If you would rather ignore clicks during the wipe, wait for the light layer's transitionend event before accepting the next one.
Both overlap two full layers and clip one. Dark Mode grows the new theme as a circle from the switch: the gesture and the change are tied together. Wipe Transition moves it in a straight line with a marker on the border: for 0.6 s, before and after sit side by side, which helps when the switch changes readability (high contrast, road display) or when it has no visible starting point.