Version 0.1.0 just released! Check out the release notes from GitHub Releases

Replace Stair-Step Breakpoints With One Helper That Resolves to a CSS clamp() Expression at Build Time

Fluid Headline in React

Most "responsive headline" code is three or four @media blocks doubling the font size at each breakpoint. The result is fine at the breakpoints and a little janky in between. CSS clamp() fixes the jank — but typing the right clamp(min, fluid, max) for every size is tedious. Salty CSS ships defineViewportClamp so you author the helper once and call it with the reference size.

Define the helpers

// /styles/helpers.css.ts
import { defineViewportClamp } from "@salty-css/core/helpers";

// Reference at a 1920px desktop viewport.
// Output can shrink to 50% on small screens and grow to 125% on 4K.
export const fhdClamp = defineViewportClamp({
  screenSize: 1920,
  minMultiplier: 0.5,
  maxMultiplier: 1.25,
});

// A second helper for mobile-anchored values.
export const mobileClamp = defineViewportClamp({
  screenSize: 640,
  minMultiplier: 0.75,
  maxMultiplier: 1,
});

Use it in the React component

// /components/headline.css.ts
import { styled } from "@salty-css/react/styled";
import { fhdClamp, mobileClamp } from "../styles/helpers.css";

export const Headline = styled("h1", {
  base: {
    // Scales from ~48px on a phone to 120px on a 4K screen,
    // perfectly fluid in between. One declaration, no @media stack.
    fontSize: fhdClamp(96),
    lineHeight: 1.05,
    margin: 0,

    // For small viewports, swap to a mobile-anchored clamp so the
    // floor doesn't drop too aggressively at 320px.
    "@largeMobileDown": {
      fontSize: mobileClamp(48),
    },
  },
});

What it produces

fhdClamp(96) resolves at build time to a plain clamp(…, …vw, …) expression — the value is baked into saltygen/index.css. There is no defineViewportClamp call left in your bundle; the browser handles all the math from then on. Resize-listener gymnastics are not needed.

When to reach for it (and when not)

  • Reach for it for headlines, hero paddings, page gutters — anything you want to scale "with the viewport," not "at three breakpoints."
  • Don't reach for it when you actually want a stepped feel (a 1.25rem → 1.5rem jump at a design-system breakpoint). Variants or a media query express that intent more clearly.
  • Combine with defineVariables when you want the clamp values to live as design tokens. See the Viewport Clamp utility for the responsive-tokens pattern.

Gotchas

  • Reference size matters. screenSize: 1920 means "96px is the value at 1920px viewport." If your audience is mostly on 1366px laptops, anchor closer to that — or your min will pin everywhere.
  • Multipliers, not absolute caps. minMultiplier: 0.5 is "50% of 96" = 48px. Pass an explicit min as the second arg (fhdClamp(96, 42)) when you want a hard floor.
  • Vertical axis exists. Pass axis: 'vertical' to the helper for layouts that key off vh instead of vw (mobile portrait, full-bleed media).