774 lines
39 KiB
HTML
Raw Permalink Normal View History

<!doctype html>
<html lang="en" data-layout="default" data-shoelace-version="0.0.10">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Learn how to customize Nebula through parts and custom properties." />
<title>Customizing</title>
<meta name="turbo-cache-control" />
<link rel="stylesheet" href="/assets/styles/docs.css" />
<link rel="stylesheet" href="/assets/styles/code-previews.css" />
<link rel="stylesheet" href="/assets/styles/search.css" />
<link rel="icon" href="/assets/images/logo.svg" type="image/x-icon" />
<meta name="twitter:card" content="summary" />
<meta name="twitter:creator" content="shoelace_style" />
<meta name="twitter:image" content="https://nebulaui.org/assets/images/og-image.png" />
<meta property="og:url" content="https://nebulaui.org/getting-started/customizing/" />
<meta property="og:title" content="Customizing" />
<meta property="og:description" content="Learn how to customize Nebula through parts and custom properties." />
<meta property="og:image" content="https://nebulaui.org/assets/images/og-image.png" />
<link rel="stylesheet" href="/dist/themes/light.css" />
<link rel="stylesheet" href="/dist/themes/dark.css" />
<script type="module" src="/dist/shoelace-autoloader.js"></script>
<script>
(() => {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const theme = localStorage.getItem('theme') || 'auto';
document.documentElement.classList.toggle(
'sl-theme-dark',
theme === 'dark' || (theme === 'auto' && prefersDark)
);
})();
</script>
<script src="/assets/scripts/turbo.js" type="module"></script>
<script src="/assets/scripts/docs.js" defer=""></script>
<script src="/assets/scripts/code-previews.js" defer=""></script>
<script src="/assets/scripts/lunr.js" defer=""></script>
<script src="/assets/scripts/search.js" defer=""></script>
</head>
<body>
<a id="skip-to-main" class="visually-hidden" href="#main-content" data-smooth-link="false">
Skip to main content
</a>
<button id="menu-toggle" type="button" aria-label="Menu">
<svg width="148" height="148" viewBox="0 0 148 148" xmlns="http://www.w3.org/2000/svg">
<g stroke="currentColor" stroke-width="18" fill="none" fill-rule="evenodd" stroke-linecap="round">
<path d="M9.5 125.5h129M9.5 74.5h129M9.5 23.5h129"></path>
</g>
</svg>
</button>
<div id="icon-toolbar">
<a
href="https://github.com/onsonr/nebula"
title="View Nebula on GitHub"
class="external-link"
rel="noopener noreferrer"
target="_blank"
>
<sl-icon name="github"></sl-icon>
</a>
<a
href="https://twitter.com/shoelace_style"
title="Follow Nebula on Twitter"
class="external-link"
rel="noopener noreferrer"
target="_blank"
>
<sl-icon name="twitter"></sl-icon>
</a>
<sl-dropdown id="theme-selector" placement="bottom-end" distance="3">
<sl-button slot="trigger" size="small" variant="text" caret="" title="Press \ to toggle">
<sl-icon class="only-light" name="sun-fill"></sl-icon>
<sl-icon class="only-dark" name="moon-fill"></sl-icon>
</sl-button>
<sl-menu>
<sl-menu-item type="checkbox" value="light">Light</sl-menu-item>
<sl-menu-item type="checkbox" value="dark">Dark</sl-menu-item>
<sl-divider></sl-divider>
<sl-menu-item type="checkbox" value="auto">System</sl-menu-item>
</sl-menu>
</sl-dropdown>
</div>
<aside id="sidebar" data-preserve-scroll="">
<header>
<a href="/">
<img src="/assets/images/wordmark.svg" alt="Nebula" />
</a>
<div class="sidebar-version">0.0.10</div>
</header>
<div class="sidebar-buttons">
<sl-button
size="small"
class="repo-button repo-button--github"
href="https://github.com/onsonr/nebula"
target="_blank"
>
<sl-icon slot="prefix" name="github"></sl-icon> Code
</sl-button>
<sl-button
size="small"
class="repo-button repo-button--star"
href="https://github.com/onsonr/nebula/stargazers"
target="_blank"
>
<sl-icon slot="prefix" name="star-fill"></sl-icon> Star
</sl-button>
<sl-button
size="small"
class="repo-button repo-button--twitter"
href="https://twitter.com/shoelace_style"
target="_blank"
>
<sl-icon slot="prefix" name="twitter"></sl-icon> Follow
</sl-button>
</div>
<button class="search-box" type="button" title="Press / to search" aria-label="Search" data-plugin="search">
<sl-icon name="search"></sl-icon>
<span>Search</span>
</button>
<nav>
<ul>
<li>
<h2>Getting Started</h2>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/getting-started/installation">Installation</a></li>
<li><a href="/getting-started/usage">Usage</a></li>
<li><a href="/getting-started/themes">Themes</a></li>
<li><a href="/getting-started/customizing" class="active-link">Customizing</a></li>
<li><a href="/getting-started/form-controls">Form Controls</a></li>
<li><a href="/getting-started/localization">Localization</a></li>
</ul>
</li>
<li>
<h2>Frameworks</h2>
<ul>
<li><a href="/frameworks/react">React</a></li>
<li><a href="/frameworks/vue">Vue</a></li>
<li><a href="/frameworks/angular">Angular</a></li>
</ul>
</li>
<li>
<h2>Resources</h2>
<ul>
<li><a href="/resources/community">Community</a></li>
<li>
<a
href="https://github.com/onsonr/nebula/discussions"
class="external-link"
rel="noopener noreferrer"
target="_blank"
>Help &amp; Support</a
>
</li>
<li><a href="/resources/accessibility">Accessibility</a></li>
<li><a href="/resources/contributing">Contributing</a></li>
<li><a href="/resources/changelog">Changelog</a></li>
</ul>
</li>
<li>
<h2>Components</h2>
<ul>
<li>
<a href="/components/alert"> Alert </a>
</li>
<li>
<a href="/components/animated-image"> Animated Image </a>
</li>
<li>
<a href="/components/animation"> Animation </a>
</li>
<li>
<a href="/components/avatar"> Avatar </a>
</li>
<li>
<a href="/components/badge"> Badge </a>
</li>
<li>
<a href="/components/breadcrumb"> Breadcrumb </a>
</li>
<li>
<a href="/components/breadcrumb-item"> Breadcrumb Item </a>
</li>
<li>
<a href="/components/button"> Button </a>
</li>
<li>
<a href="/components/button-group"> Button Group </a>
</li>
<li>
<a href="/components/card"> Card </a>
</li>
<li>
<a href="/components/carousel"> Carousel </a>
</li>
<li>
<a href="/components/carousel-item"> Carousel Item </a>
</li>
<li>
<a href="/components/checkbox"> Checkbox </a>
</li>
<li>
<a href="/components/color-picker"> Color Picker </a>
</li>
<li>
<a href="/components/copy-button"> Copy Button </a>
</li>
<li>
<a href="/components/details"> Details </a>
</li>
<li>
<a href="/components/dialog"> Dialog </a>
</li>
<li>
<a href="/components/divider"> Divider </a>
</li>
<li>
<a href="/components/drawer"> Drawer </a>
</li>
<li>
<a href="/components/dropdown"> Dropdown </a>
</li>
<li>
<a href="/components/format-bytes"> Format Bytes </a>
</li>
<li>
<a href="/components/format-date"> Format Date </a>
</li>
<li>
<a href="/components/format-number"> Format Number </a>
</li>
<li>
<a href="/components/icon"> Icon </a>
</li>
<li>
<a href="/components/icon-button"> Icon Button </a>
</li>
<li>
<a href="/components/image-comparer"> Image Comparer </a>
</li>
<li>
<a href="/components/include"> Include </a>
</li>
<li>
<a href="/components/input"> Input </a>
</li>
<li>
<a href="/components/menu"> Menu </a>
</li>
<li>
<a href="/components/menu-item"> Menu Item </a>
</li>
<li>
<a href="/components/menu-label"> Menu Label </a>
</li>
<li>
<a href="/components/mutation-observer"> Mutation Observer </a>
</li>
<li>
<a href="/components/option"> Option </a>
</li>
<li>
<a href="/components/popup"> Popup </a>
</li>
<li>
<a href="/components/progress-bar"> Progress Bar </a>
</li>
<li>
<a href="/components/progress-ring"> Progress Ring </a>
</li>
<li>
<a href="/components/qr-code"> QR Code </a>
</li>
<li>
<a href="/components/radio"> Radio </a>
</li>
<li>
<a href="/components/radio-button"> Radio Button </a>
</li>
<li>
<a href="/components/radio-group"> Radio Group </a>
</li>
<li>
<a href="/components/range"> Range </a>
</li>
<li>
<a href="/components/rating"> Rating </a>
</li>
<li>
<a href="/components/relative-time"> Relative Time </a>
</li>
<li>
<a href="/components/resize-observer"> Resize Observer </a>
</li>
<li>
<a href="/components/select"> Select </a>
</li>
<li>
<a href="/components/skeleton"> Skeleton </a>
</li>
<li>
<a href="/components/spinner"> Spinner </a>
</li>
<li>
<a href="/components/split-panel"> Split Panel </a>
</li>
<li>
<a href="/components/switch"> Switch </a>
</li>
<li>
<a href="/components/tab"> Tab </a>
</li>
<li>
<a href="/components/tab-group"> Tab Group </a>
</li>
<li>
<a href="/components/tab-panel"> Tab Panel </a>
</li>
<li>
<a href="/components/tag"> Tag </a>
</li>
<li>
<a href="/components/textarea"> Textarea </a>
</li>
<li>
<a href="/components/tooltip"> Tooltip </a>
</li>
<li>
<a href="/components/tree"> Tree </a>
</li>
<li>
<a href="/components/tree-item"> Tree Item </a>
</li>
<li>
<a href="/components/visually-hidden"> Visually Hidden </a>
</li>
</ul>
</li>
<li>
<h2>Design Tokens</h2>
<ul>
<li><a href="/tokens/typography">Typography</a></li>
<li><a href="/tokens/color">Color</a></li>
<li><a href="/tokens/spacing">Spacing</a></li>
<li><a href="/tokens/elevation">Elevation</a></li>
<li><a href="/tokens/border-radius">Border Radius</a></li>
<li><a href="/tokens/transition">Transition</a></li>
<li><a href="/tokens/z-index">Z-index</a></li>
<li><a href="/tokens/more">More Tokens</a></li>
</ul>
</li>
<li>
<h2>Tutorials</h2>
<ul>
<li><a href="/tutorials/integrating-with-astro">Integrating with Astro</a></li>
<li><a href="/tutorials/integrating-with-laravel">Integrating with Laravel</a></li>
<li><a href="/tutorials/integrating-with-nextjs">Integrating with NextJS</a></li>
<li><a href="/tutorials/integrating-with-rails">Integrating with Rails</a></li>
</ul>
</li>
</ul>
</nav>
</aside>
<main>
<a id="main-content"></a>
<article id="content" class="content content--with-toc">
<div class="content__toc">
<ul>
<li class="top"><a href="#">Customizing</a></li>
<li data-level="2"><a href="#design-tokens">Design Tokens</a></li>
<li data-level="2"><a href="#css-parts">CSS Parts</a></li>
<li data-level="2"><a href="#custom-properties">Custom Properties</a></li>
<li data-level="2"><a href="#animations">Animations</a></li>
</ul>
</div>
<div class="content__body">
<h1>Customizing</h1>
<p>
Nebula components can be customized at a high level through design tokens. This gives you control over theme
colors and general styling. For more advanced customizations, you can make use of CSS parts and custom
properties to target individual components.
</p>
<h2 id="design-tokens" class="anchor-heading">
Design Tokens<a href="#design-tokens" aria-label='Direct link to "Design Tokens"'></a>
</h2>
<p>
Nebula makes use of several design tokens to provide a consistent appearance across components. You can
customize them and use them in your own application with pure CSS — no preprocessor required.
</p>
<p>
Design tokens offer a high-level way to customize the library with minimal effort. There are no
component-specific variables, however, as design tokens are intended to be generic and highly reusable. To
customize an individual component, refer to the section entitled <a href="#css-parts">CSS Parts</a>.
</p>
<p>
Design tokens are accessed through CSS custom properties that are defined in your theme. Because design
tokens live at the page level, theyre prefixed with <code>--sl-</code> to avoid collisions with other
libraries.
</p>
<p>
To customize a design token, simply override it in your stylesheet using a <code>:root</code> block. Heres
an example that changes the primary theme to purple based on existing
<a href="/tokens/color#primitives">color primitives</a>.
</p>
<pre><code class="language-css" id="code-block-35"><span class="token selector">:root</span> <span class="token punctuation">{</span>
<span class="token comment">/* Changes the primary theme color to purple using primitives */</span>
<span class="token property">--sl-color-primary-50</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--sl-color-purple-50<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token property">--sl-color-primary-100</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--sl-color-purple-100<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token property">--sl-color-primary-200</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--sl-color-purple-200<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token property">--sl-color-primary-300</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--sl-color-purple-300<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token property">--sl-color-primary-400</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--sl-color-purple-400<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token property">--sl-color-primary-500</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--sl-color-purple-500<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token property">--sl-color-primary-600</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--sl-color-purple-600<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token property">--sl-color-primary-700</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--sl-color-purple-700<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token property">--sl-color-primary-800</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--sl-color-purple-800<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token property">--sl-color-primary-900</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--sl-color-purple-900<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token property">--sl-color-primary-950</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--sl-color-purple-950<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code><sl-copy-button class="copy-code-button" from="code-block-35"></sl-copy-button></pre>
<p>
Many design tokens are described further along in this documentation. For a complete list, refer to
<code>src/themes/light.css</code> in the projects
<a
href="https://github.com/onsonr/nebula/blob/current/src/themes/light.css"
class="external-link"
rel="noopener noreferrer"
target="_blank"
>source code</a
>.
</p>
<h2 id="css-parts" class="anchor-heading">
CSS Parts<a href="#css-parts" aria-label='Direct link to "CSS Parts"'></a>
</h2>
<p>
Whereas design tokens offer a high-level way to customize the library, CSS parts offer a low-level way to
customize individual components. Again, this is done with pure CSS — no preprocessor required.
</p>
<p>
Nebula components use a
<a
href="https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM"
class="external-link"
rel="noopener noreferrer"
target="_blank"
>shadow DOM</a
>
to encapsulate their styles and behaviors. As a result, you cant simply target their internals with the
usual CSS selectors. Instead, components expose “parts” that can be targeted with the
<a
href="https://developer.mozilla.org/en-US/docs/Web/CSS/::part"
class="external-link"
rel="noopener noreferrer"
target="_blank"
>CSS part selector</a
>, or <code>::part()</code>.
</p>
<p>Heres an example that modifies buttons with the <code>tomato-button</code> class.</p>
<div class="code-preview">
<div class="code-preview__preview">
<sl-button class="tomato-button"> Tomato Button </sl-button>
<style>
.tomato-button::part(base) {
background: var(--sl-color-neutral-0);
border: solid 1px tomato;
}
.tomato-button::part(base):hover {
background: rgba(255, 99, 71, 0.1);
}
.tomato-button::part(base):active {
background: rgba(255, 99, 71, 0.2);
}
.tomato-button::part(base):focus-visible {
box-shadow: 0 0 0 3px rgba(255, 99, 71, 0.33);
}
.tomato-button::part(label) {
color: tomato;
}
</style>
<div class="code-preview__resizer">
<sl-icon name="grip-vertical"></sl-icon>
</div>
</div>
<div class="code-preview__source-group" id="code-preview-source-group-2">
<div class="code-preview__source code-preview__source--html">
<pre><code class="language-html" id="code-block-36"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>sl-button</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>tomato-button<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span> Tomato Button <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>sl-button</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
<span class="token selector">.tomato-button::part(base)</span> <span class="token punctuation">{</span>
<span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--sl-color-neutral-0<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token property">border</span><span class="token punctuation">:</span> solid 1px tomato<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector">.tomato-button::part(base):hover</span> <span class="token punctuation">{</span>
<span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span>255<span class="token punctuation">,</span> 99<span class="token punctuation">,</span> 71<span class="token punctuation">,</span> 0.1<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector">.tomato-button::part(base):active</span> <span class="token punctuation">{</span>
<span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">rgba</span><span class="token punctuation">(</span>255<span class="token punctuation">,</span> 99<span class="token punctuation">,</span> 71<span class="token punctuation">,</span> 0.2<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector">.tomato-button::part(base):focus-visible</span> <span class="token punctuation">{</span>
<span class="token property">box-shadow</span><span class="token punctuation">:</span> 0 0 0 3px <span class="token function">rgba</span><span class="token punctuation">(</span>255<span class="token punctuation">,</span> 99<span class="token punctuation">,</span> 71<span class="token punctuation">,</span> 0.33<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector">.tomato-button::part(label)</span> <span class="token punctuation">{</span>
<span class="token property">color</span><span class="token punctuation">:</span> tomato<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code><sl-copy-button class="copy-code-button" from="code-block-36"></sl-copy-button></pre>
</div>
</div>
<div class="code-preview__buttons">
<button
type="button"
class="code-preview__button code-preview__toggle"
aria-expanded="false"
aria-controls="code-preview-source-group-2"
>
Source
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="6 9 12 15 18 9"></polyline>
</svg>
</button>
<button type="button" class="code-preview__button code-preview__button--codepen" title="Edit on CodePen">
<svg
width="138"
height="26"
viewBox="0 0 138 26"
fill="none"
stroke="currentColor"
stroke-width="2.3"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
d="M80 6h-9v14h9 M114 6h-9 v14h9 M111 13h-6 M77 13h-6 M122 20V6l11 14V6 M22 16.7L33 24l11-7.3V9.3L33 2L22 9.3V16.7z M44 16.7L33 9.3l-11 7.4 M22 9.3l11 7.3 l11-7.3 M33 2v7.3 M33 16.7V24 M88 14h6c2.2 0 4-1.8 4-4s-1.8-4-4-4h-6v14 M15 8c-1.3-1.3-3-2-5-2c-4 0-7 3-7 7s3 7 7 7 c2 0 3.7-0.8 5-2 M64 13c0 4-3 7-7 7h-5V6h5C61 6 64 9 64 13z"
></path>
</svg>
</button>
</div>
</div>
<p>
At first glance, this approach might seem a bit verbose or even limiting, but it comes with a few important
advantages:
</p>
<ul>
<li>
<p>
Customizations can be made to components with explicit selectors, such as <code>::part(icon)</code>,
rather than implicit selectors, such as <code>.button &gt; div &gt; span + .icon</code>, that are much
more fragile.
</p>
</li>
<li>
<p>
The internal structure of a component will likely change as it evolves. By exposing CSS parts through an
API, the internals can be reworked without fear of breaking customizations as long as its parts remain
intact.
</p>
</li>
<li>
<p>
It encourages us to think more about how components are designed and how customizations should be
allowed before users can take advantage of them. Once we opt a part into the components API, its
guaranteed to be supported and cant be removed until a major version of the library is released.
</p>
</li>
</ul>
<p>
Most (but not all) components expose parts. You can find them in each components API documentation under
the “CSS Parts” section.
</p>
<h2 id="custom-properties" class="anchor-heading">
Custom Properties<a href="#custom-properties" aria-label='Direct link to "Custom Properties"'></a>
</h2>
<p>
For convenience, some components expose CSS custom properties you can override. These are not design tokens,
nor do they have the same <code>--sl-</code> prefix since theyre scoped to a component.
</p>
<p>You can set custom properties on a component in your stylesheet.</p>
<pre><code class="language-css" id="code-block-37"><span class="token selector">sl-avatar</span> <span class="token punctuation">{</span>
<span class="token property">--size</span><span class="token punctuation">:</span> 6rem<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code><sl-copy-button class="copy-code-button" from="code-block-37"></sl-copy-button></pre>
<p>This will also work if you need to target a subset of components with a specific class.</p>
<pre><code class="language-css" id="code-block-38"><span class="token selector">sl-avatar.your-class</span> <span class="token punctuation">{</span>
<span class="token property">--size</span><span class="token punctuation">:</span> 6rem<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code><sl-copy-button class="copy-code-button" from="code-block-38"></sl-copy-button></pre>
<p>Alternatively, you can set them inline directly on the element.</p>
<pre><code class="language-html" id="code-block-39"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>sl-avatar</span> <span class="token special-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value css language-css"><span class="token property">--size</span><span class="token punctuation">:</span> 6rem<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>sl-avatar</span><span class="token punctuation">&gt;</span></span>
</code><sl-copy-button class="copy-code-button" from="code-block-39"></sl-copy-button></pre>
<p>
Not all components expose CSS custom properties. For those that do, they can be found in the components API
documentation.
</p>
<h2 id="animations" class="anchor-heading">
Animations<a href="#animations" aria-label='Direct link to "Animations"'></a>
</h2>
<p>
Some components use animation, such as when a dialog is shown or hidden. Animations are performed using the
<a
href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API"
class="external-link"
rel="noopener noreferrer"
target="_blank"
>Web Animations API</a
>
rather than CSS. However, you can still customize them through Nebulas animation registry. If a component
has customizable animations, theyll be listed in the “Animation” section of its documentation.
</p>
<p>
To customize a default animation, use the <code>setDefaultAnimation()</code> method. The function accepts an
animation name (found in the components docs) and an object with <code>keyframes</code>, and
<code>options</code> or <code>null</code> to disable the animation.
</p>
<p>This example will make all dialogs use a custom show animation.</p>
<pre><code class="language-js" id="code-block-40"><span class="token keyword">import</span> <span class="token punctuation">{</span> setDefaultAnimation <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@onsonr/nebula/dist/utilities/animation-registry.js'</span><span class="token punctuation">;</span>
<span class="token comment">// Change the default animation for all dialogs</span>
<span class="token function">setDefaultAnimation</span><span class="token punctuation">(</span><span class="token string">'dialog.show'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
<span class="token literal-property property">keyframes</span><span class="token operator">:</span> <span class="token punctuation">[</span>
<span class="token punctuation">{</span> <span class="token literal-property property">transform</span><span class="token operator">:</span> <span class="token string">'rotate(-10deg) scale(0.5)'</span><span class="token punctuation">,</span> <span class="token literal-property property">opacity</span><span class="token operator">:</span> <span class="token string">'0'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span> <span class="token literal-property property">transform</span><span class="token operator">:</span> <span class="token string">'rotate(0deg) scale(1)'</span><span class="token punctuation">,</span> <span class="token literal-property property">opacity</span><span class="token operator">:</span> <span class="token string">'1'</span> <span class="token punctuation">}</span>
<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token literal-property property">options</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token literal-property property">duration</span><span class="token operator">:</span> <span class="token number">500</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code><sl-copy-button class="copy-code-button" from="code-block-40"></sl-copy-button></pre>
<div role="alert" class="callout callout--tip">
<p>
To support RTL languages in your animation, you can pass an additional property called
<code>rtlKeyframes</code>. This property shares the same type as <code>keyframes</code> and will be
automatically used when the components directionality is RTL. If <code>rtlKeyframes</code> is not
provided, <code>keyframes</code> will be used as a fallback.
</p>
</div>
<p>
If you only want to target a single component, use the <code>setAnimation()</code> method instead. This
function accepts an element, an animation name, and an object comprised of animation
<code>keyframes</code> and <code>options</code>.
</p>
<p>In this example, only the target dialog will use a custom show animation.</p>
<pre><code class="language-js" id="code-block-41"><span class="token keyword">import</span> <span class="token punctuation">{</span> setAnimation <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@onsonr/nebula/dist/utilities/animation-registry.js'</span><span class="token punctuation">;</span>
<span class="token comment">// Change the animation for a single dialog</span>
<span class="token keyword">const</span> dialog <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'#my-dialog'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">setAnimation</span><span class="token punctuation">(</span>dialog<span class="token punctuation">,</span> <span class="token string">'dialog.show'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
<span class="token literal-property property">keyframes</span><span class="token operator">:</span> <span class="token punctuation">[</span>
<span class="token punctuation">{</span> <span class="token literal-property property">transform</span><span class="token operator">:</span> <span class="token string">'rotate(-10deg) scale(0.5)'</span><span class="token punctuation">,</span> <span class="token literal-property property">opacity</span><span class="token operator">:</span> <span class="token string">'0'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span> <span class="token literal-property property">transform</span><span class="token operator">:</span> <span class="token string">'rotate(0deg) scale(1)'</span><span class="token punctuation">,</span> <span class="token literal-property property">opacity</span><span class="token operator">:</span> <span class="token string">'1'</span> <span class="token punctuation">}</span>
<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token literal-property property">options</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token literal-property property">duration</span><span class="token operator">:</span> <span class="token number">500</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code><sl-copy-button class="copy-code-button" from="code-block-41"></sl-copy-button></pre>
<p>
To learn more about creating Web Animations, refer to the documentation for
<a
href="https://developer.mozilla.org/en-US/docs/Web/API/Element/animate"
class="external-link"
rel="noopener noreferrer"
target="_blank"
><code>Element.animate()</code></a
>.
</p>
<div role="alert" class="callout callout--tip">
<p>
Animations respect the users <code>prefers-reduced-motion</code> setting. When this setting is enabled,
animations will not be played. To disable animations for all users, pass in <code>null</code> instead of a
keyframes/options object.
</p>
</div>
</div>
</article>
</main>
</body>
</html>