Resetting styles inside Lit-Element Web Components
Published: 2021-01-30 23:46:18

<span>Photo by <a href="https://unsplash.com/@mab_studio?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Michele Blackwell</a> on <a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span>

So you are working on your Web Components and soon enough you realize they are really good at encapsulating stuff. That's the goal. Check out this Web Component:

{% codepen https://codepen.io/jdvivar/pen/ZEBYbYM %}

There are 2 `p` tags. On the one hand, we have one declared entirely inside the Web Component, the one with `inner content`:
```js
...
render() {
  return html`
    <div>
      <p>Inner content</p>
    </div>
    <div>
      <slot></slot>
    </div>
  `
}
...
```
And on the other hand, we have a `p` tag declared as part of the body which is moved in as part of the `slot` functionality of our Web Component:
```html
...
<div>
  <my-element>
    <p>Slotted content</p>
  </my-element>
</div>
...
```
We have a reset rule declared for `p` tags:
```css
p {
  margin: 0;
}
```

As you can see, the `p` tag declared outside gets the style applied and moved in without margins. However the `p` declared inside is "protected" from the page styles and so it gets general treatment: user agent styles. That's why they look different.

## How do we solve this problem?

So far, I think there's only one way to solve it: declaring the reset styles within the Web Component as well. In our Web Component, the `styles` static class getter will looke like so:
```js
static get styles() {
  return css`
    div {
      border: 1px solid red;
    }
    p {
      margin: 0;
    }
  `;
}
```

Here is our updated *pen*:
{% codepen https://codepen.io/jdvivar/pen/WNobQQX %}

Solved, right? Well, it works, but this is far from optimal. Firstly, we should have this reset styles outside the Web Component itself, that way you can share the reset styles amongst other components. Something like this:
```js
...
const resetStyles = () => css`
  p {
    margin: 0;
  }
`
...
static get styles() {
  return [
    resetStyles(),
    css`
      div {
        border: 1px solid red;
      }
    `
  ]
}
...
```

{% codepen https://codepen.io/jdvivar/pen/vYyENGG %}

But secondly and more importantly, as a good rule of thumb in software development: never have the same stuff repeated.

We still have a reset styles stylesheet, let's call it `reset.css`, and an object with the reset styles which is returned by `resetStyles()`. That means we have the reset styles both as a LitElement's css object and as an independent stylesheet.

The cool thing would be to have the reset stylesheet and that's it.

**How do we do that?**

We can process the stylesheet and create a CSS object, just how LitElement understands them. There are many ways to do this, I'll use Rollup for my example.

Let's Rollup! Using a simple config like this:

```js
import litcss from 'rollup-plugin-lit-css'

export default {
  input: 'src/reset.css.js',
  plugins: [
    litcss({ uglify: true })
  ],
  output: {
    file: 'reset.css.lit.js',
    format: 'es'
  }
}
```

Here we're using Rollup's great `rollup-plugin-lit-css` plugin by {% user bennypowers %}

Our `src/reset.css.js` is super simple:
```js
export { default } from '../reset.css'
```

That's it!

Now we can use it in LitElement:
```js
...
import reset from "./reset.css.lit.js";
const resetStyles = () => reset
...
```

We'll need something more advanced than CodePen for this, let's use Glitch and voilá! Now we only have one place where our reset styles are written (`reset.css`). Check it out:

{% glitch resetting-styles-web-components app %}

Remember in this example the file `reset.css.lit.js` has been created by Rollup.

## Minireset.css

A similar approach than the one just explained I used to improve minireset.css in [this PR](https://github.com/jgthms/minireset.css/pull/28) and provide an additional LitElement compatible file other people can use in LitElement Web Components. minireset.css is a great (and very tiny) reset you can use at production sites, which I recommend, check it out:

https://jgthms.com/minireset.css/

Install it on your project:
```sh
npm install --save minireset.css
```

Then in LitElement Web Components where you want to have the styles reset, import them:
```js
import { minireset } from 'minireset.css/minireset.css.lit.js'
```

And then either use them as part of an array CSS result, like so:
```js
static get styles() {
  return [
    minireset,
    ... your other styles
  ]
}
```

or directly in your styles:
```js
static get styles() {
  return css`
    ${minireset}
    
    ... your other styles
  `
}
```

### That's a wrap!

I hope you found this article useful. Questions and feedback are very welcome 🙂