CSS Fragmentation

Neste artigo vou apresentar um módulo do CSS chamado CSS fragmentation. Talvez você já o tenha utilizado e não saiba.

A princípio, é importante saber que todo elemento é definido por uma caixa (box) que pode estar disposta em dois níveis, block e inline:

  • block: são aqueles que elementos que aparecem em uma nova linha, como parágrafos, listas, cabeçalhos, etc.
  • inline: são elementos que ficam na mesma linha uns próximos aos outros como, links, spans, input, etc.

A fragmentação ocorre quando queremos controlar a quebra do conteúdo entre múltiplas páginas numa impressão ou quando estamos criando um layout com múltiplas colunas.

Fragmentação com múltiplas colunas

Vejamos nosso primeiro exemplo, nele dividimos nosso layout em três colunas utilizando as propriedades do CSS column-width e column-gap.

body {
  padding: 2em;
  font: 16px/1.5 'Open Sans', sans-serif;
  color: #333;
}

section {
  margin-bottom: 2em;
  padding-bottom: 2em;
}

.wrapper {
  width: 800px;
  margin: 0 auto;
}

.box {
  border: 5px dashed red;
  padding: 10px;
  font-size: 25px;
  font-weight: 600;
}

.container {
  column-width: 250px;
  column-gap: 25px;
}
<div class="container">
                <p>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis fringilla ultrices arcu, at
                    pellentesque ex consectetur vehicula. Nulla sed volutpat mi. Nulla fringilla ultrices tellus, sed
                    pharetra ex porta a. Etiam ac posuere libero.
                </p>

                <div class="box">
                    Caixa de texto aparecendo em duas colunas.
                </div>

                <p>Nam ultrices, mi nec imperdiet venenatis, tortor lorem
                    faucibus risus, eu maximus lacus velit rutrum nunc. Phasellus vitae consectetur eros. Duis
                    scelerisque porta ex, quis pharetra ipsum laoreet id. Fusce interdum ut diam id tristique. Morbi
                    lacinia turpis ac nisl facilisis, eget volutpat lacus blandit. Aenean sed eleifend augue. Donec nec
                    vulputate tortor. Pellentesque neque turpis, luctus facilisis felis ac, iaculis gravida nisl.Morbi
                    nibh erat, elementum a arcu a, dictum feugiat ante. Pellentesque tempus urna ac tortor sodales
                    ullamcorper. Duis dignissim malesuada elit sit amet sollicitudin. Maecenas sodales auctor ex, id
                    lobortis arcu molestie sit amet. </p>
            </div>

Mas repare que algo inconveniente ocorre, a caixa de texto ficou dividido entre a primeira e a segunda coluna.

Para corrigir o problema podemos utilizar a propriedade break-inside como avoid na classe .box:

-webkit-column-break-inside: avoid; /* Chrome, Safari, Opera */
          page-break-inside: avoid; /* Firefox */
               break-inside: avoid; /* IE 10+ */

Ela define como a quebra de uma página, coluna ou região deve se comportar, assim quando escolhemos avoid, estamos dizendo para evitar qualquer quebra a partir da caixa de texto dentro do layout multi-coluna.

Essa propriedade ainda controla a quebra dentro de um parágrafo, cabeçalho ou div. Você poderia por exemplo fazer com que uma lista fosse exibida em uma coluna (em vez de transbordar para a próxima coluna) com break-inside: avoid-column ou entre páginas com break-inside: avoid-page.

Outras propriedades

break-before e break-after

Um caso muito comum em que utilizamos essas propriedades é quando temos a impressão de uma página e queremos garantir que o conteúdo seja quebrado antes ou depois de uma determinada tag. Por exemplo:break-before e break-after.

h3 {
  break-before: page;
}

Ou

p {
  break-after: page;
}

Nos daria a quebra antes do segundo Título 2 (h3) ou após um parágrafo qualquer:

orphans e widows

A propriedade orphan especifica o número mínimo de linhas que devem ser deixadas no final do parágrafo antes da quebra de página ou de coluna.

p {
orphans: 3;
}

Este código está dizendo que queremos um mínimo de 3 linhas restantes em uma página se um parágrafo for dividido.

Ele age como um guia para dizer ao navegador, se não é possível deixar pelo menos 3 linhas antes de colocar todo o texto na nova página.

É importante observar que essas propriedades são consideradas preferências e não regras, isto é, se o navegador não puder descobrir uma maneira de fazer com que funcione seguindo as regras, ele as ignorará em favor de algo que considera funcionar.

A propriedade da window especifica o número mínimo de linhas de um parágrafo que deve ser deixado no topo antes da quebra de página ou de coluna.

p {
widows: 4;
}

Neste caso o código diz que queremos um mínimo de 4 linhas no início de uma página ou coluna se um parágrafo for dividido.

Ele age como um guia para dizer ao navegador que, se você vai começar a próxima página com menos de 4 linhas, não será o bastante.

Novamente é importante observar que essas propriedades são preferências e não regras.

box-decoration-break

Essa propriedade permite controlar uma situação em que você tenha uma caixa com uma borda quebrada entre duas colunas ou páginas, nos dando a possibilidade de cortar pela metade ou deixar que as duas metades da caixa sejam envolvidas totalmente em uma borda.

.box {
-webkit-box-decoration-break: slice;
  -o-box-decoration-break: slice;
  box-decoration-break: slice;
}
.box {
  -webkit-box-decoration-break: clone;
  -o-box-decoration-break: clone;
  box-decoration-break: clone;
}

É importante notar que nem todos os navegadores oferecem suporte para essa propriedade, (veja https://caniuse.com/#search=box-decoration-break) e que nos outros casos mesmo havendo suporte, ainda devemos ter cuidado nos testes, evitando utilizar a fragmentação desnecessariamente para não termos futuras surpresas quando o conteúdo da página for alterado.

Leia mais detalhes sobre o assunto em MDN web docs https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fragmentation

Compartilhe!