Skip to content

Configuration

NuvoUI core is configured with Sass module configuration: you pass variables in a with (...) clause when you load it. Every setting has a default, so an empty configuration works; you set only what you change.

@use "@nuvoui/core" as * with (
$generate-utility-classes: true,
$brand: #4361ee,
$feature-flags: ("animations": false)
);
  • Configure once. Sass loads a module once per compilation, so the configuration goes on the first @use of core. A second @use ... with of the same module fails with This module was already loaded, so it can't be configured using "with".
  • Only known variables. A variable that core does not declare fails with This variable was not declared with !default in the @used module. This is also how removed 1.x settings such as $primary and $secondary are reported.
  • Maps replace, they do not merge. A scale map such as $spacings or $font-sizes replaces the default map, so include every key you use. The exceptions are $feature-flags, where a missing flag counts as on, and the theme maps, which hold overrides only.

In a project with several stylesheets, put the configuration in one partial and load that partial everywhere.

styles/_nuvoui.scss
@forward "@nuvoui/core" with (
$generate-utility-classes: true,
$brand: #4361ee
);
styles/components/_card.scss
@use "../nuvoui" as *;
.card {
@include apply(p(4), bg(surface), rounded(lg));
}

Core emits CSS when it is loaded: the reset, the base element styles, the tokens and, when enabled, the utility classes. Within one compilation that CSS is emitted once, however many files load the partial. A stylesheet compiled on its own, as a separate entry point, emits it again.

Output Emitted when
Reset (@layer reset) Always
Base element styles and .sr-only (@layer base) The base flag is on (default)
Tokens: fixed :root block, light block, dark block, operating system fallback The theme flag is on (default)
Tooltips (@layer components) The tooltips flag is on (default), with or without utility classes
Utility classes $generate-utility-classes: true and the feature’s flag

Reset, base and components live in cascade layers (@layer reset, base, components). Utility classes and your own CSS are not in a layer, so they always win over the base styles without !important.

$generate-utility-classes decides whether the utility classes are emitted. It is false by default: a project that styles everything through apply() gets mixins, functions, tokens and base styles, and no classes.

// Mixins and tokens only
@use "@nuvoui/core" as *;
// Mixins, tokens and every utility class
@use "@nuvoui/core" as * with ($generate-utility-classes: true);

The prebuilt stylesheet in the package (dist/nuvoui.css and dist/nuvoui.min.css) is compiled with utility classes on and the default configuration.

$feature-flags turns groups of output on and off. Every flag is on by default, and a flag missing from your map counts as on, so the map lists only what you turn off.

@use "@nuvoui/core" with (
$generate-utility-classes: true,
$feature-flags: (
"animations": false,
"backdrops": false,
"tooltips": false
)
);

Turning a flag off removes output, never mixins: every mixin stays available in apply(). Each flag owns its classes completely.

Flag Controls
alignments Vertical alignment classes (align-top, align-middle)
animations Animation classes (animate-spin, hover-ready)
backdrops Backdrop filter classes
base Base element styles and .sr-only; needs no utility classes
borders Border width, colour, style and radius classes
container .container, .container.flex, .container.grid
container-queries Query container classes (container-inline-size, container-sidebar)
cursors Cursor classes
displays Display, visibility, overflow and truncation classes; not .flex or .grid
flex .flex, .flex.inline, .flex@{breakpoint} and every flex modifier and child class
grid .grid, .grid.inline, .grid@{breakpoint}, every grid modifier and the span classes
opacity Opacity classes
position Position, offset and inset classes
shadows Shadow classes
sizing Width, height, minimum and maximum size classes
spacing Padding, margin, gap and space classes
theme All tokens and the colour classes
tooltips Tooltip styles
transforms Transform classes
transitions Transition, duration, easing and delay classes
typography Font size, weight, line height, tracking, alignment, case, decoration and wrapping classes
z-index Z-index classes

Three flags need more care:

  • typography was named config-typo in 1.x. The old key is ignored in 2.0 (a missing flag counts as on), so ("config-typo": false) no longer turns anything off. Rename it.
  • flex and grid own every flex and grid class, including .container.flex and .container.grid. With ("displays": false), flex and grid layouts keep working.
  • theme off removes every token as well as the colour classes. Scale mixins then output raw values (p(4) gives 1rem), token() and colour words such as bg(brand), bg(red, 600) or text-color(muted) raise an error that says the theme flag is off, and base styles use the raw $font-family. black, white and transparent still compile, as plain CSS colours.
