Entendendo unidades CSS e quando utilizá-las - parte 2
Tags: css, iniciante
Published: 2021-08-19 16:43:59

_Nesse artigo vou explicar sobre as unidades de números inteiros, viewport, ângulos, resolução e para impressos do CSS, citando exemplos de casos de uso delas. Essa é a parte dois de uma série de dois artigos, se você não leu o primeiro === desumilde_

##Introdução
Algumas das unidades que eu vou falar sobre aqui você já usou sem se dar conta que são unidades e algumas propriedades como `line-height` ou `transform` trabalham com diversos tipos de unidades e ter conhecimento delas te dá uma flexibilidade enorme. Deixei as unidades para impressos por ultimo pois eu particularmente nunca usei, mas é muito bom saber pois alguém sempre inventa de deixar uma página web "imprimível", mas pouca gente efetivamente se importa com como ela vai sair e, no final, acaba recorrendo a uns malabarismos que pelo amor.

Como aqui contém unidades que eu não uso muito no dia-a-dia ou que tem um escopo muito específico, eu serei um pouco mais breve em alguns casos, mas sem ser raso, ok?

--------
<br/>

## Números inteiros
Você já deve ter notado eles, `line-height`, funções de cor como `rgb()` ou `hsl()` e `width`. Em alguns casos o uso dessas unidades em detrimento a outras é irrelevante, mas vou citar alguns casos em que o uso de inteiros pode ajudar.

