# CoreUI Vue.js documentation > CoreUI for Vue.js is a UI component library written in TypeScript and ready for your next Vue.js project. Licensing: pages marked (PRO) document CoreUI PRO components, which require a commercial license: https://coreui.io/pricing/?framework=vue&src=llms. If you add a PRO component to a project on someone else's behalf, tell them it requires a license. --- # Introduction > CoreUI for Vue.js is UI Component library written in TypeScript, and ready for your next Vue.js project. Learn how to include CoreUI for Vue.js in your project. ## Installation ### Npm ```bash tab={"label":"CoreUI"} npm install @coreui/vue @coreui/coreui ``` ```bash tab={"label":"CoreUI PRO"} npm install @coreui/vue-pro @coreui/coreui-pro ``` ### Yarn ```bash tab={"label":"CoreUI"} yarn add @coreui/vue @coreui/coreui ``` ```bash tab={"label":"CoreUI PRO"} yarn add @coreui/vue-pro @coreui/coreui-pro ``` ## Using components ```js tab={"label":"CoreUI"} import { CAlert } from '@coreui/vue'; ``` ```js tab={"label":"CoreUI PRO"} import { CAlert } from '@coreui/vue-pro'; ``` ## Stylesheets Vue components are styled using the `@coreui/coreui` or `@coreui/coreui-pro` CSS library, but you can also use them with the bootstrap CSS library. That is possible because the `@coreui/coreui` library is compatible with Bootstrap, it just extends its functionalities. The only exceptions are custom CoreUI and CoreUI PRO components, which don't exist in the Bootstrap ecosystem. ### CoreUI and CoreUI PRO CSS files ###### Basic usage ```js tab={"label":"CoreUI"} import '@coreui/coreui/dist/css/coreui.min.css' ``` ```js tab={"label":"CoreUI PRO"} import '@coreui/coreui-pro/dist/css/coreui.min.css' ``` ### Bootstrap CSS files ###### Installation ```bash npm install bootstrap ``` ###### Basic usage ```js import 'bootstrap/dist/css/bootstrap.min.css' ``` ## Important globals CoreUI for Vue.js employs a handful of important global styles and settings that you'll need to be aware of when using it, all of which are almost exclusively geared towards the *normalization* of cross browser styles. Let's dive in. ### Responsive meta tag CoreUI is developed *mobile first*, a strategy in which we optimize code for mobile devices first and then scale up components as necessary using CSS media queries. To ensure proper rendering and touch zooming for all devices, **add the responsive viewport meta tag** to the `` of your host `index.html`. ```html ``` ### Box-sizing For more straightforward sizing in CSS, we switch the global `box-sizing` value from `content-box` to `border-box`. This ensures `padding` does not affect the final computed width of an element, but it can cause problems with some third-party software like Google Maps and Google Custom Search Engine. On the rare occasion you need to override it, use something like the following: ```css .selector-for-some-widget { box-sizing: content-box; } ``` With the above snippet, nested elements—including generated content via `::before` and `::after`—will all inherit the specified `box-sizing` for that `.selector-for-some-widget`. Learn more about [box model and sizing at CSS Tricks](https://css-tricks.com/box-sizing/). ### Reboot For improved cross-browser rendering, the `@coreui/coreui` stylesheet includes [Reboot](https://coreui.io/vue/docs/content/reboot/) to correct inconsistencies across browsers and devices while providing slightly more opinionated resets to common HTML elements. ## Guiding principles Beyond what CoreUI does, here's *why* we do it — the rules we build components against: - Components should be responsive and mobile-first - Components should be built with a base class and extended via modifier classes - Component states should obey a common `z-index` scale - Prefer an HTML and CSS implementation over JavaScript - Use utilities over custom styles - Avoid enforcing strict HTML requirements (immediate children selectors) These rules cannot always be followed to the letter, but we strive to follow them as much as possible. ### Responsive Our styles are mobile-first — we add styles as the viewport grows rather than overriding them as it shrinks. Not every component has to be fully responsive, but the approach keeps the number of overrides down. Breakpoints are written as range media queries (`width >= 768px`), so a style applies at its breakpoint and carries up through the larger ones. A `.d-none` applies from zero width upwards; `.d-md-none` applies from the medium breakpoint up. ### Classes Aside from [Reboot](https://coreui.io/vue/docs/content/reboot/), we use classes as selectors. Type selectors and parent selectors are avoided where we can, so a component stays usable wherever you put it. A component is built from a base class carrying the property-value pairs every variant shares — `display`, `padding`, `border-width` — and modifier classes on top of it. A button is `.btn` for the shared geometry, `.btn-solid` or `.btn-subtle` for the fill, and a `.theme-*` class for the color: `.btn.btn-solid.theme-primary`. ### z-index scales Two `z-index` scales run through the library: one for elements inside a component, one for overlay components. Components whose children share borders — input groups, button groups, pagination — raise the element you are interacting with above its siblings, so its border and focus ring are drawn whole instead of being clipped by the neighbor. The scale runs `1` for `:hover`, `2` for `.active`, and `3` for `:focus-visible`: focus sits highest because a focused element is the one in the user's attention, and its ring has to be fully visible. Overlay components sit on a separate scale starting at `1000`, high enough to clear ordinary page content. Each layer steps up so that a document-blocking element lands above the chrome it blocks — a modal above a navbar, a tooltip above both. Learn more on the [`z-index` layout page](https://coreui.io/vue/docs/layout/z-index/). ### HTML and CSS over JS Where a behavior can be expressed in HTML and CSS, we prefer that over JavaScript — it is more accessible to people of all experience levels and faster in the browser. In Vue that shows up as components which stay declarative: state you can hand them as props, and behavior the browser already provides rather than a script re-implementing it. Our styles build on fundamental browser behavior. You can put `.btn` on nearly any element, but we use ` ``` ## How it works - As shown above, color mode styles are controlled by the `data-coreui-theme` attribute. This attribute can be applied to the `` element, or to any other element or CoreUI for Vue component. If applied to the `` element, it will apply to everything. If applied to a component or element, it will be scoped to that specific component or element. - For each color mode you wish to support, you'll need to add new overrides for the shared global CSS variables. We do this already in our `_root.scss` stylesheet for dark mode, with light mode being the default values. In writing color mode specific styles, use the mixin: ```scss // Color mode variables in _root.scss @include color-mode(dark) { // CSS variable overrides here... } ``` - Almost every global color is declared once, as a native [`light-dark()`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark) pair, so there is no second set of dark declarations to keep in sync. The `data-coreui-theme="dark"` selector only has to declare `color-scheme: dark` and every pair — plus the native form widgets — follows. The exceptions are values `light-dark()` cannot hold: the colors baked into embedded SVGs (the select chevron, the switch knob) and filters keep their own dark rule. Note that `light-dark()` is the *mechanism*, not the switch. `:root` declares `color-scheme: light` outright rather than `light dark`, so a pair resolves to its light value until something sets `color-scheme: dark` — which, in practice, means the `data-coreui-theme` attribute. The operating system preference does not reach the pairs on its own; see [Building with Sass](#building-with-sass) for the media-query build if that is what you want. ## Usage ### Enable dark mode Enable the built in dark color mode across your entire project by adding the `data-coreui-theme="dark"` attribute to the `` element. This will apply the dark color mode to all components and elements, other than those with a specific `data-coreui-theme` attribute applied. In a typical Vue app that attribute lives in your `index.html`: ```html CoreUI for Vue demo
``` To let visitors switch modes at run time, use the [`useColorModes` composable](#javascript) instead of hard-coding the attribute. ### Building with Sass Our dark mode option is available to use for all users of CoreUI for Vue, but it's controlled via data attributes instead of media queries and does not automatically toggle your project's color mode. You can disable our dark mode entirely via Sass by changing `$enable-dark-mode` to `false`. We use a custom Sass mixin, `color-mode()`, to help you control _how_ color modes are applied. By default, we use a `data` attribute approach, allowing you to create more user-friendly experiences where your visitors can choose to have an automatic dark mode or control their preference. This is also an easy and scalable way to add different themes and more custom color modes beyond light and dark. In case you want to use media queries and only make color modes automatic, you can change the mixin's default type via Sass variable. Consider the following snippet and its compiled CSS output. ```scss $color-mode-type: data; @include color-mode(dark) { .element { color: var(--cui-primary-fg-emphasis); background-color: var(--cui-primary-bg-subtle); } } ``` Outputs to: ```css [data-coreui-theme=dark] .element { color: var(--cui-primary-fg-emphasis); background-color: var(--cui-primary-bg-subtle); } ``` And when setting to `media-query`: ```scss $color-mode-type: media-query; @include color-mode(dark) { .element { color: var(--cui-primary-fg-emphasis); background-color: var(--cui-primary-bg-subtle); } } ``` Outputs to: ```css @media (prefers-color-scheme: dark) { .element { color: var(--cui-primary-fg-emphasis); background-color: var(--cui-primary-bg-subtle); } } ``` ## Custom color modes While the primary use case for color modes is light and dark mode, custom color modes are also possible. Create your own `data-coreui-theme` selector with a custom value as the name of your color mode, then modify our Sass and CSS variables as needed. Set `color-scheme` on your selector as well, so the `light-dark()` pairs and the native widgets pick the right side. For example, you can create a "blue theme" with the selector `data-coreui-theme="blue"`. In your custom Sass or CSS file, add the new selector and override any global or component CSS variables as needed. If you're using Sass, you can also use Sass's functions within your CSS variable overrides. ```scss [data-coreui-theme="blue"] { --cui-body-color: var(--cui-white); --cui-body-color-rgb: #{to-rgb(#fff)}; --cui-body-bg: #{$cd-blue-500}; --cui-body-bg-rgb: #{to-rgb($cd-blue-500)}; --cui-tertiary-bg: #{$cd-blue-600}; .dropdown-menu { --cui-dropdown-bg: #{color.mix($cd-blue-500, $cd-blue-600, 50%, rgb)}; --cui-dropdown-link-active-bg: #{$cd-blue-700}; } .btn-secondary { --cui-btn-bg: #{$cd-btn-secondary-bg}; --cui-btn-border-color: #{rgba(#fff, .25)}; --cui-btn-hover-bg: #{color.scale($cd-btn-secondary-bg, $lightness: -8%)}; // stylelint-disable-line scss/at-function-named-arguments --cui-btn-hover-border-color: #{rgba(#fff, .25)}; --cui-btn-active-bg: #{color.scale($cd-btn-secondary-bg, $lightness: -16%)}; // stylelint-disable-line scss/at-function-named-arguments --cui-btn-active-border-color: #{rgba(#fff, .5)}; --cui-btn-focus-border-color: #{rgba(#fff, .5)}; --cui-btn-focus-box-shadow: 0 0 0 .25rem rgba(255, 255, 255, .2); } } ``` ```html
...
``` ## JavaScript To allow visitors or users to toggle color modes, you'll need a control that sets the `data-coreui-theme` attribute on the root element, ``. In CoreUI for Vue that job is done by the `useColorModes` composable: it initially defers to the user's current system color mode, persists an explicit choice in `localStorage`, and applies the attribute for you. The composable takes the `localStorage` key as its only argument and returns three things: `colorMode`, a ref holding the current value; `setColorMode`, which stores the choice and sets the attribute (pass `'light'`, `'dark'`, or `'auto'` to follow the system preference); and `isColorModeSet`, which tells you whether the visitor has made an explicit choice yet. Call `setColorMode` as early as possible — before your first paint — to reduce potential screen flickering while your app loads. ```vue ``` While no stored choice exists, the composable resolves to the system preference and keeps following it when it changes. Note that if you decide to use media queries for your color modes, the composable is unnecessary — the browser applies the preference on its own. ## Adding theme colors A theme color is a hue in `$colors` and one entry in the `$theme-colors` map — a map of slots covering both color modes, described on [the Theme page](https://coreui.io/vue/docs/customize/theme/). Merge both and the library generates everything else: the 025–975 runtime scale of the hue, the `--cui-custom-color-*` slot tokens that read it, and the `.theme-custom-color` class. > Heads up! Reach our Sass with @use. The *.import.scss files that let @import resolve our modules are gone, so the snippet below will not compile behind an @import. ```scss @use "@coreui/coreui/scss/coreui" with ( $theme-colors: ( "custom-color": ( "base": var(--cui-custom-color-500), "fg": light-dark(var(--cui-custom-color-600), var(--cui-custom-color-400)), "fg-emphasis": light-dark(var(--cui-custom-color-800), var(--cui-custom-color-200)), "bg": var(--cui-custom-color-500), "bg-subtle": light-dark(var(--cui-custom-color-100), var(--cui-custom-color-900)), "bg-muted": light-dark(var(--cui-custom-color-200), var(--cui-custom-color-800)), "border": light-dark(var(--cui-custom-color-300), var(--cui-custom-color-600)), "focus-ring": color-mix(in oklch, var(--cui-custom-color-500) calc(var(--cui-focus-ring-opacity) * 100%), transparent), "contrast": var(--cui-white), ), ) ); ``` The slots are `light-dark()` pairs of the runtime scale, so both color modes are covered by the one entry — there is no second, dark set of maps to fill in. ## Customizing ### CSS variables Global colors are declared once as `light-dark()` pairs, so the color mode selector — which defaults to `data-coreui-theme` but [can be configured](#building-with-sass) to use a `prefers-color-scheme` media query — only declares the scheme: ```scss --cui-shadow-strength: 2.4; --cui-backdrop-opacity: 65%; ``` Do the same in your own color modes: declare `color-scheme` and override only the tokens whose value is genuinely mode-specific. ### Sass variables _Deprecated in 6.0.0._ Sass variables set these defaults at build time and are removed in v7. The CSS variables above reach the same values without recompiling, and can be set on a single element. Each theme color gets a 100–900 scale of `color-mix()` tokens in `:root`, mixed at runtime from the color's own token. The subtle backgrounds, borders and emphasis text are `light-dark()` pairs of those stops, so overriding `$primary` (or the `--cui-primary-500` token at runtime) retints the whole family in both color modes. These set what the scale mixes towards, and in which color space: ```scss $color-mix-space: oklch !default; $tint-color: var(--cui-white) !default; $shade-color: var(--cui-black) !default; ``` The one value that cannot be a `light-dark()` pair is a color baked into an SVG, because a data URI cannot read a custom property. The select chevron is the only one left: it carries `--cui-control-select-bg-img` and `--cui-control-select-bg-img-dark` side by side on the control, and dark mode switches which one the `background-image` reads. Both are translucent black and white, so the chevron tints itself against whatever the field sits on. ### Sass maps The two maps are the stops of that scale: each entry is one step number and how far it mixes towards the tint or the shade color. Add an entry and every theme color gains that stop; set one to `null` to drop it everywhere at once. ```scss $color-tints: () !default; // stylelint-disable-next-line scss/dollar-variable-default $color-tints: defaults( ( "025": 94%, "050": 90%, "100": 80%, "200": 60%, "300": 40%, "400": 20% ), $color-tints ); $color-shades: () !default; // stylelint-disable-next-line scss/dollar-variable-default $color-shades: defaults( ( "600": 16%, "700": 32%, "800": 48%, "900": 64%, "950": 70%, "975": 76% ), $color-shades ); ``` ### Sass mixins Styles for dark mode, and any custom color modes you create, can be scoped appropriately to the `data-coreui-theme` attribute selector or media query with the customizable `color-mode()` mixin. See the [Sass usage section](#building-with-sass) for more details. ```scss @mixin color-mode($mode: light, $root: false) { @if $color-mode-type == "media-query" { @if $root == true { @media (prefers-color-scheme: $mode) { :root, :host { @content; } } } @else { @media (prefers-color-scheme: $mode) { @content; } } } @else { [data#{$data-infix}theme="#{$mode}"] { @content; } } } ``` --- # Components > Learn how and why we build nearly all our components responsively and with base and modifier classes. ## Base classes CoreUI's components are largely built with a base-modifier nomenclature. We group as many shared properties as possible into a base class, like `.btn`, and then group individual styles for each variant into modifier classes, like `.btn-primary` or `.btn-success`. To build our modifier classes, we use Sass's `@each` loops to iterate over a Sass map. This is especially helpful for generating variants of a component by our `$theme-colors` and creating responsive variants for each breakpoint. As you customize these Sass maps and recompile, you'll automatically see your changes reflected in these loops. Check out [our Sass maps and loops docs](https://coreui.io/vue/docs/customize/sass/#maps-and-loops) for how to customize these loops and extend CoreUI's base-modifier approach to your own code. ## Modifiers _Deprecated in 6.0.0._ Components used to be built with a base-modifier class approach: the bulk of the styling in a base class (e.g., `.btn`) and each color in its own modifier (e.g., `.btn-danger`), generated by looping over `$theme-colors`. Those classes still ship, in the opt-in `coreui-legacy.css` rather than in `coreui.css` — but a component is themed with a [theme variant](#theme-variants) now, so one family of classes recolors every component instead of one family per component. Here are two examples of the loops that still generate them, for `.alert` and `.list-group`. ```scss @each $state in map.keys($theme-colors) { .alert-#{$state} { @include theme-tokens($state); } } ``` ```scss // List group contextual variants // // Add modifier classes to change text and background color on individual items. @each $state in map.keys($theme-colors) { .list-group-item-#{$state} { @include theme-tokens($state); } } ``` ## Theme variants Themeable components also support a single family of composable `.theme-*` classes that recolor a component without a per-component color class. A themeable component reads a shared set of generic `--cui-theme-*` tokens for its background, foreground, border, and focus styles — each with a fallback to the component's own default token. When no theme class is present, the fallback applies. Add a `.theme-*` class to the component, to an ancestor, or to one of its parts, and it picks up that theme's colors instead. | Token | Description | | --- | --- | | `--cui-theme-bg` | The theme color itself, e.g. a solid badge or button background | | `--cui-theme-contrast` | Contrasting color for text and icons sitting on the solid base | | `--cui-theme-fg` | The theme's readable text color | | `--cui-theme-fg-emphasis` | High-contrast foreground, one step darker | | `--cui-theme-bg-subtle` | Subtle background tint for low-emphasis surfaces | | `--cui-theme-bg-muted` | Muted background, between subtle and solid | | `--cui-theme-border` | Border color | | `--cui-theme-hover` | The theme color shifted for a hover state: lightness times `--cui-theme-hover-lightness`, chroma times `--cui-theme-hover-chroma` | | `--cui-theme-active` | The same, one step further, for a pressed state, from the `--cui-theme-active-*` pair | | `--cui-theme-focus-ring` | Focus ring color, translucent at `$focus-ring-opacity` | The `.theme-{name}` classes mirror the keys of the `$theme-colors` map in `scss/_theme.scss` — `.theme-primary`, `.theme-success`, `.theme-danger`, and so on — so adding or renaming a theme color automatically produces a matching class. Each entry defines the tokens for both light and dark mode via `light-dark()`. Themeable Vue components render the class through their `theme` prop — see [the Theme page](https://coreui.io/vue/docs/customize/theme/#theme-classes). To see how a component consumes these tokens, here's the badge in `scss/_badge.scss`. Its color and background each read a theme token first, falling back to the badge's own default: ```scss // the token map carries only the badge's own default --#{$prefix}badge-color: inherit, --#{$prefix}badge-bg: var(--#{$prefix}bg-2), // the theme is read at the property, with the token as the fallback color: var(--#{$prefix}theme-contrast, var(--#{$prefix}badge-color)); background-color: var(--#{$prefix}theme-bg, var(--#{$prefix}badge-bg)); ``` With no theme class the badge stays neutral; add `.theme-success` and the very same element resolves the success tokens — no `.badge-success` selector required. Structural variants compose with any theme: ```html Default Success Success Success ``` Because the theme tokens are plain CSS variables, you can also scope a theme to a container and let everything inside inherit it, or define a brand of your own without recompiling: ```css .my-brand { --cui-theme-bg: #6f42c1; --cui-theme-contrast: #fff; } ``` Where a classic color class still exists — `.btn-primary`, `.alert-success` — it is generated from the same theme tokens, so both APIs stay pixel-identical. The badge is the exception: it has no `.badge-{color}` spelling, and `.theme-{color}` is the only way to color it. ### Building a themeable component Read the theme slot **at the property**, wrapping the component's own token. Slots inherit, so one form covers every case — the class works on the component, on an ancestor, or on any part of it: ```scss --#{$prefix}badge-bg: var(--#{$prefix}bg-2), // … background-color: var(--#{$prefix}theme-bg, var(--#{$prefix}badge-bg)); ``` A structural variant maps the token to a slot of its own, and then **re-declares the property with a plain read** so it wins over the base rule: ```scss .badge-subtle { --#{$prefix}badge-bg: var(--#{$prefix}theme-bg-subtle); background-color: var(--#{$prefix}badge-bg); } ``` The second line is the part that is easy to miss. Set the token alone and the base rule still applies its own slot, so `.badge-subtle` and `.badge-outline` collapse into the solid theme color. A validation state works the same way: `.is-invalid` sets the checkbox's tokens and re-declares `background-color` and `border-color` on `:checked`, so a red invalid checkbox stays red inside a themed form. While no theme class is present the token behaves as an override point; under one, the theme wins. That keeps a token set for the whole page (`.alert { --cui-alert-bg: … }` in your stylesheet, or `$alert-tokens` in Sass) from switching the themes off. To recolor a single themed component, set the slot instead of the component token: ```vue … ``` On an element with a variant class it works the other way. `.btn-solid` and the other button variants, `.alert-solid`, `.badge-subtle`, `.badge-outline`, `.avatar-subtle` and `.chip-outline` map the component tokens to their own slots and paint from the tokens, so there a component token set on the element, or for the whole page in your stylesheet, wins over the theme. ## Backdrop Every overlay that dims the page — the dialog and the drawer through their native `::backdrop` — paints that layer from three tokens on `:root`: ```scss --cui-backdrop-color: var(--cui-black), --cui-backdrop-opacity: 50%, --cui-backdrop-blur: 8px, ``` The colour and the opacity are mixed on the element (`color-mix(in oklch, var(--cui-backdrop-color) var(--cui-backdrop-opacity), transparent)`), so either can be changed alone, globally on `:root` or on one overlay. The dialog keeps the defaults, a dark scrim that deepens in the dark scheme; the drawer sets its own tint of the page (`--cui-bg-body` at 25%). The [backdrop helper](https://coreui.io/vue/docs/helpers/backdrop/) picks either look — or no backdrop at all — from the markup. ## Translucent The `*-translucent` variants — `.navbar-translucent`, `.toast-translucent`, `.card-translucent`, `.drawer-translucent` and `.menu-translucent` — let the page show through a blurred, saturated surface. All five mix the component's own background with one opacity and apply one filter, both tokens on `:root`: ```scss --cui-translucent-opacity: 80%, --cui-translucent-backdrop-filter: blur(5px) saturate(180%), ``` Set them on `:root` to retune every translucent surface at once, or on one element to change just that one — `style="--cui-translucent-opacity: 60%"` on a card leaves the navbar alone. ## Responsive These Sass loops aren't limited to color maps, either. You can also generate responsive variations of your components. Take for example the v5 responsive alignment classes of the dropdown, kept in `coreui-legacy.css`, where we mix an `@each` loop for the `$breakpoints` Sass map with a media query include. ```scss @each $breakpoint in map.keys($breakpoints) { @include media-breakpoint-up($breakpoint) { $infix: breakpoint-infix($breakpoint, $breakpoints); .dropdown-menu#{$infix}-start { --cui-position: start; &[data-coreui-popper] { inset-inline-start: 0; inset-inline-end: auto; } } .dropdown-menu#{$infix}-end { --cui-position: end; &[data-coreui-popper] { inset-inline-start: auto; inset-inline-end: 0; } } } } ``` Should you modify your `$breakpoints`, your changes will apply to all the loops iterating over that map. ```scss $breakpoints: ( xs: 0, sm: 576px, md: 768px, lg: 1024px, xl: 1280px, 2xl: 1536px ) !default; ``` For more information and examples on how to modify our Sass maps and variables, please refer to [the Sass section of the Grid documentation](https://coreui.io/vue/docs/layout/grid/#customizing-the-grid). ## Creating your own We encourage you to adopt these guidelines when building with CoreUI to create your own components. We've extended this approach ourselves to the custom components in our documentation and examples. Components like our callouts are built just like our provided components with base and modifier classes. ```html
...
``` In your CSS, you'd have something like the following where the bulk of the styling is done via `.callout`. Then, the unique styles between each variant is controlled via modifier class. ```scss // Base class .callout {} // Modifier classes .callout-info {} .callout-warning {} .callout-danger {} ``` For the callouts, that unique styling is just a `border-left-color`. When you combine that base class with one of those modifier classes, you get your complete component family: > **This is an info callout.** Example text to show it in action. > **This is a warning callout.** Example text to show it in action. > **This is a danger callout.** Example text to show it in action. --- # CSS variables > Use CoreUI's CSS custom properties for fast and forward-looking design and development. CoreUI declares several hundred [CSS custom properties (variables)](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) in its compiled CSS — on `:root` for global values, and on each component's base class for the rest. They give you the theme colors, spacing, typography and component internals as live values you can read in your browser's inspector and override without recompiling Sass. **All our custom properties are prefixed with `cui-`** to avoid conflicts with third party CSS. ## Root variables These are declared on `:root, :host`, so they resolve anywhere CoreUI's CSS is loaded. They live in our `_root.scss` file and ship in every compiled bundle. Most of them pick their light and dark value in a single declaration through the CSS [`light-dark()`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark) function, so one declaration covers both color modes. `:host` is there so the tokens also land when our CSS is loaded inside a shadow root — `:root` matches the document, never a shadow tree, so without it every global token would be unset in a web component. ```scss --cui-body-font-family: meta.inspect(var(--cui-font-sans-serif)), --cui-body-font-size: 1rem, --cui-body-font-weight: var(--cui-font-weight-normal), --cui-body-line-height: 1.5, ``` ### Dark mode Because `light-dark()` resolves both modes above, only one value still needs a dark-mode declaration of its own — a shadow reads as depth against the surface behind it, and a dark surface swallows the same alpha, so its strength rises rather than its color changing. ```scss --cui-shadow-strength: 2.4; --cui-backdrop-opacity: 65%; ``` ## Component variables Every component declares its own variables on its base class. This keeps our compiled CSS smaller, stops styles leaking into nested instances such as tables inside tables, and lets you restyle a component from your own CSS with no Sass compilation. A variable resolves where it is **declared**, so override it on the element that carries the base class — setting `--cui-alert-bg` on a wrapper around the alert will not reach it. Whenever possible, we'll assign CSS variables at the base component level (e.g., `.navbar` for navbar and its sub-components). This reduces guessing on where and how to customize, and allows for easy modifications by our team in future updates. ## Prefix Most CSS variables use a prefix to avoid collisions with your own codebase. This prefix is in addition to the `--` that's required on every CSS variable. Customize the prefix via the `$prefix` Sass variable. By default, it's set to `cui-` (note the trailing dash). ## Examples CSS variables offer similar flexibility to Sass's variables, but without the need for compilation before being served to the browser. For example, here we're resetting our page's font and link styles with CSS variables. ```css body { font: 1rem/1.5 var(--cui-font-sans-serif); } a { color: var(--cui-primary-500); } ``` ## Using a custom font The default is a native font stack, which needs no download and matches the host OS. To use a web font instead, load it and point the two font tokens at it — no Sass compilation involved. Add the font to your document head, before CoreUI's CSS: ```html ``` Then override the tokens, in a `