Skip to main content
Version: 2.x

Style

When developing frontend applications, it is crucial to create a sense of stylistic unity and cohesion that gives users a better, smoother experience. Achieving this goal can be tricky in the micro-frontend world, where all the moving parts are not built together and often cannot rely on the same stylistic definitions.

micro-lc helps you make sure that all orchestrated pieces feel alike supporting various means of style declaration and offering some out-of-the-box utilities.

Styling applications

When styling micro-lc applications, one key factor to consider is whether Shadow DOM is enabled or not.

If Shadow DOM is enabled, the application layout is put inside of micro-lc shadow root, while the content is not, meaning that their respective styles are encapsulated and cannot affect one another. Furthermore, "global" document styles (e.g., style tags in document head) do not influence layout – or any other node in a shadow root, even if it is placed in content –.

On the other hand, if micro-lc Shadow DOM is disabled, both layout and content are placed in regular DOM and are always affected by the same styling rules.

caution

Although partially supported in micro-lc v1, v2 does operate a complete separation of concerns between layout, routing, and UI components. dark mode features are completely delegated to layout and micro-lc API application interactions.

Sample micro-lc components do not support dark mode

Style declarations

style attribute

The style attribute is available to all HTML elements and enable fine-grained, encapsulating styling. It can be used when composing resources declaring it alongside other attributes.

micro-lc.config.yaml
layout:
content: |
<div style="color: red;">This will be red</div>

applications:
home:
integrationMode: compose
route: ./
config:
content:
- tag: div
attributes:
style: "color: orange;"
content: This will be orange

Since it affects only the element to which it belongs and its children, the style attribute works the same with or without Shadow DOM enabled.

Style information elements

The <style> HTML element can be used to style a document without recurring to external sources.

If a <style> tag is placed outside a shadow-root, it effects all the elements rendered in the regular DOM. If it is places inside a shadow-root, it effects only the elements in the same shadow-root. <style> tags can be either declared in the index.html or constructed when composing components.

<!doctype html>
<html lang="en">
<head>
<title>Style information elements</title>

<style>
div {
background: red;
}
</style>

<script async type="module" src="https://cdn.jsdelivr.net/npm/@micro-lc/orchestrator@latest/dist/micro-lc.production.js"></script>
</head>
<body>
<micro-lc config-src="./config.yaml"></micro-lc>
</body>
</html>

External stylesheets

External stylesheets are referenced through <link> HTML elements. They behave the same way as style information elements: they effect only elements in the same DOM and can be declared in the index.html or constructed when composing components.

<!doctype html>
<html lang="en">
<head>
<title>Style information elements</title>

<link rel="stylesheet" href="./my-stylesheet-1.css">

<script async type="module" src="https://cdn.jsdelivr.net/npm/@micro-lc/orchestrator@latest/dist/micro-lc.production.js"></script>
</head>
<body>
<micro-lc config-src="./config.yaml"></micro-lc>
</body>
</html>

Style injection

micro-lc API provides to a way to inject style at runtime with the setStyle method, implementing the following interface:

type SetStyle = (styles: CSSConfig) => void

interface CSSConfig {
global?: Record<string, string | number>
nodes?: Record<string, Record<string, string | number>>
}

Global style

Global style is injected in the uppermost selector, which is :host if micro-lc is in Shadow DOM mode and :root (which in most cases is head) if it is not. This behaviour is useful to set global CSS variables that can be used to enforce a consistent theme thought the whole application.

For example, after an application or a component has made this call:

microlcApi.getExtensions().css.setStyle({
global: {
'--my-application-color': 'red'
}
})

each node parented by micro-lc can use var(--my-application-color) to access the global variable in its own CSS, whether it is in a shadow-root or not.

Nodes styling

With the node property of setStyle argument, specific CSS selectors can be constructed and injected in DOM. These selectors are effected by Shadow DOM, meaning they apply only on elements in the same DOM (just like style information elements).

For example, after an application or a component has made this call:

microlcApi.getExtensions().css.setStyle({
nodes: {
p: {
color: 'red'
}
}
})

all <p> elements in the same DOM of the call will be red.

Dark mode

micro-lc is agnostic in terms of dark-mode support, meaning that since it controls only page layout, any kind of dark-mode support must be enabled via web-components composing the layout and parcels/compose applications. Notice that the iframe integration mode will not be able to support any kind of style injection due its complete sandboxing and encapsulation.

A good reference for implementing dark mode in your components can be found with the ionic framework:

We briefly remind here that UA compatibility can be ensured by using meta tags in index.html of your micro-lc orchestrated application like:

<meta name="color-scheme" content="dark light" />

this is recommended by HTML specification and has fairly good browser support.

In order to use OS-provided color scheme preferences, it can be helpful the media query construct

@media (prefers-color-scheme: light) {
body {
--text-color: #eee;
--bkg-color: #121212;
}
}

which works inside web-components: even within their shadow-dom by evaluating

window.matchMedia('(prefers-color-scheme: light)')

which has fairly good browser support.

In order to build theme switch buttons, we recommend using micro-lc api by, for instance, setting CSS variables when using webcomponents with shadow-dom or CSS classes for the <body> tag or attribute of html, which though will not work inside a shadow-dom of a web-component.