Browser Support
Porchlight uses modern CSS without polyfills. Browser support, CSS bundler support, and the project’s test coverage are different questions.
Support matrix
| Area | Current contract |
|---|---|
| Package build | Lightning CSS targets Chrome 149; this preserves modern syntax, not a promise of identical behavior in every engine |
| Primary validation | Playwright Chromium: component, accessibility, layout, and visual tests |
| Additional coverage | Playwright Firefox and WebKit: narrow smoke tests for forms/app shell, dense tables, and native dialog behavior |
| Consumer responsibility | Check your own supported browser versions, components, themes, and interaction states |
Playwright WebKit is not a test of every shipping Safari version. The repo does not run a full minimum-version matrix for Chrome, Firefox, or Safari. Do not interpret the build target or a CSS specification’s publication date as an independently tested browser support floor.
Required features
| Feature | Why it matters |
|---|---|
| Cascade layers and custom properties | Layer ordering and design tokens |
@scope |
Most component rules are scoped; unsupported browsers can lose component styling entirely |
:has(), :is(), :where() |
Component states and low-specificity selectors |
OKLCH, light-dark(), color-mix() |
Theme tokens and derived colors |
| Logical properties, grid/flex, size container queries | Layout, RTL, and responsive component behavior |
| Native dialog / Popover API | Required when using the corresponding interactive HTML patterns |
For example, Firefox enabled @scope by default in 146; earlier versions
lack this required capability. See the
Firefox 146 release notes
and MDN’s @scope compatibility table.
This identifies one required capability, not a guarantee that every component
works identically from that version onward.
Progressive and experimental features
Fallbacks differ by component; some optional affordances disappear entirely.
| Feature | Use | Without support |
|---|---|---|
| Anchor positioning | Menus, calendar popovers, tooltips | Menus use their base positioning; tooltips are hidden, so keep essential labels visible elsewhere |
| Scroll-driven animations | Reveal and scroll-progress components | Reveal content stays visible; progress bar is hidden |
field-sizing: content |
Auto-growing textareas | Ordinary resizable textarea |
interpolate-size |
Intrinsic-size transitions | Base disclosure behavior; no intrinsic-size interpolation |
text-box |
Optical label alignment | Normal line-box alignment |
| Gap decorations | Optional grid dividers | Normal gaps without divider lines |
Typed attr() |
Color swatches | Supply application-owned dimensions and fallback appearance |
| Scroll-state queries | Scroll-region edges and stuck separators | Base scrollport, persistent border, and sticky positioning remain available |
| View transitions | Optional navigation animations | Cross-document navigation is disabled by default; apps must opt in |
How degradation works
@supports gates an optional browser feature; it cannot polyfill a required
feature such as @scope, and it cannot prevent a build tool from failing to
parse syntax inside the gate. The base component and its accessibility
contract still need to be checked in the target browser.
compat.css omits the dedicated enhancement layer. It still uses modern
component CSS, including @scope, color functions, and component-level feature
gates. It is a parser-friendly entry, not an old-browser compatibility layer.
See installation and Bun parser guidance.
Testing
- Chromium covers component contracts, composed apps, visual snapshots, RTL, forced colors, contrast preferences, reduced motion, and zoom.
- Firefox/WebKit smoke coverage is smaller; passing it does not establish full parity.
- Automated accessibility and deterministic color-contrast checks help detect regressions. They do not certify every composition or custom theme as WCAG-conformant.
- Applications own behaviors such as tab keyboard navigation, combobox state, focus management, and data loading. Native HTML semantics and CSS alone do not implement those controllers.