π¨ Styling Components
Keep your componentsβ styles self-contained while supporting shared design tokens. UIElement does not enforce a specific styling method, but we recommend techniques that help balance encapsulation, reusability, and maintainability.
Design Principles
UIElement is focused on state management and reactivity, not styling. However, to ensure consistent, maintainable, and reusable styles, we recommend techniques that scope component styles properly while allowing shared design tokens (e.g., spacing, font sizes, colors, layout grids).
- β Each component brings along its own specific styles.
- β Component styles should be scoped or encapsulated so they don't leak out.
- β Allow customizations via CSS custom properties or pre-defined classes.
Parent components may apply styles to the wrapper element of known sub-components for layout purposes. But avoid styling inner elements of sub-components directly. This would tightly couple the styles of the outer and inner components.
Scope Styles to Custom Element
Use the custom element name to scope component styles if you control the page and the components within. This protects against component styles leaking out, while still allowing to use the CSS cascade. No need for Shadow DOM, no duplicate style rules.
my-component {
& button {
/* Button style rules */
}
/* More selectors for inner elements */
}
Advantages of Custom Element Names
- β By definition unique within the document with a descriptive name.
- β Low specificity, making it easy to override when you need to with a single class.
When to use
β
Best when you control the page and need styles to cascade naturally.
β Avoid if you expect style clashes from third-party styles.
Encapsulate Styles with Shadow DOM
Use Shadow DOM to encapsulate styles if your component is going to be used in a pages where you don't control the styles. This way you make sure page styles don't leak in and component styles don't leak out.
<my-component>
<template shadowrootmode="open">
<style>
button {
/* Button style rules */
}
/* More selectors for inner elements */
</style>
<!-- Inner elements -->
</template>
</my-component>
When to use
β
Best when your component is used in environments where you donβt control styles.
β Avoid if you need global styles to apply inside the component.
Shared Design Tokens with CSS Custom Properties
Web Components canβt inherit global styles inside Shadow DOM, but CSS custom properties allow components to remain flexible and themeable.
Defining Design Tokens
Set global tokens in a stylesheet:
:root {
--button-bg: #007bff;
--button-text: #fff;
--spacing: 1rem;
}
Using Tokens in a Component
my-component {
padding: var(--spacing);
& button {
background: var(--button-bg);
color: var(--button-text);
}
}
Advantages of CSS Custom Properties
- β Supports theming β Users can override styles globally.
- β Works inside Shadow DOM β Unlike normal CSS, custom properties are inherited inside the shadow tree.
Defined Variants with Classes
Use classes if your components can appear in a limited set of specific manifestations. For example, buttons could come in certain sizes and have primary, secondary and tertiary variants.
my-button {
/* Style rules for default (medium-sized, secondary) buttons */
&.small {
/* Style rules for small buttons */
}
&.large {
/* Style rules for large buttons */
}
&.primary {
/* Style rules for primary buttons */
}
&.tertiary {
/* Style rules for tertiary buttons */
}
}
CSS-only Components
Just because UIElement is a JavaScript library doesn't mean you have to use JavaScript in every component. It's perfectly fine to use custom elements just for styling purposes.
Here's the example of the <callout-box>
we're using in this documentation:
Source Code
Loading...
Next Steps
Now that you know how to style components, explore:
- Data Flow β Learn about inter-component communication.
- Examples & Recipes β See styling techniques in action.