Deixe seu frontend mais consistente com componentes positionless
Tags: css, html, webdev, braziliandevs
Published: 2023-08-24 19:17:45

Por mais que muita gente diga por aí que front-end é fácil, não é. E só nós pessoas de front-end sabemos disso, pois pode até parecer simples posicionar elementos com CSS numa tela, mas será que está sendo feito da melhor forma?

E são essas boas práticas que levam muito tempo para entrar na cabeça de uma pessoa iniciante, ter o conhecimento de como posicionar, alinhar ou separar elementos numa tela. E vou deixar meus cinco centavos sobre isso neste post.

## Mas de onde surgiu o termo "positionless"?

Confesso que esse termo surgiu na minha cabeça (até pesquisei mas não encontrei nada) muito inspirado pelo termo "tableless" que foi uma revolução no desenvolvimento web há uns 15/20 anos quando devs largaram a mão de montar sites com tabelas e também pelo termo "stateless" que é basicamente ter componentes agnósticos livres de manipulação de estado.

E com isso o termo "positionless" veio justamente por pensar na boa prática de deixar componentes de um layout livres de qualquer regra CSS que manipule seu próprio posicionamento na viewport.

## Como é uma tela sem componentes "positionless"?

Eu tenho certeza que em projetos pessoais no início de carreira ou até em projetos legados de alguma empresa que tenha trabalhado você já viu um código dessa forma com elementos posicionados hardcoded:

<a name="exemplo-de-botao-no-header"></a>

**Exemplo de botão no header**

```html
<div class="header">
  <img src="logo.png">
  <a href="" class="button">Fale conosco</a>
</div>
```

```css
.header {
  position: relative;
}

.button {
  position: absolute;
  top: 15px;
  right: 15px;
}
```

Ou até, também, numa lista de posts de um blog:

<a name="exemplo-de-lista-de-posts"></a>

**Exemplo de lista de posts**

```html
<div class="list">
  <div class="card">
    <img src="card-thumb.png">
    <h2 class="card-title">Título do post</h2>
  </div>
  ...
</div>
```

```css
.card {
  margin: 10px;
}
```

> Isso tudo se ainda não estiver com o estilo inline que deixaria tudo muito pior, né?

Repare nesses trechos de código que o posicionamento/separação dos elementos `.button` e `.card` estão cuidando do próprio posicionamento, seja com `position` ou com `margin`.

Mas agora pensa comigo, provavelmente esse button e esse card está sendo ou poderá ser utilizado em outras partes do site, certo? E se o posicionamento ou separação for diferente em outro lugar? Você vai sobrescrever esse código de que forma? Vai criar outra folha de estilo se for em outra página? Vai usar `!important` se for na mesma página?

Por que não deixar os componentes da sua aplicação agnósticos de posicionamento? Porque o problema não é usar position/margin/etc, isso são recursos que são feitos para serem usados em determinados casos, o problema é usá-los de forma errada que pode prejudicar todo o prosseguimento do seu desenvolvimento de layout.

Então que tal deixar a responsabilidade do posicionamento para o pai daquele componente específico? No exemplo do botão do header, [aproveitando o HTML](#exemplo-de-botao-no-header), podemos ao invés de usar `position` para jogar o botão para o lado direito do header alinhado ao logo, podemos fazer com flexbox dessa forma: 

```css
.header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
```

Ficando ainda melhor não só na questão de deixar a responsabilidade de posicionamento para o pai, mas também por não criar uma nova camada deixando o layout mais complexo para ser renderizado e manutenido.

E no exemplo da [listagem de posts](#exemplo-de-lista-de-posts), deixando a responsabilidade de separação de cards para o pai podemos usar `gap` na lista ao invés do `margin` diretamente nos cards que estava afetando todos os cards da aplicação, dessa forma:

```css
.list {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 10px;
}
```

## "Mas e se eu precisar estilizar um elemento específico?"

Certo, pode ser que você realmente precise editar o posicionamento de algum elemento específico, mas pense uma forma que aquilo não afete as outras partes de seu layout e também que force tanto a especificidade, deixando tudo muito complexo.

Pense que uma vez que seu componente é agnóstico, ele pode ser incluído em qualquer lugar de seu layout e o pai/container dele que ficará responsável por isso, logo podemos fazer algo no sentido lá do primeiro exemplo:

```css
.header .button {
  position: absolute;
  top: 15px;
  right: 15px;
}
```

MAS CALMA LÁ! É aí que você precisa repensar se essa é a melhor forma de se fazer isso, pois mesmo não afetando outras partes do site pode ter uma forma melhor e nesse exemplo específico, vimos que não, pois conseguimos posicionar o botão da forma que gostaríamos sem criar um segundo nível de especificidade, pois zero especificidade é melhor que uma especificidade.

 
## Conclusão

Com tudo isso podemos ver o quão consistente nosso layout fica e também o tanto de recurso que economizados não tendo que sobrescrever estilos usando o horroroso `!important` ou criando especificidades desnecessárias que poderiam ser evitadas deixando a responsabilidade ao pai do seu componente.

Antes de começar a criar suas divs e seus style.css ou de começar a manutenção do site de qualquer forma, pense bem em como aquele elemento será reutilizado e no que outros lugares de sua aplicação poderá ser afetada com aquela nova edição ou adição.

Eu quero ouvir a opinião de vocês sobre isso nos comentários. That's all folks!

## Referências para estudo

- [Especificidade na MDN](https://developer.mozilla.org/pt-BR/docs/Web/CSS/Specificity)
- [Don’t Use Margins For Spacing Between Components, Use Gaps](https://dev.to/domagojvidovic/dont-use-margins-for-spacing-between-components-use-gaps-4llc)