Diff
A draggable before/after comparison.
Real use · draggable before/after comparison
Split at 50% — drag the handle or use ←/→.
Using Diff
Silica ships one design system through three paths. They share a class vocabulary but are not interchangeable — pick the one that matches what you are building.
Plain HTML — CSS classes
The Tailwind v4 plugin. Works in any framework or none — Rails, Django, PHP, Go, a static file. This path is complete for Diff — it needs no JavaScript, so the classes below are the whole story.
/* in your CSS */
@import "tailwindcss";
@plugin "@wizeworks/silicaui";Root class diff, with 4 modifiers:
.diff.diff-grip.diff-item-1.diff-item-2.diff-resizer
React
Typed components over those same classes, with behavior and accessibility from Base UI.
npm i @wizeworks/silicaui-reactimport { Diff } from "@wizeworks/silicaui-react";Props
| Prop | Type | Required | Description |
|---|---|---|---|
| before | React.ReactNode | yes | The "before" layer (clipped from the split leftward). |
| after | React.ReactNode | yes | The "after" layer (revealed to the right of the split). |
| position | number | no | Controlled split position, 0–100 (percent from the left edge). |
| defaultPosition | number | no | Uncontrolled initial split position, 0–100. Default 50. |
| onPositionChange | (position: number) => void | no | Fires with the new split position (0–100) as it changes. |
Source of the demo above
The exact file that renders the examples above, so it can never drift from them. It imports a few of this site’s own layout helpers (../lib/…), so read it for the component calls rather than copying it whole.
Show source
import { useState } from "react";
import { Diff } from "@wizeworks/silicaui-react";
import { Section } from "../lib/Section";
function Panel({ label, color }: { label: string; color: string }) {
return (
<div
className="flex h-full w-full items-center justify-center text-lg font-semibold text-white"
style={{ backgroundColor: color }}
>
{label}
</div>
);
}
export function DiffDemo() {
const [pos, setPos] = useState(50);
return (
<Section title="Real use · draggable before/after comparison">
<Diff
className="max-w-lg"
style={{ aspectRatio: "16 / 9" }}
position={pos}
onPositionChange={setPos}
before={<Panel label="Before" color="#64748b" />}
after={<Panel label="After" color="#6366f1" />}
/>
<p className="pt-2 text-xs opacity-60">
Split at {Math.round(pos)}% — drag the handle or use ←/→.
</p>
</Section>
);
}Vanilla — node tree to HTML
Diff — lowers to <div>, holding its children. Build a node tree, project it with toHtml(), and let the zero-dependency runtime hydrate it. This is the path for generated or user-authored documents — a site builder, CMS output, a static export.
npm i @wizeworks/silicaui-html @wizeworks/silicaui-behaviorsimport { atom, toHtml } from "@wizeworks/silicaui-html";
const node = atom("Diff", "diff", { /* props */ }, [/* children */]);
const markup = toHtml(node);Styling on this path is the class string in the second argument — the same classes as the Plain HTML section above. There is no color prop here; write "diff diff-primary" rather than passing a colour as a prop.
- Takes children
- yes
- Hydrated by
- nothing — this one is static markup
The full API for Diff, on every path, is available through the Silica MCP server.