Web Components, estilizando seus componentes (parte 4)
Tags: javascript, webcomponents, css, frontend
Published: 2021-04-18 21:05:34

Essa é a quarta parte da série de tutoriais sobre Web Components, não deixe de ver a [primeira](https://dev.to/gabrieljm/web-components-o-que-sao-e-como-criar-parte-1-ale), [segunda](https://dev.to/gabrieljm/web-components-atributos-e-metodos-de-reacao-parte-2-g6h) e principalmente a [terceira](https://dev.to/gabrieljm/web-components-o-que-e-shadowdom-parte-3-oba) partes. Neste tutorial irei falar sobre CSS ao se usar Web Components, o que tem de coisa nova, como podemos ter uma base de estilo que não sofra muito pelo encapsulamento dos componentes, entre outros detalhes.

# Recapitulando

Lembre lá nas primeiras partes em que nós criamos componentes que não possuíam Shadow DOM. Então, a estilização deles é bem simples, só de referenciar a tag ou adiciona-la uma classe CSS podemos estilizar como um outro elemento qualquer. É bom relembrar esse detalhe porque nessa parte iremos nos focar mais nos elementos que possuem um Shadow DOM. Com isso em mente lembre também que os elementos com Shadow DOM possuem CSS com escopo.

# Vale ressaltar

Um detalhe a se falar em relação aos elementos com estilização interna é que existem alguns parâmetros de estilo que são herdados pelos elementos, mesmo que dentro de um Shadow DOM. São parâmetros geralmente relacionados a tipografia como: `font-family`, `font-size`, `font-style`, `color`, `text-align`, `text-decoration`, entre outros... Vale lembrar que esse detalhe que acabei de mencionar foi algo que reparei utilizando os Web Components, e graças a isso podem ter outros tipos de parâmetros que podem ser herdados pelos elementos mesmo dentro de um Shadow DOM, então fique atento.

# Estilizando o host

Quando criamos um Web Component, o elemento em que estamos declarando é conhecido como `host` (hospedeiro), ou seja, o elemento que hospeda o `shadow root` (a raiz do Shadow DOM) que criamos. E esse elemento é como outro já nativo do HTML, ou seja, ele pode ser estilizado também, contudo não é tão simples de se estilizar esse elemento quanto só de por seu nome, principalmente pelo fato de que o nome do elemento só será definido posteriormente quando usarmos a API de `customElements`. Para ter acesso a esse elemento é necessário usar o seletor `:host`, e usá-lo com parênteses para selecionar outros detalhes, por exemplo:

```css
:host {} /* Estiliza o host */
:host(.blue) {} /* Estiliza o host quando possui a classe blue */
:host([active]) {} /* Estiliza o host quando possui um atributo active */
:host(:hover) {} /* Estiliza o host quando o mouse estiver sobre ele */
```

Lembre que o host, vem com `display: inline` por padrão, importante lembrar disso caso o css não se comporte como você espera de primeira.

## Estilizando o host baseado no contexto

Podemos também estilizar o component baseado no estado CSS do seu elemento pai ou superior, fazemos isso utilizando `:host-context()` passando dentro do parênteses o seletor corresponde ao estado CSS de um dos elementos pai. Esse seletor funciona mais ou menos como se a gente colocasse `if parentElement has some-class apply this style (se o elemento pai tiver alguma-classe aplique este estilo)`.

```html
<body class="dark-theme">
  <my-component></my-component>
</body>
```

```css
/* Aplica um estilo quando um elemento pai tem a classe dark-theme */
:host-context(.dark-theme) {}
```

# Estilizando nós distribuídos

Como falamos em outras partes, os nós distribuídos são primeiramente afetados pelo estilo aplicado a eles no momento que são gerados no light DOM antes de entrarem no shadow DOM de um componente. Contudo, é possível estilizar esses elementos usando outro seletor especial `::slotted()`, passando dentro dos parenteses o seletor correspondente ao elemento distribuído que você deseja selecionar.

```css
/* Seleciona todo h2 que esteja em um <slot> */
::slotted(h2) {}

/* Seleciona todo span que seja filho direto de
   uma div com a classe "active" que esteja em um <slot>
*/
::slotted(div.active > span) {}

/* Seleciona todo elemento p que esteja
   em um <slot> filho de um section
*/
section > ::slotted(p) {}
```

Lembrando que na ordem de prevalência do CSS todos estilos aplicados no light DOM prevalecem sobre os estilos definidos usando `::slotted()`. Essa é uma maneira de deixar seus componentes muito mais customizavéis para quem for utilizar.

Caso você crie um `<slot>` com id ele pode ser usado para referenciar o elemento no css.

```html
<slot id="my-slot"></slot>
<style>
  /* Estiliza o conteúdo do slot com aquele id */
  #my-slot::slotted(*) {}
</style>
```

# Estilizando usando Parts

Outro recurso que temos para estilizar Web Components é o pseudo-seletor `::part()`, que permite o autor do componente definir trechos dos seus elementos que podem ser acessados por fora.

```html
#shadow-root
<header part="header">
  <h1>Título</h1>
</header>
<main part="content"></main>
<footer part="footer">
  <span>Rodapé</span>
</footer>
```

```css
/* Tem acesso ao header e total controle para alterar seu estilo */
my-element::part(header) {}

/* O mesmo se da para o footer e o main */
my-element::part(content) {}
my-element::part(footer) {}
```

Esse é um dos recursos que eu acho mais interessantes quando se trata de deixar nossos componentes customizáveis. É possível deixar muita coisa acessível e até mesmo inacessível se você desejar.

# Estilizando um componente por fora

Como vimos existem muitas maneiras de se estilizar um web component, porém a maneira mais simples é selecionando a tag:

```css
my-element {
	display: block;
	width: 300px;
}
```

**Estilizações definidas do lado de fora sempre sobrepõem as estilizações definidas no Shadow DOM**. Contudo, as vezes pode acontecer de não ser suficiente quando se quer estilizar algo mais interno no componente e dependendo é bem mais trabalhoso também, nesses casos podemos utilizar das propriedades customizadas do CSS.

```css
my-element {
	--internal-color: #333;
}
```

Dentro do componente:

```css
:host {
	color: var(--internal-color, white);
}
```

---

# Referências

[https://developers.google.com/web/fundamentals/web-components/shadowdom](https://developers.google.com/web/fundamentals/web-components/shadowdom)

[https://css-tricks.com/encapsulating-style-and-structure-with-shadow-dom/](https://css-tricks.com/encapsulating-style-and-structure-with-shadow-dom/)

# Conclusão

Agora você viu como por ser mais simples ou deixar mais simples a estilização de um Web Component. Espero muito que tenha gostado e caso tenha alguma dúvida pode deixar nos comentários e até o próximo!!!