Skip to content
NativeCSS
Docs contents

Known Limitations

Deliberate trade-offs, not bugs - every point here was found through real testing in real browsers and is solved this way on purpose, not overlooked.

Derived Color Tokens Don't React to Local Overrides

A custom property derived via color-mix() (e.g. --ncss-color-brand-100) is computed only once - where it's declared (:root) - and then inherited as a finished value. A seed value overridden locally deeper in the tree doesn't cause an already-inherited derivation to recompute. This only affects a theme applied locally (not on :root): components that use the seed directly (.ncss-btn--primary) react correctly; components that use the derived scale (.ncss-badge via -100/-on-soft) stay at the old color. A real theme.css on :root doesn't have this problem - see Theming.

Flex/Grid Children Get Automatically "Blockified"

A declared display: inline/inline-block on a direct child of a flex/grid container (.ncss-stack/-cluster/-grid/-flex) gets computed by the browser to display: block - not a bug, officially anchored in the spec, no opt-out provided. Affects .ncss-text-boxed (needs display:inline): always place it in a plain <div> wrapper, never directly as a flex/grid child - not even indirectly via a .ncss-card-body that itself carries .ncss-stack/-cluster/-grid or is --horizontal. display: contents doesn't solve it (removes its own box entirely).

.ncss-card-media Never Rounds Itself

border-radius: 0, so that .ncss-placeholder (has its own border-radius) doesn't round all four corners of the media when combined - the card itself (overflow: clip) handles rounding only where the media actually touches a real card corner.

.ncss-container--narrow Is Only a Modifier

Sets only max-width - always use it together with the base class (class="ncss-container ncss-container--narrow"). Used alone, centering is missing, the block sticks to the left, and a nested .ncss-full-bleed child inside it breaks out visibly askew.

<!-- Correct -->
<div class="ncss-container ncss-container--narrow">...</div>
<!-- Wrong: --narrow alone is missing the centering -->
<div class="ncss-container--narrow">...</div>

Never */ in the Middle of a CSS Comment

For example, a wildcard class mention like .ncss-radius-x/.ncss-shadow-x in prose - that character sequence ends the comment right there, and everything after it up to the next comment terminator gets parsed as real (broken) CSS code, often without a console error. After every comment change containing wildcard class names, check that no new instance has appeared.

helpers Can't Override components

A utility from helpers/ can't override a same-named property from components/, regardless of the order the classes appear in the class attribute - Cascade Layers evaluate by layer order, not source order, and components comes after helpers (see Architecture). class="ncss-card ncss-surface--brand" keeps the background of .ncss-card, for instance - for a colored card, use the component's own color variant instead (.ncss-card--brand).

Other Deliberate Trade-offs

  • initial-letter (drop cap) is not Baseline (Firefox has never shipped it). Safari needs -webkit-initial-letter, ncss declares both. Without support, the first letter simply stays normal size.
  • background-attachment: fixed is deliberately not used for parallax - it has always been disabled on iOS Safari. Instead animation-timeline: view() (.ncss-hero--parallax), @supports-gated.
  • Relative url() values inside a custom property resolve against the base URL of the stylesheet that consumes the property - not against the page that set it. background-image is therefore never passed through a custom property, but always set directly inline on the element.
  • .ncss-table-stacked deliberately breaks programmatic table semantics for screen readers - only use it when the content really should read like a list of record cards, otherwise use .ncss-table-scroll.
  • display: grid-lanes (true row-respecting masonry) is only available in very recent browsers - .ncss-masonry automatically falls back to the column-based CSS Columns approach when grid-lanes is unavailable.
  • Mega-menu positioning doesn't automatically dock to the viewport edge without CSS Anchor Positioning - max-width only prevents overflow; in very narrow windows the trigger may no longer sit centered under the menu.