Como fazer pro texto não quebrar de linha no CSS
Tags: css, webdev, beginners, braziliandevs
Published: 2023-05-06 04:42:33


_Se você desenvolve layouts no seu dia-a-dia, o causo da imagem abaixo já aconteceu com você_

![Imagem de um chat entre duas pessoas. A pessoa um diz "puta que pariu caralho", a pessoa 2 responde com "?", a pessoa 1 então manda uma imagem de um botão em que o texto interno está quebrando em duas linhas com a frase "essa porra quebra de linha", ao que a pessoa 2 responde "tentou white-space?"](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2j7ivtli0j8saummjp1d.png)

&nbsp;

E geralmente te recomendam uma dessas soluções:
- width: 100%
- word-break
- white-space

Mas muito provavelmente seu problema não tem nada a ver com nenhuma dessas 3 propriedades.

Nesse artigo eu vou explicar porque esse problema acontece e como o navegador entende quebras de linha.

<br />

------

<br />

## O real problema

Se você adicionar estilo nenhum no elemento, o valor padrão da `width` dele será "auto".

A width de "auto" primeiro faz a soma da largura total do seu conteúdo + border + margin-inline + padding-inline. Se a soma disso for menor que o espaço disponível, a `width` vai ocupar todo espaço disponível, mas se for menor que o espaço disponível, ela vai procurar oportunidades de **_soft wrap_** (ou quebra fofo), ou seja caracteres de espaço (U+0020) e sinalizadores de quebra de linha (U+000D).

O algoritmo que aplica soft-wrap de acordo com o tamanho do container que é o que provavelmente decidiu por você que seu texto não cabe em 1 linha só.

Isso é um problema de width que pode ser resolvido com _intrinsic-sizing_!

A propriedade `width: max-content` vai dizer que o container tem que ser no mínimo do tamanho do conteúdo.

