No-JavaScript Fallback

The problem

@squircle-js/svelte relies on JavaScript to measure element dimensions (via ResizeObserver) and compute the SVG clip-path. When JavaScript is disabled or hasn't loaded yet, the element will have no clip-path applied, leaving it unstyled.

To handle this gracefully, the package ships SquircleNoScript.

How SquircleNoScript works

SquircleNoScript renders a <noscript> block into the document <head> containing a CSS rule:

[data-squircle] {
clip-path: none !important;
border-radius: attr(data-squircle) !important;
}

Every Squircle (or element with use:squircle) writes the cornerRadius value to a data-squircle attribute. When JavaScript is disabled, the browser applies the noscript CSS, which:

  1. Removes the (non-functional) clip-path
  2. Falls back to standard border-radius using the radius stored in data-squircle

The result is a rounded element that looks correct even without JavaScript — not a perfect squircle, but a clean, rounded shape that matches the intended cornerRadius.

Setup in SvelteKit

Add SquircleNoScript once in your root layout:

<!-- src/routes/+layout.svelte -->
<script>
import { SquircleNoScript } from "@squircle-js/svelte";
</script>
<SquircleNoScript />
<slot />

Because SquircleNoScript uses <svelte:head> internally, the <noscript> block lands in the document <head> where it belongs. It only renders inside a <noscript> tag, so it has zero impact on JavaScript-enabled users.

No other configuration is needed. All Squircle components and use:squircle elements on the page automatically benefit from the fallback.

SSR considerations

During server-side rendering, the clip-path is not yet computed — actions only run on the client in Svelte. This means there is a brief window on first paint where a Squircle element may appear without a clip-path, particularly when neither defaultWidth / defaultHeight nor explicit width / height are provided.

To minimise this:

  • Prefer StaticSquircle for elements with fixed dimensions. Once the client hydrates, the clip-path applies immediately and stably.
  • Provide defaultWidth and defaultHeight to dynamic Squircle instances when you know a reasonable starting size.

What users see

ScenarioVisual result
JavaScript enabledFull squircle clip-path
JavaScript disabled, SquircleNoScript presentRounded corners via border-radius
JavaScript disabled, no SquircleNoScriptSquare element (no rounding)
SSR, before hydrationSquare element; clip-path applies on mount

Progressive enhancement checklist

  • Include <SquircleNoScript /> once in your +layout.svelte
  • Prefer StaticSquircle for any element whose size is known at authoring time
  • Pass defaultWidth / defaultHeight to dynamic Squircle instances when possible
  • Treat the squircle shape as a visual polish, not a structural guarantee — content should remain readable without it