You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte/site/content/guide/03-scoped-styles.md

118 lines
3.2 KiB

---
title: Scoped styles
---
One of Svelte's key tenets is that components should be self-contained and reusable in different contexts. Because of that, it has a mechanism for *scoping* your CSS, so that you don't accidentally clobber other selectors on the page.
### Adding styles
Your component template can have a `<style>` tag, like so:
```html
<!--{ title: 'Scoped styles' }-->
<style>
.foo {
color: red;
font-size: 2em;
font-family: 'Comic Sans MS';
}
</style>
<div class="foo">
Big red Comic Sans
</div>
```
### How it works
Open the example above in the REPL and inspect the element to see what has happened Svelte has added a `svelte-[uniqueid]` class to the element, and transformed the CSS selector accordingly. Since no other element on the page can share that selector, anything else on the page with `class="foo"` will be unaffected by our styles.
This is vastly simpler than achieving the same effect via [Shadow DOM](http://caniuse.com/#search=shadow%20dom) and works everywhere without polyfills.
> Svelte will add a `<style>` tag to the page containing your scoped styles. Dynamically adding styles may be impossible if your site has a [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP). If that's the case, you can use scoped styles by [server-rendering your CSS](guide#rendering-css) and using the `css: false` compiler option (or `--no-css` with the CLI).
### Cascading rules
Styles will *only* apply to the current component, unless you opt in to cascading with the `:global(...)` modifier:
<!-- TODO `cascade: false` in the REPL -->
```html
<!-- { repl: false } -->
<script>
import Widget from './Widget.html';
</script>
<style>
p {
/* this block will be disregarded, since
there are no <p> elements here */
color: red;
}
div :global(p) {
/* this block will be applied to any <p> elements
inside the <div>, i.e. in <Widget> */
font-weight: bold;
}
</style>
<div>
<Widget/>
</div>
```
> Scoped styles are *not* dynamic  they are shared between all instances of a component. In other words you can't use `{tags}` inside your CSS.
### Unused style removal
Svelte will identify and remove styles that are not being used in your app. It will also emit a warning so that you can remove them from the source.
For rules *not* to be removed, they must apply to the component's markup. As far as Svelte is concerned `.bold` is unused in the following code and should be removed:
```html
<!-- { repl: false } -->
<div>
<p bind:this={paragraph}>this text is not bold</p>
</div>
<style>
.bold {
color: bold;
}
</style>
<script>
import { onMount } from 'svelte';
let paragraph;
onMount(() => {
paragraph.classList.add('bold');
});
</script>
```
Instead of manually manipulating the DOM, you should always use the `class` attribute (or the [class directive](https://svelte.technology/guide#classes)):
```html
<!-- { repl: false } -->
<div>
<p class:bold={bold}>this text is bold</p>
</div>
```
If that's impossible for some reason, you can use `:global(...)`:
```html
<!-- { repl: false } -->
<style>
div :global(.bold) {
color: bold;
}
</style>
```
The same applies to the contents of `{@html ...}` tags.