Eu falo bem mais detalhadamente nesse meu artigo sobre intrinsic sizing:
{% embed https://dev.to/lixeletto/alem-das-unidades-css-intrinsic-sizing-e-responsividade-gl %}

&nbsp;

`width: 100%;` pode não só não resolver como quebrar o seu layout!
Isso se deve ao fato de que os 100% são aplicados apenas ao conteúdo, a largura final vai ser somada à largura do padding, margin e border, "estourando" seu conteúdo horizontalmente.


![Imagem de dois containers, um com width de auto e outro com width de 100%, o segundo com overflow por causa da propriedade](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/09c9h06ks6wsww1s4bie.png)
<small>Imagem por Ahmad Hadeed no seu artigo [Everything About Auto in CSS](https://ishadeed.com/article/auto-css/)</small>

&nbsp;

<br />

------

<br />

## E as outras propriedades?

Elas basicamente usam da engine do navegador que lida com espaço em branco. Whitespace (pra ser curto) é de extrema importância pro navegador - ela é responsável por manter algumas tabulações da sua identação, espaço entre palavras, mas se você escreve algo como exemplo abaixo com espaçamento escagalhado, ela interpreta corretamente os espaços, tabulações e quebras de linha que tem que ignorar.

![Um h1 contendo uma palavra Hello e um span com a palavra World! com muitos excessos de espaçamento e tabulação](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pmq3w59ltxoagylnxfit.png)
<small>Print retirado do artigo [How whitespace is handled by HTML, CSS, and in the DOM da MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace#how_does_css_process_whitespace)</small>

&nbsp;

> Daqui pra baixo é nerdagem, então <a href="#tldr">TL:DR</a>
> **Essas propriedades basicamente chupinham da lógica de quebra de espaço do navegador**

&nbsp;

<br />

------

<br />

## O navegador e o algoritmo de whitespace

Quando o _whitespace _é delimitado pra elementos [inline](https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements#list_of_inline_elements) (TextNodes, `<span>`, `<input>`, etc), o navegador cria um contexto específico pra eles chamado _Inline Formatting Context_ (vou chamar de IFC).

O IFC calcula as quebras de espaço e também  coordena eixo de leitura [`text-orientation`](https://developer.mozilla.org/en-US/docs/Web/CSS/text-orientation)

O IFC lida com espaçamentos da seguinte forma
```html
<!-- Legenda
  ◦ - espaço
  ⇥ - tabulação
  ⏎ - quebra de linha
-->
<!-- Primeiro, espaços e tabs imediatamente antes
e depois de uma quebra de linha são ignorados,
então se pegarmos o exemplo abaixo... -->

<h1>◦◦◦Hello◦⏎
⇥⇥⇥⇥<span>◦World!</span>⇥◦◦</h1>

<!-- ...e aplicar essa regra, nós temos: -->

<h1>◦◦◦Hello⏎
<span>◦World!</span>⇥◦◦</h1>

<!-- A seguir, todos os caracteres de tab são
transformados em caracteres de tab, então
o exemplo fica da seguinte maneira: -->

<h1>◦◦◦Hello⏎
<span>◦World!</span>◦◦◦</h1>


<!-- Em seguida, quebras de linhas também são
convertidas em espaços: -->

<h1>◦◦◦Hello◦<span>◦World!</span>◦◦◦</h1>

<!-- Após isso, qualquer espaço seguido imediatamente
de outro espaço (mesmo entre dois elementos separados)
é ignorado, nos deixando com o seguinte: -->

<h1>◦Hello◦<span>World!</span>◦</h1>

<!-- E finalmente, espaços no começo e no fim
do elemento são removidos, nos resultando isso: -->

<h1>Hello◦<span>World!</span></h1>

```
<small>Transcrito da publicação [How whitespace is handled by HTML, CSS, and in the DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace#how_does_css_process_whitespace), traduzido por mim.</small>

&nbsp;

> 💡 Inclusive, traduzi usando o designMode do navegador, é tipo um `contenteditable`. Não sabe o que é isso? [Leia essa thread do @omariosouto no Twitter](https://twitter.com/omariosouto/status/1653356007391649794?s=20)

&nbsp;

<br />

------

<br />

## A propriedade `white-space`

O `white-space` usa esse algoritmo pra calcular as "_soft wrap opportunities_" que são espaços e tabs, mas também quebras de palavras se a propriedade [`hyphens: auto;`](https://developer.mozilla.org/pt-BR/docs/Web/CSS/hyphens) estiver presente pro elemento.

Essa propriedade também aplica hífen em quebras de palavras de acordo com o atributo `lang` do seu HTML.

Quais são os valores aceitos pelo `white-space`?

| Valor | Novas Linhas | Espaçoes e tabulações | Quebra de texto |
| :---: | :---:| :---: | :---: |
| `normal` | Recolhido | Recolhido | Quebra |
| `nowrap` | Recolhido | Recolhido | Sem quebra |
| `pre` | Preservado | Preservado | Sem quebra  |
| `pre-wrap` | Preservado | Preservado | Quebra  |
| `pre-line` | Preservado | Recolhido | Quebra  |
| `break-spaces` | Preservado | Preservado| Quebra  |
<small>Tabela transcrita da [documentação do white-space na MDN, em inglês, pois a em português está terrivelmente desatualizada](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space).</small>

&nbsp;

Aplicadas, essas propriedades se comportam da seguinte maneira:
![Textos com diferentes aplicações de white-space](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pmfo12wufrxmsdz4bkbi.png)

<br />

------

<br />

### A propriedade `word-break`

Essa propriedade define como o navegador vai calcular o agrupamento de caracteres, quais são quebráveis por hyphens ou soft wrap opportunities, especialmente necessário em caracteres CJK (Chinese, Japanese, Korean).

Os valores de [`word-break`](https://developer.mozilla.org/en-US/docs/Web/CSS/word-break) são `normal`, `keep-all` e `break-all`.

- `normal`
Quebra de linha padrão


- `keep-all`
Não permite quebra nenhuma pra caracteres CKJ, mas age como `normal` pra outros caracteres.

- `break-all`
Vai inserir quebra em qualquer espaço entre caracteres, mesmo CKJ.

> ⛔ Geralmente, pra resolver o problema de quebra de linha, sugerem essa propriedade ao invés de `white-space` e a maioria das vezes não funciona, agora entende o porquê?

&nbsp;

![Exemplos de word-break](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/33c68g01in3xk3xiyqwj.png)
<small>`word-break: break-word` omitido por estar depreciado</small>

<br />

------

<br />

### A propriedade `overflow-wrap`

Ele não cuida do espaço em branco, nem dos _soft wraps_ e hifenações entre palavras, ele cuida da lógica que o container pai usa pra decidir se as palavras dentro dele devem quebrar de linha ou não.

É basicamente **o mesmo** algoritmo que intrinsic sizing utiliza!

Os seus valores são `normal`, `anywhere` e `break-word`

- `normal`
É o comportamento normal - quebra em _soft wraps_ se o texto não couber no container.

- `anywhere`
Vai quebrar **todas** as palavras em _soft wraps_, e na ausência deles só vai quebrar msm, e sem hífen ein!

- `break-word` (antigamente valor da propriedade word-break)
Vai funcionar que nem o `anywhere` **mas** vai manter palavras na mesma linha se elas couberem.

Eles funcionam mais ou menos como `width: max-content`, `min-content` e `fit-content`, respectivamente;


![Demonstração de overflow-wrap](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5nvf8y57m93kn9tnfen5.png)

&nbsp;


## <span id="tldr">TL;DR</span>

O **white-space** controla o algoritmo que o navegador utiliza pra lidar com espaço em branco.
O **word-break** lida com como o navegador coordena o agrupamento de caracteres de acordo com hifenação e linguagem.
O **overflow-wrap** lida como o elemento coordena o conteúdo de acordo com seu tamanho intrínseco.


<br />

------

<br />

E por hoje é isso!

E ai, vocês já tiveram esse tipo de problema? Como resolveram?
Espero que tenha ajudado algumas pessoas a chutar menos!