Styling components using CSS, CSS pre and post-processors as well as working with web components.
Aurelia 2 simplifies the process of styling components, supporting a variety of CSS flavors and encapsulation methods. Whether you prefer raw CSS, PostCSS, SASS, or Stylus, Aurelia 2 streamlines their integration into your components. Ultimately, all styles compile into standard CSS that browsers can interpret.
Aurelia 2 automatically imports styles for custom elements based on file naming conventions. For instance, if you have a custom element named my-component
, Aurelia 2 looks for a corresponding stylesheet named my-component.css
.
Consider the following file structure:
my-component.ts
: The TypeScript file defining the MyComponent
class.
my-component.css
: The stylesheet containing styles for MyComponent
.
my-component.html
: The HTML template for MyComponent
.
Aurelia 2's convention-based approach eliminates the need to explicitly import the CSS file. When you run your application, Aurelia 2 automatically detects and applies the styles.
When MyComponent
is used in the application, the associated styles are automatically applied, giving the paragraph text a blue color and a light grey background with padding and rounded corners.
The Shadow DOM API, part of the Web Components standard, provides encapsulation by hiding the component's internal DOM and styles from the rest of the application. Aurelia 2 offers several options for working with Shadow DOM:
Global Shadow DOM: By default, encapsulates all components in your application.
Configured Shadow DOM: Use the useShadowDOM
decorator to opt-in per component.
Global opt-out Shadow DOM: Enable Shadow DOM globally but disable it for specific components.
If your application uses CSS frameworks like Bootstrap, which rely on global styles, consider how Shadow DOM encapsulation may affect their behavior. The following sections guide managing global and shared styles.
To enable Shadow DOM after the initial setup, configure it in the main.ts
file:
The StyleConfiguration
class from Aurelia allows you to specify how styles are applied, including options for Shadow DOM.
When using Webpack, ensure the following rule is included in the Webpack configuration:
This rule ensures that HTML files within your src
directory are processed correctly to work with Shadow DOM.
In the Shadow DOM, styles are scoped to their components and don't leak to the global scope. To apply global styles across all components, use the sharedStyles
property in the Shadow DOM configuration.
The sharedStyles
property accepts an array, allowing you to include multiple shared stylesheets.
useShadowDOM
The useShadowDOM
decorator, imported from Aurelia, lets you enable Shadow DOM on a per-component basis. Without configuration options, it defaults to open
mode.
You can specify the Shadow DOM mode (open
or closed
) as a configuration option. The open
mode allows JavaScript to access the component's DOM through the shadowRoot
property, while closed
mode restricts this access.
The useShadowDOM
decorator also allows disabling Shadow DOM for a specific component by passing false
.
Shadow DOM introduces special selectors that offer additional styling capabilities. These selectors are part of the CSS Scoping Module specification.
The :host
selector targets the custom element itself, not its children. You can use the :host()
function to apply styles based on the host element's classes or attributes.
In this example, all app-header
elements have a solid border, and those with the active
class have a grey background.
The :host-context
selector styles the custom element based on its context within the document.
Here, app-header
elements will have white text on a dark background inside an element with the dark-mode
class.
When Shadow DOM does not meet your needs, CSS Modules balance style encapsulation and global accessibility. CSS Modules transform class names into unique identifiers, preventing style collisions.
To use CSS Modules, include the following loader configuration in your Webpack setup:
This rule processes CSS files, enabling CSS module functionality.
Define your styles, and reference the class names in your HTML templates. Webpack will handle the conversion to unique class names.
After processing, the title
class may be transformed to a unique identifier like title_1a2b3c
.
CSS Modules support the :global
selector for styling global elements without transformation.
This style will apply globally to elements with the button-primary
class, maintaining the class name without transformation.
Shadow DOM encapsulates a component's styles, preventing them from leaking into the global scope. Aurelia 2 offers granular control over Shadow DOM usage, including global and per-component configuration.
When using Shadow DOM, you can style content passed into slots using the ::slotted()
pseudo-element.
In this example, content assigned to the tab-content
slot will receive padding and a border. At the same time, the encapsulation ensures that these styles don't affect other elements outside the tab-panel
component.
CSS variables can be used within Shadow DOM to create themeable components:
Users of the button-group
component can then define these variables at a higher level to theme the buttons consistently across the application.
Animations can be defined within Shadow DOM to ensure they are scoped to the component:
The slide-in
animation is encapsulated within the animated-banner
component, preventing it from conflicting with any other animations defined in the global scope.
CSS Modules provide a powerful way to locally scope class names, avoiding global conflicts. With Aurelia 2, you can leverage CSS Modules to create maintainable, conflict-free styles.
CSS Modules support composing classes from other modules, promoting reusability.
In this example, primaryButton
composes the baseButton
styles, adding its own background and text color. CSS Modules ensures that these class names are unique to avoid styling conflicts.
CSS Modules can also facilitate theming by exporting and importing variables.
By defining and exporting theme variables in theme.css
, they can be imported and used in other CSS Modules to ensure consistent theming across the application.
For more guidance on class and style bindings in Aurelia applications, please take a look at the [CSS classes and styling section](.. templates/class-and-style-bindings.md). This section covers strategies for dynamically working with classes and inline styles.