Status: IMPLEMENTED
Champion: Unknown
Revision: latest
RFC created: 1970/01/01
Last updated: unknown
This RFC has been merged
# CSS Definition for a LWC Component
# Template Declaration
<template>
<a href={url}>{name}</a>
<p>{tagline}</p>
</template>
# CSS Declaration
a { color: red; }
p { margin: 10px 0; }
The CSS will be compiled, and a prefix will be added on every rule to guarantee that specificity of the rule only applies to the body of the host element (the custom element that represents the component).
# Styling the host element
The :host
allows you to style the element hosting the component:
:host {
opacity: 0.4;
transition: opacity 420ms ease-in-out;
}
:host(:hover) {
opacity: 1;
}
:host(:active) {
position: relative;
top: 3px;
left: 3px;
}
The CSS will be compiled, and a prefix will replace :host
to guarantee that specificity of the rule only applies to the host element (the custom element that represents the component).
One gotcha is that rules in the parent page have higher specificity than :host
rules defined in CSS file, but lower specificity than a style
attribute defined on the host element.
# Proposal 1
x-foo.html
<template>
<div>
<p>
<x-bar>
<div>
</template>
<style>
div { border-color: blue; }
</style>
x-bar.html
<template>
<div>
<slot></slot>
</div>
</template>
<style>
div { border-color: gray; }
</style>
<link href="some.css">
some.css
:host { border-color: yellow; }
Assuming that there is a main.js
that creates the instance of x-foo
, the output markup will be:
<x-foo x="maintpl">
<div x="footpl">
<p x="footpl">
<x-bar x="footpl">
<div x="bartpl">
<slot x="bartpl">
<div x="footpl">
and the styles added to the document will be:
/* from foo component */
div[x="footpl"] { color: blue; }
/* from bar component */
x-bar, [is="x-bar"] { border-color: yellow; }
div[x="bartpl"] { color: blue; }
This proposal relies on the fact that a unique key can be produced (it is a function of the name of the component and the name of the template), and this key can be added to the associated css and added as an attribute to each element in the template, and used at the same time as a matching prefix on every css rule.
The host
rule is special, and it is not really bound to the template, but to the host. Rendering one template vs another should not imply changes in the style of the host element, that will be a problem.
# Implementation Details
/deep/
and::shadow
are now deprecated, and should not be supported in our css compiler.::slotted
should probably be banned for now, we can add it later.:host
should be supported in our first version (defined at the component level):host-context
might be very tricky to implement,
# Examples
# :host
:host {
background: red;
}
:host(.fancy) {
background: purple;
}
In the example above, the host will receive background color red, but if the host matches the selector .fancy
, it will receive background color purple. This also helps with cases where the component is used for different tag names or via is
attribute.
From what I can infer from the spec (https://drafts.csswg.org/css-scoping/#host-selector), it only supports a simple selector in the parenthesis.
# :host-context
Selects a shadow host based on a matching parent element.
:host-context(.x-foo) {
background: red;
}
In the example above, the host will receive background color red only if the host element is inserted as a direct child of a <x-foo>
tag.
From what I can infer from the spec (https://drafts.csswg.org/css-scoping/#host-selector), it only supports a simple selector in the parenthesis.
# Important Notice
Implementations should not rely on or use the selectors generated by the Lightning Web Components compiler. This is an implementation detail of Lightning Web Components and relying on it in user-land can potentially break your code in future releases.