diff --git a/docs/_guide/styles.md b/docs/_guide/styles.md
index 0f19e0d9..d6057cb5 100644
--- a/docs/_guide/styles.md
+++ b/docs/_guide/styles.md
@@ -4,66 +4,317 @@ title: Styles
slug: styles
---
-**This guide applies only if you use the default (shadow DOM) render root.** If you modify your element's render root to render into the main DOM tree instead of a shadow root, these instructions won't apply.
-
-**If you're using the Shady CSS polyfill, be aware that it has some limitations.** See the [Shady CSS README](https://github.com/webcomponents/shadycss/blob/master/README.md#limitations) for more information.
-
{::options toc_levels="1..3" /}
* ToC
{:toc}
-## Use the :host and :host() CSS pseudo-classes
+This page is a guide to the styling options available for LitElement components.
-When styling your custom element, you can use the `:host` and `:host()` CSS pseudo-classes in a `
-
Hello world
+import { LitElement, css, cssLiteral } from 'lit-element';
+
+const mainColor = cssLiteral`red`;
+
+class MyElement extends LitElement {
+ static styles = css`
+ :host {
+ display: block;
+ color: ${mainColor}
+ }
`;
}
```
-{% include project.html folder="docs/style/hostselector" openFile="my-element.js" %}
+### Define styles in a style element {#style-element}
+
+We recommend using static styles to style LitElement components. However, in some cases you may want to evaluate and apply styles per instance, rather than to all instances of a LitElement component. One way to do this is to include inline styles in a `
+ `;
+ }
+}
+```
+
+### Define styles in an external stylesheet {#external-stylesheet}
+
+We strongly recommend static styles, CSS custom properties, or [lit-html's `classMap` or `styleMap` directives](TODO) if you're stying non-host shadow root contents.
+
+However, you can load an external stylesheet into a shadow root with a `` element:
+
+```js
+import {LitElement} from 'lit-element';
+
+class MyElement extends LitElement {
+ render() {
+ return html`
+
+ `;
+ }
+}
+```
+
+This can be a good way to load CSS generated from tools like SASS/LESS.
+
+There are some important caveats though:
+
+* External styles can cause a flash-of-unstyled-content (FOUC) while they load.
+* The URL in the `href` attribute is relative to the _main document_, making this technique mostly useful for application elements where asset URLs are well known, and not for reusable elements published publicly.
+
+### Write CSS styles for a host element and its shadow DOM {#shadow-dom-styles}
+
+In this section:
+
+* [Write CSS styles for a host element](#host-styles).
+* [Write CSS styles for elements in shadow DOM](#shadow-dom-styles).
+* [Write CSS styles for slotted children](#slotted-styles). Light DOM children of your host element can be rendered in shadow DOM via the `slot` element.
+
+#### Write CSS styles for a host element {#host-styles}
+
+An element can apply styles to itself with the `:host` and `:host()` CSS psuedo-classes used inside the element's ShadowRoot. The tern "host" is used because an element is the host of its own shadow root.
+
+* `:host` selects the host element of the shadow root:
+
+ ```css
+ :host {
+ display: block;
+ color: blue;
+ }
+ ```
+
+* `:host(...)` selects the host element, but only if the selector inside the parentheses matches the host element:
+
+ ```css
+ :host([.important]) {
+ color: red;
+ font-weight: bold;
+ }
+ ```
+
+{% include project.html folder="style/hostselector" openFile="my-element.js" %}
Two best practices for working with custom elements are:
-* Set a `:host` display style such as `block` or `inline-block` so that your component's `width` and `height` can be set.
+* Add a `:host` display style (such as `block` or `inline-block`) unless you prefer the default of `inline`.
-* Set a `:host()` display style that respects the `hidden` attribute.
+ Inline elements are sized by their content and cannot have their dimensions set via CSS. They can also cause block element children to overflow its bounds.
+
+ ```css
+ :host {
+ display: block;
+ }
+ ```
+
+* Add a `:host()` display style that respects the `hidden` attribute.
+
+ ```css
+ :host([hidden]) {
+ display: none;
+ }
+ ```
+
+{% include project.html folder="style/bestpracs" openFile="my-element.js" %}
+
+See [Custom Element Best Practices](https://developers.google.com/web/fundamentals/web-components/best-practices) for more information.
+
+#### Write CSS styles for elements in shadow DOM {#shadow-dom-styles}
+
+To style elements in a shadow root, simply use standard CSS selectors.
+
+Since CSS selectors in a shadow root only apply to elements in the shadow root, you don't need to be defensive against accidentally styling other elements in the page. This means you can generally write much simpler selectors, that are easier to reason about, and faster, than without shadow DOM.
+
+Simple selectors, like `*`, tagname, id, and class selectors, are fine in a shadow root because they don't match outside the root:
+
+```css
+* {
+ color: black;
+}
+
+h1 {
+ font-size: 4rem;
+}
+
+#main {
+ padding: 16px;
+}
+
+.important {
+ color: red;
+}
+```
+
+#### Write CSS styles for slotted children {#slotted-styles}
+
+Use the `::slotted()` CSS pseudo-element to select light DOM children that have been included in shadow DOM via the `` element.
+
+* `::slotted(*)` matches all slotted elements.
+
+* `::slotted(p)` matches slotted paragraphs.
+
+* `p ::slotted(*)` matches slotted elements in a paragraph element.
+
+```js
+{% include projects/style/slotted/my-element.js %}
+```
+
+{% include project.html folder="style/slotted" openFile="my-element.js" %}
+
+## Styling options for component consumers {#styling-for-consumers}
+
+When you use a LitElement component, you can set styles from the main document by using its custom element tag as a selector. For example:
+
+_index.html_
```html
+...
+
```
-{% include project.html folder="docs/style/bestpracs" openFile="my-element.js" %}
+
-See [Custom Element Best Practices](https://developers.google.com/web/fundamentals/web-components/best-practices) for more information.
+An element type selector has higher specificity than the `:host` pseudo-class selector.
+
+Styles set for a host element from outside its shadow DOM will override styles set with the `:host` or `:host()` pseudo-class selectors inside shadow DOM. See Inheritance.
-### Style shadow DOM children via properties inherited via :host
+
-Child elements in your template will inherit CSS properties you assign to your host via the `:host` CSS pseudo-class:
+## Theming
+
+This section describes how to use CSS inheritance and custom CSS properties to:
+
+* Create easily stylable LitElement components.
+* Create a style theme that can easily be applied to imported LitElement components.
+
+### CSS Inheritance and shadow DOM {#inheritance}
+
+[Inherited CSS properties](https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance) like `color`, `font-family`, and all CSS custom properties (`--*`) inherit through shadow root boundaries.
+
+This means that by default an element will share some important styles from its outside context.
+
+Component authors can take advantage of this to style all of a shadow root's contents by setting inherited properties on the host with the `:host` CSS pseudo-class:
_my-element.js_
@@ -83,27 +334,22 @@ render() {
}
```
-{% include project.html folder="docs/style/inherited" openFile="my-element.js" %}
+{% include project.html folder="style/inherited" openFile="my-element.js" %}
-If your host element itself inherits properties from another element, the host's shadow DOM children will inherit those properties in turn:
+If a host element itself inherits properties from another element, the host's shadow DOM children will inherit those properties in turn:
```html
- ...
-
Will use Roboto font
+
+ Will use Roboto font
+
```
-{% include project.html folder="docs/style/inherited2" openFile="my-element.js" %}
+{% include project.html folder="style/inherited2" openFile="my-element.js" %}
-## Style the host from the main document
-
-You can also style the host from outside its own template.
-
-### Use the custom element tag as a selector
-
-You can set styles for the host from the main document by using its custom element tag as a selector. For example:
+A LitElement component can be styled by using its custom element tag as a selector. For example:
_index.html_
@@ -119,12 +365,15 @@ _index.html_
```
-**The :host CSS pseudo-class has higher specificity than the element's type selector.** Styles set for your host with the `:host` pseudo-class from inside its own template will override styles set in the main document. For example:
+An element type selector has higher specificity than the `:host` pseudo-class selector.
+
+Styles set for a host element from outside its shadow DOM will override styles set with the `:host` or `:host()` pseudo-class selectors inside shadow DOM. For example:
_index.html_
```html
```
-### Use custom properties
+### Custom CSS Properties {#css-properties}
-Custom properties inherit down the DOM tree. You can use this to let your users apply styles and themes to your elements.
+Custom properties inherit down the DOM tree, and through shadow root boundaries. You can use this to let your users apply styles and themes to your elements.
For example, the following element sets its background color to a CSS variable that uses the value of the custom property `--myBackground` if it is available, and uses `yellow` otherwise:
@@ -187,105 +436,25 @@ If the user has an existing app theme, they can easily apply their theme propert
```
```js
-{% include projects/docs/style/customproperties/my-element.js %}
+{% include projects/style/customproperties/my-element.js %}
```
-{% include project.html folder="docs/style/customproperties" openFile="my-element.js" %}
+{% include project.html folder="style/customproperties" openFile="my-element.js" %}
See [CSS Custom Properties on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/--*) for more information.
-## Select slotted elements with the ::slotted() CSS pseudo-element
-
-Use the `::slotted()` CSS pseudo-element to select light DOM elements that have been included in shadow DOM via the `` element.
-
-* `::slotted(*)` matches all slotted elements.
-
-* `::slotted(p)` matches slotted paragraphs.
-
-* `p ::slotted(*)` matches slotted elements in a paragraph element.
-
-```js
-{% include projects/docs/style/slotted/my-element.js %}
-```
-
-{% include project.html folder="docs/style/slotted" openFile="my-element.js" %}
-
-## Use JavaScript expressions in LitElement style blocks
-
-You can include style information in a JavaScript expression inside a LitElement template:
-
-```js
-render() {
- return html`
-
-
hi world
- `;
-}
-
-get myStyles() {
- return html`p { color: red }`;
-}
-```
-
-{% include project.html folder="docs/style/expressions" openFile="my-element.js" %}
-
-## Example: A small theme
+### A simple example theme {#example-theme}
_index.html_
```html
-
-...
-
+{% include projects/style/theming/index.html %}
```
_my-element.js_
```js
-render() {
- return html`
-
-
-
- ${this.menuItems.map(item => html`
${item}
`)}
-
- `;
-}
-```
-
-_my-styles.js_
-
-```js
-export const navStyles = html`
- ul {
- list-style-type: none;
- margin: 0;
- padding: 0;
- }
- .navigation {
- display: flex;
- flex-direction: row;
- }
- .item {
- padding: 8px;
- }
-`;
+{% include projects/style/theming/my-element.js %}
```
-{% include project.html folder="docs/style/smalltheme" openFile="my-element.js" %}
+{% include project.html folder="style/theming" openFile="theme.css" %}
diff --git a/docs/_guide/templates.md b/docs/_guide/templates.md
index c400eb48..296a0f43 100644
--- a/docs/_guide/templates.md
+++ b/docs/_guide/templates.md
@@ -374,7 +374,7 @@ class MyPage extends LitElement {
{% include project.html folder="docs/templates/composeimports" openFile="my-page.js" %}
-## Specify the render root
+## Specify the render root {#renderroot}
The node into which your component's template will render is called its **render root**.
diff --git a/docs/_includes/projects/docs/style/before/my-element.js b/docs/_includes/projects/docs/style/before/my-element.js
deleted file mode 100644
index a83e3df4..00000000
--- a/docs/_includes/projects/docs/style/before/my-element.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Try LitElement https://lit-element.polymer-project.org/try
- * Starting code for 6. Style
- */
-
-import { LitElement, html } from 'lit-element';
-
-class MyElement extends LitElement {
- static get properties() {
- return {
- message: { type: String },
- myArray: { type: Array },
- myBool: { type: Boolean }
- };
- }
-
- constructor() {
- super();
- this.message='Hello world! From my-element';
- this.myArray = ['an','array','of','test','data'];
- this.myBool = true;
- }
-
- render() {
- return html`
-
-
-
-
-