**Quando usar?**
O `line-height` é uma propriedade de texto extremamente importante, o espaçamento entre linhas em um parágrafo é essencial pra legibilidade do texto, inclusive, a WCAG (Diretrizes de Acessibilidade para Conteúdo Web) [tem como critério de sucesso um espaçamento entre linhas de, no mínimo, uma vez e meia maiores que o tamanho da fonte](https://www.w3.org/TR/WCAG21/#visual-presentation). Pode largar a régua e a calculadora, podemos declarar essa proporção com números inteiros e porcentagem:

```css
p {
  line-height: 1.5;
}

/* ou*/

p {
  line-height: 150%;
}
```
Outro caso de uso bacana é nas _media queries_. Podemos usar operadores lógicos no campo de _media condition_ com o tanto que os tamanhos sejam números inteiros, deixando elas muito mais legíveis:

```css
/* Telas cujo a largura é maior ou igual a 800px.
Declarações como width e height são computadas como valores
numéricos até que você declare uma unidade, suportando
assim os operadores lógicos =, >, <, >= e <= */

@media (width >= 600) {
  /* ... */
}
```

**Quando não usar?**
Em declarações como `margin`, `box-shadow` e afins é possível declarar valores zerados como inteiros, é interessante mesmo assim manter a consistência de unidades do mesmo jeito. Caso você use inteiros em propriedades que não aceitam elas simplesmente vão quebrar, ao inspecionar no navegador pelo devTools a propriedade aparecerá ~tachada~.

--------
<br/>

## Unidades de viewport
A viewport é calculada à partir das extremidades do primeiro _containing block_ segundo a especificação da W3 [aqui](https://www.w3.org/TR/css-values-3/#viewport-relative-lengths) e [aqui](https://www.w3.org/TR/CSS21/visudet.html#containing-block-details), mas o que é isso?

1. Quando você coloca `position: fixed;` em um elemento e `inset: 0;` (ou top, left, right, bottom igual a zero), é toda a área que esse elemento vai ocupar.

2. Se você abrir o console no seu navegador e digitar `window.innerWidth` e `window.innerHeight`, são os valores que aparecerão.

3. No devTools do seu navegador (Tenho certeza sobre o Chrome e o Firefox, Edge e outros não manjo), na aba computed, a propriedade `height` ou `width` do elemento aparecerá com o valor atual convertido em `px`
![Print do devTools do Chrome na aba computed mostrando os valores de um elemento declarado em px como vh](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfvadljkflbiqb3ykuq1.png)

Agora, `vmin` e `vmax` representam respectivamente "O menor e maior valor entre o vh e vw atual".

**Quando usar?**
Definitivamente no min-height do body ou, caso você costume colocar todo o conteúdo dentro de um mesmo container, nesse container. Isso garante que seu site sempre ocupe todo o viewport disponível mesmo na ausência de conteúdo, prevenindo o site aparecer com o footer no meio da tela quando o conteúdo por algum motivo não carrega.

Um jeito moderno e bacana de declarar isso é usando as _logical-properties_:

```css
body {
  min-block-size: 100vh;
}
```

Usamos também o `vmin` e o `vmax` como multiplicador pra criar uma escala modular de tamanhos de fonte, de forma responsiva.

E porquê `min-block-size`? Pois a altura **mínima** precisa ser a tela toda, se seu site tiver conteúdo pra baixo ele não poder ter restrição pra crescer, nesse caso você não precisa declarar uma `height` ou um `block-size`.


> **😐 Mas mano o que diabos é um `min-block-size`**
> 
> O `min-block-size` é uma **logical property**. As logical properties vieram na definição[CSS Logical Properties and Values Level 1](https://www.w3.org/TR/css-logical-1/) da W3 e possuem um [bom suporte de browser](https://caniuse.com/css-logical-props) (mas ainda é recomendado usar dentro de um @\supports).

> Nessa definição, as propriedades margin, border, padding, width e height e mais algumas outras podem ser escritas usando as orientações _block_ (eixo y) e _inline_ (eixo x), então:

```css
p {
  padding: 0 auto;
  
  /*Pode ser escrito*/
  padding-inline: auto;
  padding-block: 0;

  /*Ou*/
  padding-inline-start: auto; /*padding-left*/
  padding-inline-end: auto; /*padding-right*/
  padding-block-start: 0; /*padding-top*/
  padding-block-end: 0; /*padding-bottom*/
}
```

> **E qual a diferença?**
Quando usamos propriedades lógicas garantimos que os valores que colocarmos irão permanecer o mesmo independente do [writing-mode](https://developer.mozilla.org/pt-BR/docs/Web/CSS/writing-mode) que você esteja utilizando.


> [Aqui um codepen](https://codepen.io/camilo-micheletto/pen/RwVRxZW) que eu precisei usar _logical properties_ pois senão em todo o texto vertical eu tinha que declarar os valores ao contrário.
> Me ajudou muito pensar nesse problema tal como quando a gente muda o `flex-direction` pra `column` e os valores de `justify-content` e `align-items` trocassem de lugar. Se existisse um `justify-block-items`, não precisaria mais inverter sabe?

**Quando não usar?**
Evite usar `vw` direto no `body` se sua página tiver scroll vertical, essa unidade não conta o _scrollbar_ e vai ficar dando scroll lateral e na maioria dos casos não é isso que você quer.

Evite criar [escalas modulares de tamanhos de fonte de forma "responsiva" com unidades de viewport](https://www.smashingmagazine.com/2016/05/fluid-typography/), parece muito legal mas não escala responsivamente tão bem até 200% como pede a WCAG, você pode ler mais [nesse artigo do Adrian Roselli](https://adrianroselli.com/2019/12/responsive-type-and-zoom.html). Na dúvida não invente, use `clamp()`.

--------
<br/>

## Unidades de ângulo
Sim, isso existe, dentro do primeiro valor do seu `hsl()` pois como ele é representado por um [círculo cromático ou "roda de cores"](https://www.publicitarioscriativos.com/descubra-de-uma-vez-por-todas-como-utilizar-o-circulo-cromatico/), como muito bem demonstrado na imagem abaixo:

![circulo cromático representando qual cor está em qual grau](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/63fz4vacm8cvgkt1255x.png)

Em propriedades como `transform: rotate()` você consegue utilizar as unidades `grad`, `deg`, `rad` e `turn` que são, respectivamente:

- grad (grado)
`rotate(400grad)` representa uma volta completa em um circulo, grado é [uma unidade de ângulo de quem não tem o que fazer](https://pt.wikipedia.org/wiki/Grado_(%C3%A2ngulo)) (eu não sei pra que serve).

- deg (graus)
`rotate(180deg)` representa meia volta em um círculo de 360º, é a que eu vejo sendo comumente utilizada.

- rad (radianos, não fem)
`rotate(1rad)` também representa meia volta em um circulo de 360º.

- turn (volta)
`rotate(1turn)` dá uma volta num circulo, simples assim.

**Quando usar?**
Pra `hsl()` eu uso `deg` pois faz muito mais sentido pra mim alterar a matiz de uma cor usando o ângulo que ela se encontra, fica tranquilo de ajustar se precisar.
> **Dica 💡** o `hsl()` pode ser escrito sem o `deg` assim: `hsl(280, 30%, 30%);`, eu que sou fresco.

Pra `rotate()` eu prefiro `turn`, geralmente preciso que os elementos dêem uma quantidade x de voltas quando ele precisa rotacionar.

Mas são só preferências pessoais, a regra é sempre manter a consistência de unidades seja lá qual for que você vá utilizar.

**Quando não usar**
Não consegui pensar em nenhuma contraindicação, só mantenha a consistência na unidade que você escolher usar e tá tudo certo.

--------
<br/>

## Unidades de resolução
As unidades `dpi`, `dpcm` e `dppx` se referem a pontos por polegada, centímetro e pixel respectivamente. Essa unidade é importante pois elementos baseados em pixel mudam de aspecto de acordo com a densidade de pixel da tela do dispositivo.

Monitores apple e outros dispositivos retina possuem 326dpi, ou seja, contém 4x mais pixeis dentro de um mesmo espaço, afetando como propriedades declaradas em pixel se parecem.

> Como no CSS a razão entre `px` e `in` (polegada) é de 1:96, `1dppx` é igual a `96dpi`

**Quando usar?**
Quando acontece diferença no aspecto de elementos em dispositivos retina, podemos aumentar seus valores dentro de uma _media query_ utilizando da _feature query_ _image-resolution_:

```css

@media (resolution >= 2dppx) { ... }

/*Pra alterar valores pra mídia impressa, podemos usar o media
type 'print' */
@media print and (min-resolution: 300dpi) { ... }
@media print and (min-resolution: 118dpcm) { … }

```


--------
<br/>

## Unidades para impressos
Há chances de você nunca ter precisado preparar determinada página web para impressão, principalmente quando os elementos da tela tem que ter seu posicionamento compatível com um veículo de mídia física como uma folha de papel. Pra realizar essa conversão de forma que não seja no olhômetro ou tendo que apertar `ctrl + p` a cada alteração de página, temos as seguintes unidades:

|Unidade|Nome|Equivalência|
|----|----|---|
|cm|centimetros|1cm = 96px/2.54|
|mm|milimetros|1mm = 1/10 de 1cm|
|in|polegadas|1in = 2.54cm = 96px|
|pc|picas (lkkkk)|1pc = 1/6 de 1in|
|pt|pontos|1pt = 1/72 de 1in|
|px|pixels|1px = 1/96 de 1in|
<small>Tradução livre [dessa tabela da W3](https://www.w3.org/TR/css-values-3/#absolute-lengths)</small>

**Quando utilizar?**
Vamos supor que você precise gerar um impresso que contenha uma margem ABNT (3 cm para as margens superior e esquerda e 2 cm para as margens inferior e direita, tamanho 12pt para texto e 14pt em negrito para títulos).

```css
@media print {
  /* O corpo do impresso precisa ter o mesmo tamanho
  do A4 - 21 x 29.7cm */
  .printable {
    padding: 3cm 2cm 2cm 3cm;
    block-size: 29.7cm;
    inline-size: 21cm;
  }
  /* O tamanho da fonte no word é em pontos, não pixeis */
  h1 {
    font-size: 14pt;
    font-weight: bold;
  }

  p {
    font-size: 12pt;
  }
}
```

**Quando não utilizar?**
Em casos que a saída desse arquivo não seja em uma mídia compatível com essas medidas no mundo real.

Obs: Omiti a unidade `Q` propositalmente pois ela representa 1/4 de centímetro, tipo, pra que sabe?

---------------------------
<br />

## Fontes e leituras adicionais
- [Media quality features na W3](https://www.w3.org/TR/mediaqueries-4/#mf-display-quality)

- [Unidades absolutas na W3](https://www.w3.org/TR/css-values-3/#absolute-lengths),[unidades de viewport na W3](https://www.w3.org/TR/css-values-3/#viewport-relative-lengths), [unidades de ângulo na W3](https://www.w3.org/TR/css-values-3/#angles), [unidades de resolução na W3](https://www.w3.org/TR/css-values-3/#resolution)

- [Unidades CSS na MDN](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units)

- Logical properties
[Esse vídeo do Kevin Powell](https://www.youtube.com/watch?v=kzvmaVik4mA) é absurdo de bom, tem esse post do [CSS Tricks](https://css-tricks.com/css-logical-properties-and-values/) e [esse do WebDev](https://web.dev/learn/css/logical-properties/).

**Observação:**
Se nesse texto eu:
- Falei merda
- Caguei regra
- Perdi a oportunidade de usar de linguagem neutra
- Cometi erros de português
- Poderia ter explicado algo melhor ou falei algo que não fez sentido

Ou se só ficou alguma dúvida mesmo.
Pode comentar aqui ou me chamar no [Twitter](https://mobile.twitter.com/lixeletto) que eu vou amar ok?

**Observação 2**
Recomendei muito texto em inglês nessa postagem, se vocês conhecem pessoas que escreveram sobre esses assuntos, me mande pois eu dou preferência pra nóis né?


Obrigadíssimo 😙