Skip to main content
CodeAlchemy
Tailwind

Tailwind CSS v4.1: text shadows, masks, and more

CodeAlchemy Team··6 min read

Source: Tailwind CSS blog

v4.1 is the first feature drop after the v4.0 rewrite, and it leans into utilities the team had been asked for for years. Adam Wathan opens with a candid line:

I wasn't sure it would ever happen but we did it — we released a version of Tailwind CSS that includes text-shadow utilities.

TL;DR

  • `text-shadow-*` — finally, native utilities for legible headings over imagery.
  • `mask-*` — composable image and gradient masks; ergonomic enough to use in production layouts, not just demos.
  • `pointer-*` / `any-pointer-*` — variants that respect input device coarseness.
  • `@source not` and `@source inline` — finer control over what the compiler scans and what it bakes in unconditionally.
  • New state variantsnoscript, user-valid, inverted-colors, and a handful of others.

Text shadows

Tailwind shipped without text-shadow utilities for nearly a decade. The reason wasn't ideology — designers genuinely don't reach for text-shadow that often, and a flat scale didn't match the breadth of usage when they did. v4.1 lands a small stepped scale tuned for the most common case: keeping a heading legible against a busy hero image:

<h1 class="text-4xl text-white text-shadow-md text-shadow-black/40">
  Tailwind v4.1
</h1>

The default theme gives you text-shadow-xs through text-shadow-2xl, plus opacity modifiers. For more elaborate effects you can drop in arbitrary values, or extend the theme via @theme to create your own scale.

Masks

The CSS mask-* properties are notoriously verbose — multiple longhand variants, image-vs-gradient bifurcation, vendor prefixes still required for older browsers. v4.1 wraps that into a composable utility set:

  • `mask-image-*` — apply an image as a mask source.
  • `mask-linear-*` / `mask-radial-*` / `mask-conic-*` — gradient masks that read like the gradient utilities you already know.
  • `mask-clip-*` / `mask-origin-*` / `mask-mode-*` — fine-grained control of the mask layer.
  • `mask-no-repeat`, `mask-cover`, `mask-contain` — the size/repeat shortcuts.

A common pattern — fading the bottom of a long-scrolling feed — collapses to:

<div class="mask-linear-to-b mask-from-black mask-to-transparent">
  …content…
</div>

Pointer variants

Detecting input devices in CSS used to mean media queries embedded in arbitrary modifiers. v4.1 ships first-class variants:

  • `pointer-coarse:` — only when the primary input is coarse (most touchscreens).
  • `pointer-fine:` — only when the primary input is fine (mouse, trackpad, stylus).
  • `any-pointer-coarse:` / `any-pointer-fine:` — true if any attached pointer matches.

Hit targets that scale up on touch and stay compact on desktop are now:

<button class="px-3 py-1.5 pointer-coarse:px-4 pointer-coarse:py-3">
  Subscribe
</button>

The variants compose with the rest of the system, so pointer-coarse:hover:bg-brand-500 does what you expect.

`@source not` and `@source inline`

v4 already moved most projects off the content array. v4.1 fixes the remaining pain points:

  • `@source not "../legacy/"`** — exclude a folder from automatic scanning. Useful for vendored code you can't yet delete and don't want classes pulled from.
  • `@source inline("hidden md:flex group-hover:opacity-100")` — safelist classes that only ever exist as runtime strings. Replaces the old safelist array with something declarative and discoverable.

These two cover the cases where automatic detection was either too eager or not eager enough.

New variants

A grab-bag of state variants that cover edge cases the previous list missed:

  • `noscript:` — only when JavaScript is disabled.
  • `user-valid:` / `user-invalid:` — the modern form-validation pseudo-classes; no styling on initial render, only after the user has interacted.
  • `inverted-colors:` — respect the OS-level "Invert Colors" accessibility setting.
  • `details-content:` — style only the content of an open <details> (already in v4.0; expanded matchers in 4.1).

If you've been working around any of these via arbitrary attribute selectors, you can delete the workaround.

Upgrade

v4.1 is a drop-in bump on the v4 line. Upgrade with the package manager line for your setup:

npm install tailwindcss@latest @tailwindcss/vite@latest
# or
npm install tailwindcss@latest @tailwindcss/postcss@latest

There are no breaking changes. The compiler will pick up the new utilities and variants the next time it runs.

What v4.1 signals

The release pattern matters as much as the contents. v4.0 was the engine rewrite; v4.1 is the team showing they can ship focused feature drops on top of that engine without breaking compat. v4.2 followed with webpack and logical properties; later minors will keep filling in CSS-platform features (look for view-transitions and scroll-driven animations to land as utilities).

For now, the practical advice is: bump, scan your codebase for hand-rolled text-shadow and CSS mask declarations, replace them with utilities, and call it done.

Patterns the new utilities unlock

A few real-world layouts that used to require custom CSS but now collapse to utilities:

  • Hero with overlay text on imagery. text-shadow-md text-shadow-black/40 keeps headings legible against any background without injecting a tinted overlay div. The overlay div pattern was always a layout hack; with shadows native, it's simply unnecessary.
  • Edge-fade scrolling lists. mask-linear-to-b mask-from-black mask-to-transparent fades the bottom of an overflowing container so the cut-off feels intentional. Used to require either a positioned gradient sibling or a custom mask-image declaration.
  • Touch-vs-mouse hit targets. A button that's compact on desktop but generous on touch: px-3 py-1.5 pointer-coarse:px-4 pointer-coarse:py-3. Pre-v4.1, this required @media (pointer: coarse) blocks scattered across the styles.
  • Forms that respect "Invert Colors". macOS and iOS users with the accessibility setting enabled get genuinely awful contrast on app UIs that ignore it. inverted-colors:bg-fg inverted-colors:text-bg flips colors when the OS setting is active.
  • Progressive-enhancement fallbacks. noscript:hidden collapses elements that only make sense with JS, without a JS-driven class toggle.

Each of these is a small win on its own; together they remove a half-dozen tiny CSS files from a typical codebase.

What's coming next

v4.2 (already shipped) added webpack and logical properties. The team's public roadmap and GitHub discussions point at:

  • Scroll-driven animations — utilities for animation-timeline and view-timeline, the modern CSS primitives for scroll-triggered effects.
  • View transitions@view-transition and the corresponding view-transition-name utilities for cross-page animations.
  • Anchor positioninganchor-name, position-anchor, and the related properties for tooltip-style positioning that doesn't need JS.

None of these are confirmed for a specific minor, but the trajectory is clear: utilities for every CSS feature that browsers ship.

Source

Source / further reading: Tailwind CSS blog