// Keep layout, drop the display utilities
@use "@nuvoui/core" with (
$generate-utility-classes: true,
$feature-flags: ("displays": false)
);

$parent-selector scopes the utility classes and the base element styles under a selector. Use it to add NuvoUI to part of a page that has other styles, such as a widget or a documentation site.

@use "@nuvoui/core" with (
$generate-utility-classes: true,
$parent-selector: ".app"
);
.app .p-4 {
padding: var(--nu-space-4);
}
@layer base {
body.app, .app:not(body) {
background-color: var(--nu-bg-base);
/* ... */
}
.app h1 {
/* ... */
}
}
Output Scoped by $parent-selector
Utility classes Yes: .app .p-4
Base element styles and .sr-only Yes: .app h1, and the body rules on the scope element
Light tokens On :root (global); nested light sections use .app [data-theme="light"]
Dark, inverse, operating system fallback and high contrast tokens No: global
Reset No: global

Tokens stay global so that every scope, and any CSS outside it, reads the same values. This site uses $parent-selector: ".nuvoui": the live examples render inside a .nuvoui element, while the documentation layout around them keeps its own styles.

The default is "", which emits unscoped classes.

$enable-dark-mode (default true) controls the dark theme. With false, core emits no dark token block, no prefers-color-scheme fallback, no data-theme="inverse" sections and no dark high contrast block; the dark-mode mixin outputs nothing. $dark-theme and $high-contrast-dark are then not used.

@use "@nuvoui/core" with (
$enable-dark-mode: false
);
Variable Default Purpose
$breakpoints xs 480px to 2xl 1536px Responsive suffixes, media query mixins, container widths
$base-size 1rem html font size in the base styles
$column-count 12 Flex fill-* columns, grid cols-*, rows-* and spans
$enable-debugger false Emits styles for a breakpoint debugging overlay (.NuvoUI-Debugger-Wrapper)

The default breakpoints:

SuffixMedia query
@xs@media (min-width: 480px)
@sm@media (min-width: 640px)
@md@media (min-width: 768px)
@lg@media (min-width: 1024px)
@xl@media (min-width: 1280px)
@2xl@media (min-width: 1536px)

Each map is described on the page that uses it.

Maps Page
$spacings, $percentages, $control-heights, $control-padding-inline Spacing, Sizing
$border-widths, $border-radii Borders
$shadow-sizes, $shadow-colors Shadows
$z-indexes, $z-index-levels Z-index
$opacities Opacity
$font-family, $font-sizes, $font-weights, $line-heights Typography
$durations, $delays, $timing-functions, $transition-default-duration, $transition-default-ease Transitions
$grid-item-sizes Grid
$brand, $success, $danger, $warning, $info, $color-primitives, $basic-colors Colours
$light-theme, $dark-theme, $high-contrast-light, $high-contrast-dark Theming

Base element styles read some keys from these maps: $spacings 1, 2 and 4, $border-radii xs, $border-widths 1 and 4, $font-sizes sm, base, lg, xl, 2xl, 3xl and 4xl, $font-weights normal and bold, $line-heights normal and tight, $control-heights and $control-padding-inline md, and the keys named by $transition-default-duration and $transition-default-ease. Removing one of them while the base flag is on raises an error that names the missing key and the map.

Every configuration variable is exported, so your own SCSS can read the configured values for compile-time maths.

@use "sass:map";
@use "@nuvoui/core" as nuvo;
.sidebar {
width: map.get(nuvo.$spacings, 64);
@include nuvo.media-up(lg) {
width: calc(map.get(nuvo.$breakpoints, lg) / 4);
}
}

Derived lists and internals are not public. $primitive-color-names (derived from $color-primitives) can be read but not configured; $theme-tokens, $color-names, $color-names-with-basic, $translate-values, $negative-translate-values, $colors-primitives, $digit-map, $colors and $color-cache are not exported, and neither are the functions to-css-var(), to-color(), from-hex(), hex-to-dec(), luminance(), is-valid-color(), is-valid-shade() and validate-theme-tokens() or the validate-tokens mixin.

For values that should follow the theme, read tokens with token() instead. See Tokens.