10 / 20
All 20 in 20 Tailwind SVG Stroke Buttons
- 01Tailwind SVG Stroke Draw Button Border on Hover
- 02Tailwind Stroke Dashoffset Button Outline Animation
- 03Tailwind Corner Start Perimeter Draw Button
- 04Tailwind Two Path Split Border Draw Button
- 05Tailwind Rounded Rect Stroke Button with rx Radius
- 06Tailwind Dashed Marching Ants Button Border
- 07Tailwind Gradient Stroke Button with SVG linearGradient
- 08Tailwind Stroke Draw Button That Reverses on Mouse Leave
- 09Tailwind Focus Visible Stroke Outline for Keyboard Users
- 10Tailwind Non Scaling Stroke Button That Resizes with Text
- 11Tailwind Stroke Draw Button with pathLength Normalization
- 12Tailwind Dual Layer Stroke Button with Offset Trailing Path
- 13Tailwind Sequential Stroke and Label Fade Button
- 14Tailwind Icon Plus Border Stroke Draw Together
- 15Tailwind Stroke Draw Submit Button Loading State
- 16Tailwind Stroke Draw Button Disabled and Error States
- 17Tailwind Scroll Triggered Button Stroke with animation-timeline
- 18Tailwind Stroke Draw Button Group with Staggered Delay
- 19Tailwind Reduced Motion Fallback for Stroke Buttons
- 20Tailwind Variable Width Stroke Button with Text Length
Tailwind Non Scaling Stroke Button That Resizes with Text
Six languages, right-to-left included, each button sized by its own text — and a border that does not draw but wipes, using [clip-path:inset(0_100%_0_0)] instead of a dash constant, so nothing has to know the perimeter at any label width. The Arabic row is the lesson: clip-path takes physical edges only, so it needs rtl:[clip-path:inset(0_0_0_100%)].
Nucleo: 44,000+ SVG icons in five families · All Icons Bundle $149
Nucleo · Affiliate link
The code
<section class="svgb-10 relative block w-full min-h-svh bg-svgb10-bg text-svgb10-fg font-svgb10-sans">
<input class="peer absolute opacity-0 pointer-events-none" type="checkbox" id="svgb-10-theme">
<label class="absolute z-[5] top-4 right-4 grid place-items-center size-11 rounded-full border border-current/20 bg-current/7 cursor-pointer transition-[background-color,transform] duration-150 hover:bg-current/15 active:scale-95 peer-focus-visible:outline-2 peer-focus-visible:outline-current peer-focus-visible:outline-offset-[3px] peer-checked:[&_svg]:rotate-180" for="svgb-10-theme">
<svg class="size-[18px] transition-transform duration-[400ms] ease-[cubic-bezier(0.2,0.7,0.3,1)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><circle cx="12" cy="12" r="8.5"/><path d="M12 3.5a8.5 8.5 0 0 0 0 17Z" fill="currentColor" stroke="none"/></svg>
<span class="absolute size-px overflow-hidden [clip-path:inset(50%)] whitespace-nowrap">Switch colour scheme</span>
</label>
<div class="min-h-svh grid place-items-center p-[clamp(22px,5vw,68px)]">
<div class="w-full max-w-220 flex flex-col gap-[clamp(20px,3vw,32px)]">
<p class="m-0 font-svgb10-serif italic text-[clamp(22px,3.6vw,38px)] tracking-[-0.02em] leading-[1.15]">One component · six locales · zero fixed widths</p>
<ul class="list-none m-0 p-0 flex flex-col gap-3.5">
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">en</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none">Start free trial</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">de</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="de">Kostenlos testen starten</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">fi</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="fi">Aloita maksuton kokeilujakso</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">ja</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="ja">無料デモ</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest" dir="rtl">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">ar</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="ar">ابدأ النسخة المجانية</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">live</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px] [&_[contenteditable]]:min-w-[4ch] [&_[contenteditable]]:[caret-color:var(--color-svgb10-stroke)]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" contenteditable="true" spellcheck="false">Type to resize the frame</span>
</button>
</li>
</ul>
<div class="grid gap-[clamp(16px,3vw,28px)] grid-cols-[repeat(auto-fit,minmax(min(100%,280px),1fr))] pt-1.5 border-t border-svgb10-rest">
<div class="flex flex-col gap-2">
<div class="relative grid place-items-center h-22">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true">
<rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="2" y="2" width="196" height="52" rx="14" vector-effect="non-scaling-stroke"/>
</svg>
<span class="relative font-svgb10-mono text-xs">non-scaling-stroke</span>
</div>
<code class="font-svgb10-mono text-[11px] text-svgb10-muted">even 2px on all four edges</code>
</div>
<div class="flex flex-col gap-2">
<div class="relative grid place-items-center h-22">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true">
<rect class="fill-none stroke-svgb10-warn [stroke-width:2]" x="2" y="2" width="196" height="52" rx="14"/>
</svg>
<span class="relative font-svgb10-mono text-xs">unprotected</span>
</div>
<code class="font-svgb10-mono text-[11px] text-svgb10-muted">uneven · the more-scaled axis paints thicker</code>
</div>
</div>
</div>
</div>
</section><section class="svgb-10 relative block w-full min-h-svh bg-svgb10-bg text-svgb10-fg font-svgb10-sans">
<input class="peer absolute opacity-0 pointer-events-none" type="checkbox" id="svgb-10-theme">
<label class="absolute z-[5] top-4 right-4 grid place-items-center size-11 rounded-full border border-current/20 bg-current/7 cursor-pointer transition-[background-color,transform] duration-150 hover:bg-current/15 active:scale-95 peer-focus-visible:outline-2 peer-focus-visible:outline-current peer-focus-visible:outline-offset-[3px] peer-checked:[&_svg]:rotate-180" for="svgb-10-theme">
<svg class="size-[18px] transition-transform duration-[400ms] ease-[cubic-bezier(0.2,0.7,0.3,1)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><circle cx="12" cy="12" r="8.5"/><path d="M12 3.5a8.5 8.5 0 0 0 0 17Z" fill="currentColor" stroke="none"/></svg>
<span class="absolute size-px overflow-hidden [clip-path:inset(50%)] whitespace-nowrap">Switch colour scheme</span>
</label>
<div class="min-h-svh grid place-items-center p-[clamp(22px,5vw,68px)]">
<div class="w-full max-w-220 flex flex-col gap-[clamp(20px,3vw,32px)]">
<p class="m-0 font-svgb10-serif italic text-[clamp(22px,3.6vw,38px)] tracking-[-0.02em] leading-[1.15]">One component · six locales · zero fixed widths</p>
<ul class="list-none m-0 p-0 flex flex-col gap-3.5">
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">en</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none">Start free trial</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">de</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="de">Kostenlos testen starten</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">fi</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="fi">Aloita maksuton kokeilujakso</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">ja</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="ja">無料デモ</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest" dir="rtl">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">ar</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="ar">ابدأ النسخة المجانية</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">live</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px] [&_[contenteditable]]:min-w-[4ch] [&_[contenteditable]]:[caret-color:var(--color-svgb10-stroke)]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" contenteditable="true" spellcheck="false">Type to resize the frame</span>
</button>
</li>
</ul>
<div class="grid gap-[clamp(16px,3vw,28px)] grid-cols-[repeat(auto-fit,minmax(min(100%,280px),1fr))] pt-1.5 border-t border-svgb10-rest">
<div class="flex flex-col gap-2">
<div class="relative grid place-items-center h-22">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true">
<rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="2" y="2" width="196" height="52" rx="14" vector-effect="non-scaling-stroke"/>
</svg>
<span class="relative font-svgb10-mono text-xs">non-scaling-stroke</span>
</div>
<code class="font-svgb10-mono text-[11px] text-svgb10-muted">even 2px on all four edges</code>
</div>
<div class="flex flex-col gap-2">
<div class="relative grid place-items-center h-22">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true">
<rect class="fill-none stroke-svgb10-warn [stroke-width:2]" x="2" y="2" width="196" height="52" rx="14"/>
</svg>
<span class="relative font-svgb10-mono text-xs">unprotected</span>
</div>
<code class="font-svgb10-mono text-[11px] text-svgb10-muted">uneven · the more-scaled axis paints thicker</code>
</div>
</div>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-svgb10-bg: #f7f5f0;
--color-svgb10-bg: oklch(0.972 0.008 90);
--color-svgb10-fg: #17161a;
--color-svgb10-fg: oklch(0.20 0.006 290);
--color-svgb10-muted: #6c6a75;
--color-svgb10-muted: oklch(0.555 0.012 290);
--color-svgb10-rest: rgba(23, 22, 26, 0.16);
--color-svgb10-rest: oklch(0.20 0.006 290 / 0.16);
--color-svgb10-stroke: #5b21f0;
--color-svgb10-stroke: oklch(0.46 0.26 295);
--color-svgb10-warn: #c4341f;
--color-svgb10-warn: oklch(0.53 0.19 32);
--font-svgb10-sans: 'Inter Tight', system-ui, sans-serif;
--font-svgb10-serif: 'Instrument Serif', ui-serif, Georgia, serif;
--font-svgb10-mono: 'JetBrains Mono', ui-monospace, monospace;
/* the seam marks the wipe front; inset-inline-start is logical, so the same
keyframe travels the correct way in both reading directions */
--animate-svgb10-seam: svgb10-seam 760ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
@keyframes svgb10-seam {
0% {
inset-inline-start: 0;
opacity: 0;
}
10% {
opacity: 1;
}
86% {
opacity: 1;
}
100% {
inset-inline-start: 100%;
opacity: 0;
}
}
.svgb-10:has(#svgb-10-theme:checked) {
--color-svgb10-bg: #0f0e12;
--color-svgb10-bg: oklch(0.18 0.006 290);
--color-svgb10-fg: #f0eff4;
--color-svgb10-fg: oklch(0.96 0.004 290);
--color-svgb10-muted: #918f9c;
--color-svgb10-muted: oklch(0.68 0.012 290);
--color-svgb10-rest: rgba(240, 239, 244, 0.18);
--color-svgb10-rest: oklch(0.96 0.004 290 / 0.18);
--color-svgb10-stroke: #c4a8ff;
--color-svgb10-stroke: oklch(0.82 0.15 295);
--color-svgb10-warn: #ff9478;
--color-svgb10-warn: oklch(0.75 0.16 32);
}@import "tailwindcss";
@theme {
--color-svgb10-bg: #f7f5f0;
--color-svgb10-bg: oklch(0.972 0.008 90);
--color-svgb10-fg: #17161a;
--color-svgb10-fg: oklch(0.20 0.006 290);
--color-svgb10-muted: #6c6a75;
--color-svgb10-muted: oklch(0.555 0.012 290);
--color-svgb10-rest: rgba(23, 22, 26, 0.16);
--color-svgb10-rest: oklch(0.20 0.006 290 / 0.16);
--color-svgb10-stroke: #5b21f0;
--color-svgb10-stroke: oklch(0.46 0.26 295);
--color-svgb10-warn: #c4341f;
--color-svgb10-warn: oklch(0.53 0.19 32);
--font-svgb10-sans: 'Inter Tight', system-ui, sans-serif;
--font-svgb10-serif: 'Instrument Serif', ui-serif, Georgia, serif;
--font-svgb10-mono: 'JetBrains Mono', ui-monospace, monospace;
/* the seam marks the wipe front; inset-inline-start is logical, so the same
keyframe travels the correct way in both reading directions */
--animate-svgb10-seam: svgb10-seam 760ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
@keyframes svgb10-seam {
0% {
inset-inline-start: 0;
opacity: 0;
}
10% {
opacity: 1;
}
86% {
opacity: 1;
}
100% {
inset-inline-start: 100%;
opacity: 0;
}
}
.svgb-10:has(#svgb-10-theme:checked) {
--color-svgb10-bg: #0f0e12;
--color-svgb10-bg: oklch(0.18 0.006 290);
--color-svgb10-fg: #f0eff4;
--color-svgb10-fg: oklch(0.96 0.004 290);
--color-svgb10-muted: #918f9c;
--color-svgb10-muted: oklch(0.68 0.012 290);
--color-svgb10-rest: rgba(240, 239, 244, 0.18);
--color-svgb10-rest: oklch(0.96 0.004 290 / 0.18);
--color-svgb10-stroke: #c4a8ff;
--color-svgb10-stroke: oklch(0.82 0.15 295);
--color-svgb10-warn: #ff9478;
--color-svgb10-warn: oklch(0.75 0.16 32);
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-svgb10-bg: #f7f5f0;
--color-svgb10-bg: oklch(0.972 0.008 90);
--color-svgb10-fg: #17161a;
--color-svgb10-fg: oklch(0.20 0.006 290);
--color-svgb10-muted: #6c6a75;
--color-svgb10-muted: oklch(0.555 0.012 290);
--color-svgb10-rest: rgba(23, 22, 26, 0.16);
--color-svgb10-rest: oklch(0.20 0.006 290 / 0.16);
--color-svgb10-stroke: #5b21f0;
--color-svgb10-stroke: oklch(0.46 0.26 295);
--color-svgb10-warn: #c4341f;
--color-svgb10-warn: oklch(0.53 0.19 32);
--font-svgb10-sans: 'Inter Tight', system-ui, sans-serif;
--font-svgb10-serif: 'Instrument Serif', ui-serif, Georgia, serif;
--font-svgb10-mono: 'JetBrains Mono', ui-monospace, monospace;
/* the seam marks the wipe front; inset-inline-start is logical, so the same
keyframe travels the correct way in both reading directions */
--animate-svgb10-seam: svgb10-seam 760ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
@keyframes svgb10-seam {
0% {
inset-inline-start: 0;
opacity: 0;
}
10% {
opacity: 1;
}
86% {
opacity: 1;
}
100% {
inset-inline-start: 100%;
opacity: 0;
}
}
.svgb-10:has(#svgb-10-theme:checked) {
--color-svgb10-bg: #0f0e12;
--color-svgb10-bg: oklch(0.18 0.006 290);
--color-svgb10-fg: #f0eff4;
--color-svgb10-fg: oklch(0.96 0.004 290);
--color-svgb10-muted: #918f9c;
--color-svgb10-muted: oklch(0.68 0.012 290);
--color-svgb10-rest: rgba(240, 239, 244, 0.18);
--color-svgb10-rest: oklch(0.96 0.004 290 / 0.18);
--color-svgb10-stroke: #c4a8ff;
--color-svgb10-stroke: oklch(0.82 0.15 295);
--color-svgb10-warn: #ff9478;
--color-svgb10-warn: oklch(0.75 0.16 32);
}@import "tailwindcss";
@theme {
--color-svgb10-bg: #f7f5f0;
--color-svgb10-bg: oklch(0.972 0.008 90);
--color-svgb10-fg: #17161a;
--color-svgb10-fg: oklch(0.20 0.006 290);
--color-svgb10-muted: #6c6a75;
--color-svgb10-muted: oklch(0.555 0.012 290);
--color-svgb10-rest: rgba(23, 22, 26, 0.16);
--color-svgb10-rest: oklch(0.20 0.006 290 / 0.16);
--color-svgb10-stroke: #5b21f0;
--color-svgb10-stroke: oklch(0.46 0.26 295);
--color-svgb10-warn: #c4341f;
--color-svgb10-warn: oklch(0.53 0.19 32);
--font-svgb10-sans: 'Inter Tight', system-ui, sans-serif;
--font-svgb10-serif: 'Instrument Serif', ui-serif, Georgia, serif;
--font-svgb10-mono: 'JetBrains Mono', ui-monospace, monospace;
/* the seam marks the wipe front; inset-inline-start is logical, so the same
keyframe travels the correct way in both reading directions */
--animate-svgb10-seam: svgb10-seam 760ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
@keyframes svgb10-seam {
0% {
inset-inline-start: 0;
opacity: 0;
}
10% {
opacity: 1;
}
86% {
opacity: 1;
}
100% {
inset-inline-start: 100%;
opacity: 0;
}
}
.svgb-10:has(#svgb-10-theme:checked) {
--color-svgb10-bg: #0f0e12;
--color-svgb10-bg: oklch(0.18 0.006 290);
--color-svgb10-fg: #f0eff4;
--color-svgb10-fg: oklch(0.96 0.004 290);
--color-svgb10-muted: #918f9c;
--color-svgb10-muted: oklch(0.68 0.012 290);
--color-svgb10-rest: rgba(240, 239, 244, 0.18);
--color-svgb10-rest: oklch(0.96 0.004 290 / 0.18);
--color-svgb10-stroke: #c4a8ff;
--color-svgb10-stroke: oklch(0.82 0.15 295);
--color-svgb10-warn: #ff9478;
--color-svgb10-warn: oklch(0.75 0.16 32);
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Inter+Tight:wght@400;500;600&family=JetBrains+Mono:wght@400&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Inter+Tight:wght@400;500;600&family=JetBrains+Mono:wght@400&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The webfonts load as
<link>tags insetup, not as an@importinside the stylesheet. Tailwind emits user@importrules after its own@layerblocks, and a late@importis invalid CSS — the browser drops it and the demo silently falls back to system fonts. - The wipe is
[clip-path:inset(0_100%_0_0)]at rest andgroup-hover:[clip-path:inset(0_0_0_0)]on hover — no dash constant anywhere, which is the point: nothing has to know the perimeter at any label width. clip-path: inset()takes physical edges only, so the Arabic row needsrtl:[clip-path:inset(0_0_0_100%)]. Tailwind’srtl:variant is exactly the right tool, and forgetting it is the bug this demo was built to surface.- The seam is positioned with
start-0and animated oninset-inline-start, both logical, so it travels with the reading direction while the clip has to be told twice. [vector-effect:non-scaling-stroke]is the single class that separates the corrected rect from the broken one — the two layers are otherwise character-for-character identical.- The unprotected stroke recolours on hover via
group-hover:stroke-[color-mix(...)], so the error is named in red at the moment the correction sweeps over it. - The live row uses
[&_[contenteditable]]:min-w-[4ch]to reach the editable label, letting you type and watch the frame resize without a fixed width anywhere.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Non Scaling Stroke Button That Resizes with Text
Source: https://codefronts.com/components/tailwind-svg-stroke-buttons/tailwind-non-scaling-stroke-button-that-resizes-with-text/
Six languages, right-to-left included, each button sized by its own text — and a border that does not draw but wipes, using [clip-path:inset(0_100%_0_0)] instead of a dash constant, so nothing has to know the perimeter at any label width. The Arabic row is the lesson: clip-path takes physical edges only, so it needs rtl:[clip-path:inset(0_0_0_100%)].
## HTML
```html
<section class="svgb-10 relative block w-full min-h-svh bg-svgb10-bg text-svgb10-fg font-svgb10-sans">
<input class="peer absolute opacity-0 pointer-events-none" type="checkbox" id="svgb-10-theme">
<label class="absolute z-[5] top-4 right-4 grid place-items-center size-11 rounded-full border border-current/20 bg-current/7 cursor-pointer transition-[background-color,transform] duration-150 hover:bg-current/15 active:scale-95 peer-focus-visible:outline-2 peer-focus-visible:outline-current peer-focus-visible:outline-offset-[3px] peer-checked:[&_svg]:rotate-180" for="svgb-10-theme">
<svg class="size-[18px] transition-transform duration-[400ms] ease-[cubic-bezier(0.2,0.7,0.3,1)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><circle cx="12" cy="12" r="8.5"/><path d="M12 3.5a8.5 8.5 0 0 0 0 17Z" fill="currentColor" stroke="none"/></svg>
<span class="absolute size-px overflow-hidden [clip-path:inset(50%)] whitespace-nowrap">Switch colour scheme</span>
</label>
<div class="min-h-svh grid place-items-center p-[clamp(22px,5vw,68px)]">
<div class="w-full max-w-220 flex flex-col gap-[clamp(20px,3vw,32px)]">
<p class="m-0 font-svgb10-serif italic text-[clamp(22px,3.6vw,38px)] tracking-[-0.02em] leading-[1.15]">One component · six locales · zero fixed widths</p>
<ul class="list-none m-0 p-0 flex flex-col gap-3.5">
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">en</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none">Start free trial</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">de</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="de">Kostenlos testen starten</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">fi</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="fi">Aloita maksuton kokeilujakso</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">ja</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="ja">無料デモ</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest" dir="rtl">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">ar</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="ar">ابدأ النسخة المجانية</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">live</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px] [&_[contenteditable]]:min-w-[4ch] [&_[contenteditable]]:[caret-color:var(--color-svgb10-stroke)]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" contenteditable="true" spellcheck="false">Type to resize the frame</span>
</button>
</li>
</ul>
<div class="grid gap-[clamp(16px,3vw,28px)] grid-cols-[repeat(auto-fit,minmax(min(100%,280px),1fr))] pt-1.5 border-t border-svgb10-rest">
<div class="flex flex-col gap-2">
<div class="relative grid place-items-center h-22">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true">
<rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="2" y="2" width="196" height="52" rx="14" vector-effect="non-scaling-stroke"/>
</svg>
<span class="relative font-svgb10-mono text-xs">non-scaling-stroke</span>
</div>
<code class="font-svgb10-mono text-[11px] text-svgb10-muted">even 2px on all four edges</code>
</div>
<div class="flex flex-col gap-2">
<div class="relative grid place-items-center h-22">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true">
<rect class="fill-none stroke-svgb10-warn [stroke-width:2]" x="2" y="2" width="196" height="52" rx="14"/>
</svg>
<span class="relative font-svgb10-mono text-xs">unprotected</span>
</div>
<code class="font-svgb10-mono text-[11px] text-svgb10-muted">uneven · the more-scaled axis paints thicker</code>
</div>
</div>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-svgb10-bg: #f7f5f0;
--color-svgb10-bg: oklch(0.972 0.008 90);
--color-svgb10-fg: #17161a;
--color-svgb10-fg: oklch(0.20 0.006 290);
--color-svgb10-muted: #6c6a75;
--color-svgb10-muted: oklch(0.555 0.012 290);
--color-svgb10-rest: rgba(23, 22, 26, 0.16);
--color-svgb10-rest: oklch(0.20 0.006 290 / 0.16);
--color-svgb10-stroke: #5b21f0;
--color-svgb10-stroke: oklch(0.46 0.26 295);
--color-svgb10-warn: #c4341f;
--color-svgb10-warn: oklch(0.53 0.19 32);
--font-svgb10-sans: 'Inter Tight', system-ui, sans-serif;
--font-svgb10-serif: 'Instrument Serif', ui-serif, Georgia, serif;
--font-svgb10-mono: 'JetBrains Mono', ui-monospace, monospace;
/* the seam marks the wipe front; inset-inline-start is logical, so the same
keyframe travels the correct way in both reading directions */
--animate-svgb10-seam: svgb10-seam 760ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
@keyframes svgb10-seam {
0% {
inset-inline-start: 0;
opacity: 0;
}
10% {
opacity: 1;
}
86% {
opacity: 1;
}
100% {
inset-inline-start: 100%;
opacity: 0;
}
}
.svgb-10:has(#svgb-10-theme:checked) {
--color-svgb10-bg: #0f0e12;
--color-svgb10-bg: oklch(0.18 0.006 290);
--color-svgb10-fg: #f0eff4;
--color-svgb10-fg: oklch(0.96 0.004 290);
--color-svgb10-muted: #918f9c;
--color-svgb10-muted: oklch(0.68 0.012 290);
--color-svgb10-rest: rgba(240, 239, 244, 0.18);
--color-svgb10-rest: oklch(0.96 0.004 290 / 0.18);
--color-svgb10-stroke: #c4a8ff;
--color-svgb10-stroke: oklch(0.82 0.15 295);
--color-svgb10-warn: #ff9478;
--color-svgb10-warn: oklch(0.75 0.16 32);
}
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Non Scaling Stroke Button That Resizes with Text
Source: https://codefronts.com/components/tailwind-svg-stroke-buttons/tailwind-non-scaling-stroke-button-that-resizes-with-text/
Six languages, right-to-left included, each button sized by its own text — and a border that does not draw but wipes, using [clip-path:inset(0_100%_0_0)] instead of a dash constant, so nothing has to know the perimeter at any label width. The Arabic row is the lesson: clip-path takes physical edges only, so it needs rtl:[clip-path:inset(0_0_0_100%)].
## HTML
```html
<section class="svgb-10 relative block w-full min-h-svh bg-svgb10-bg text-svgb10-fg font-svgb10-sans">
<input class="peer absolute opacity-0 pointer-events-none" type="checkbox" id="svgb-10-theme">
<label class="absolute z-[5] top-4 right-4 grid place-items-center size-11 rounded-full border border-current/20 bg-current/7 cursor-pointer transition-[background-color,transform] duration-150 hover:bg-current/15 active:scale-95 peer-focus-visible:outline-2 peer-focus-visible:outline-current peer-focus-visible:outline-offset-[3px] peer-checked:[&_svg]:rotate-180" for="svgb-10-theme">
<svg class="size-[18px] transition-transform duration-[400ms] ease-[cubic-bezier(0.2,0.7,0.3,1)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><circle cx="12" cy="12" r="8.5"/><path d="M12 3.5a8.5 8.5 0 0 0 0 17Z" fill="currentColor" stroke="none"/></svg>
<span class="absolute size-px overflow-hidden [clip-path:inset(50%)] whitespace-nowrap">Switch colour scheme</span>
</label>
<div class="min-h-svh grid place-items-center p-[clamp(22px,5vw,68px)]">
<div class="w-full max-w-220 flex flex-col gap-[clamp(20px,3vw,32px)]">
<p class="m-0 font-svgb10-serif italic text-[clamp(22px,3.6vw,38px)] tracking-[-0.02em] leading-[1.15]">One component · six locales · zero fixed widths</p>
<ul class="list-none m-0 p-0 flex flex-col gap-3.5">
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">en</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none">Start free trial</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">de</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="de">Kostenlos testen starten</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">fi</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="fi">Aloita maksuton kokeilujakso</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">ja</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="ja">無料デモ</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest" dir="rtl">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">ar</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" lang="ar">ابدأ النسخة المجانية</span>
</button>
</li>
<li class="flex items-center gap-4 pb-1 pt-3.5 border-t border-svgb10-rest">
<span class="flex-none w-[42px] font-svgb10-mono text-[10.5px] tracking-[0.14em] uppercase text-svgb10-muted">live</span>
<button class="group relative inline-grid place-items-center min-w-23 min-h-14 px-[26px] border-0 bg-transparent text-[15px] font-medium cursor-pointer focus-visible:outline-2 focus-visible:outline-svgb10-stroke focus-visible:outline-offset-[3px] [&_[contenteditable]]:min-w-[4ch] [&_[contenteditable]]:[caret-color:var(--color-svgb10-stroke)]" type="button">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-rest [stroke-width:2] transition-[stroke] duration-200 motion-reduce:transition-none group-hover:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)] group-focus-visible:stroke-[color-mix(in_oklab,var(--color-svgb10-warn)_45%,transparent)]" x="1" y="1" width="198" height="54"/></svg>
<svg class="absolute inset-0 w-full h-full overflow-visible [clip-path:inset(0_100%_0_0)] rtl:[clip-path:inset(0_0_0_100%)] transition-[clip-path] duration-[760ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true"><rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="1" y="1" width="198" height="54" vector-effect="non-scaling-stroke"/></svg>
<span class="absolute -inset-y-1 w-[1.5px] start-0 bg-svgb10-stroke opacity-0 pointer-events-none group-hover:animate-svgb10-seam group-focus-visible:animate-svgb10-seam motion-reduce:hidden" aria-hidden="true"></span>
<span class="relative z-[1] outline-none" contenteditable="true" spellcheck="false">Type to resize the frame</span>
</button>
</li>
</ul>
<div class="grid gap-[clamp(16px,3vw,28px)] grid-cols-[repeat(auto-fit,minmax(min(100%,280px),1fr))] pt-1.5 border-t border-svgb10-rest">
<div class="flex flex-col gap-2">
<div class="relative grid place-items-center h-22">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true">
<rect class="fill-none stroke-svgb10-stroke [stroke-width:2] [vector-effect:non-scaling-stroke]" x="2" y="2" width="196" height="52" rx="14" vector-effect="non-scaling-stroke"/>
</svg>
<span class="relative font-svgb10-mono text-xs">non-scaling-stroke</span>
</div>
<code class="font-svgb10-mono text-[11px] text-svgb10-muted">even 2px on all four edges</code>
</div>
<div class="flex flex-col gap-2">
<div class="relative grid place-items-center h-22">
<svg class="absolute inset-0 w-full h-full overflow-visible" viewBox="0 0 200 56" preserveAspectRatio="none" aria-hidden="true">
<rect class="fill-none stroke-svgb10-warn [stroke-width:2]" x="2" y="2" width="196" height="52" rx="14"/>
</svg>
<span class="relative font-svgb10-mono text-xs">unprotected</span>
</div>
<code class="font-svgb10-mono text-[11px] text-svgb10-muted">uneven · the more-scaled axis paints thicker</code>
</div>
</div>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-svgb10-bg: #f7f5f0;
--color-svgb10-bg: oklch(0.972 0.008 90);
--color-svgb10-fg: #17161a;
--color-svgb10-fg: oklch(0.20 0.006 290);
--color-svgb10-muted: #6c6a75;
--color-svgb10-muted: oklch(0.555 0.012 290);
--color-svgb10-rest: rgba(23, 22, 26, 0.16);
--color-svgb10-rest: oklch(0.20 0.006 290 / 0.16);
--color-svgb10-stroke: #5b21f0;
--color-svgb10-stroke: oklch(0.46 0.26 295);
--color-svgb10-warn: #c4341f;
--color-svgb10-warn: oklch(0.53 0.19 32);
--font-svgb10-sans: 'Inter Tight', system-ui, sans-serif;
--font-svgb10-serif: 'Instrument Serif', ui-serif, Georgia, serif;
--font-svgb10-mono: 'JetBrains Mono', ui-monospace, monospace;
/* the seam marks the wipe front; inset-inline-start is logical, so the same
keyframe travels the correct way in both reading directions */
--animate-svgb10-seam: svgb10-seam 760ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
@keyframes svgb10-seam {
0% {
inset-inline-start: 0;
opacity: 0;
}
10% {
opacity: 1;
}
86% {
opacity: 1;
}
100% {
inset-inline-start: 100%;
opacity: 0;
}
}
.svgb-10:has(#svgb-10-theme:checked) {
--color-svgb10-bg: #0f0e12;
--color-svgb10-bg: oklch(0.18 0.006 290);
--color-svgb10-fg: #f0eff4;
--color-svgb10-fg: oklch(0.96 0.004 290);
--color-svgb10-muted: #918f9c;
--color-svgb10-muted: oklch(0.68 0.012 290);
--color-svgb10-rest: rgba(240, 239, 244, 0.18);
--color-svgb10-rest: oklch(0.96 0.004 290 / 0.18);
--color-svgb10-stroke: #c4a8ff;
--color-svgb10-stroke: oklch(0.82 0.15 295);
--color-svgb10-warn: #ff9478;
--color-svgb10-warn: oklch(0.75 0.16 32);
}
```How this works
No constant, no problem. A dash draw needs the perimeter, and the perimeter changes with every translation. So this demo does not draw — it reveals a correct stroke over a broken one:
class="[clip-path:inset(0_100%_0_0)]
group-hover:[clip-path:inset(0_0_0_0)]
rtl:[clip-path:inset(0_0_0_100%)]
rtl:group-hover:[clip-path:inset(0_0_0_0)]"The two layers differ by one class. Both rects are stretched from the same fixed 200×56 viewBox, so the resting border is genuinely distorted — thin on the sides, heavy top and bottom. The corrected layer adds [vector-effect:non-scaling-stroke] and nothing else. What you watch on hover is a border becoming honest.
Physical values need rtl:; logical ones do not. inset() names top, right, bottom, left — there is no logical form. The seam, by contrast, is positioned with start-0 and animates inset-inline-start, so it flips for free. The demo puts both on the same screen because the difference is invisible until an Arabic label lands in production.
Naming the error. On hover the unprotected stroke recolours through group-hover:stroke-[color-mix(...)], so the distorted line turns red exactly as the corrected one sweeps across it. Without that, the two hairlines are too similar for the eye to separate.
Editable labels, no fixed widths. The live row's [&_[contenteditable]]:min-w-[4ch] keeps an emptied label from collapsing. Type into it and the frame resizes, with no width, no viewBox change and no remeasurement anywhere.
Make it yours
- Add a language by adding a row. There is no number to update, which is the entire argument of the demo.
- Change the wipe direction by editing the
inset()edges — and remember to edit thertl:pair too. - Swap the wipe for a fade if the sweep is too showy; the correction still reads because the stroke weight visibly changes.
- Retime with one
duration-*; the wipe is a single property so no shorthand is needed. - Remove the broken layer for production. It exists to make the correction visible, not because you need two strokes.
Gotchas — read before shipping
clip-path: inset()has no logical form. Every RTL layout needs thertl:twin, and forgetting it wipes from the wrong edge — a bug that only appears in the languages you are least likely to test.- Mixing physical and logical properties in one animation is how a seam ends up travelling opposite to its own reveal. Pick one per property and know which you picked.
vector-effect: non-scaling-strokechanges the stroke's rendered geometry, so filters and glows computed in user space no longer line up.- A stretched viewBox distorts stroke width on both axes unequally; a uniform scale would be fine, which is why this only shows up on auto-width buttons.
min-w-[4ch]on an editable element is not optional — an empty contenteditable collapses to zero and becomes impossible to click into.- Do not reintroduce a dash constant here to “improve” the effect. The measurement is exactly what this demo removes.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
clip-path: inset(), vector-effect and the logical inset properties are all widely supported; color-mix() and Tailwind v4's generated sheet set the floor. The rtl: variant compiles to a [dir="rtl"] selector and needs the direction declared on an ancestor.