Contenção de CSS no Chrome 52

Texto longo, leia o resumo

A nova propriedade CSS Contenment permite que os desenvolvedores limitem o escopo de estilos, layout e pintura do navegador.

Contenção do CSS. Antes: o layout leva 59,6 ms. Depois: o layout leva 0,05ms

Ele tem alguns valores, o que torna a sintaxe esta:

    contain: none | strict | content | [ size || layout || style || paint ]

Ele está no Chrome 52, no Opera 40 e em versões mais recentes e tem suporte público do Firefox. Teste sua experiência e nos conte o que achou.

A propriedade "Conte"

Ao criar um aplicativo da web ou até mesmo um site complexo, um desafio importante de desempenho é limitar os efeitos de estilos, layout e pintura. Muitas vezes, a toda do DOM é considerada "no escopo" para o trabalho computacional, o que pode significar que a tentativa de uma "visualização" independente em um app da Web pode ser complicada. As alterações em uma parte do DOM podem afetar outras, e não há como dizer ao navegador o que deve estar dentro ou fora do escopo.

Por exemplo, digamos que parte do seu DOM seja assim:

    <section class="view">
      Home
    </section>

    <section class="view">
      About
    </section>

    <section class="view">
      Contact
    </section>

E você anexa um novo elemento a uma visualização, o que aciona estilos, layout e pintura:

    <section class="view">
      Home
    </section>

    <section class="view">
      About
      <div class="newly-added-element">Check me out!</div>
    </section>

    <section class="view">
      Contact
    </section>

No entanto, nesse caso, o DOM inteiro está de fato no escopo, o que significa que os cálculos de estilo, layout e pintura precisam considerar todos os elementos, independentemente de terem sido alterados ou não. Quanto maior o DOM, maior o trabalho de computação, o que significa que você pode fazer o aplicativo não responder à entrada do usuário.

A boa notícia é que os navegadores modernos estão ficando muito inteligentes em limitar o escopo de estilos, layout e pintura automaticamente, o que significa que tudo está ficando mais rápido sem que você precise fazer nada.

Mas a notícia ainda melhor é que há uma nova propriedade do CSS que envia os controles de escopo aos desenvolvedores: a contenção.

A contenção de CSS é uma nova propriedade, com a palavra-chave "Conte", que suporta quatro valores:

  • layout
  • paint
  • size
  • style

Cada um desses valores permite limitar a quantidade de trabalho de renderização que o navegador precisa realizar. Vamos conferir cada um deles com mais detalhes.

Layout (conter: layout)

A contenção de layout é provavelmente o maior benefício da contenção, junto com contain: paint.

Normalmente, o layout tem escopo de documento, o que faz com que ele seja dimensionado proporcionalmente ao tamanho do DOM. Portanto, se você mudar a propriedade left de um elemento, talvez todos os elementos do DOM precisem ser verificados.

Ativar a contenção aqui pode reduzir o número de elementos a apenas alguns, ao invés de todo o documento, poupando ao navegador uma tonelada de trabalho desnecessário e melhorando significativamente o desempenho.

Tinta (conter: tinta)

A pintura do escopo é outro benefício incrivelmente útil da contenção. A contenção de tinta basicamente recorta o elemento em questão, mas também tem alguns outros efeitos colaterais:

  • Funciona como um bloco contêiner para elementos de posição absoluta e fixa. Isso significa que todos os filhos são posicionados com base no elemento com contain: paint, e não em qualquer outro elemento pai, como o documento.
  • Ele se torna um contexto de pilha. Isso significa que itens como z-index terão efeito no elemento e os filhos serão empilhados de acordo com o novo contexto.
  • Ele se torna um novo contexto de formatação. Isso significa que, se você tiver, por exemplo, um elemento no nível de bloco com contenção de pintura, ele será tratado como um novo ambiente de layout independente. Isso significa que o layout fora do elemento normalmente não afeta os filhos do elemento que o contém.

Tamanho (conter: tamanho)

contain: size significa que os filhos do elemento não afetam o tamanho do pai, e que as dimensões inferidas ou declaradas serão usadas. Consequentemente, se você definisse contain: size, mas não especificasse as dimensões do elemento (diretamente ou usando propriedades flexíveis), ele seria renderizado a 0 x 0 px.

A contenção de tamanho é uma medida de cinto e chaves para garantir que você não dependa de elementos filhos para dimensionar, mas por si só não oferece muitos benefícios de desempenho.

Estilo (contendo: estilo)

Pode ser difícil prever quais serão os efeitos da árvore do DOM de alteração de estilos de um elemento na árvore. Um exemplo disso é algo como contadores CSS, em que a alteração de um contador em um filho pode afetar valores de contador de mesmo nome usados em outras partes do documento. Quando contain: style está definido, as mudanças de estilo não são propagadas novamente para além do elemento que as contém.

Para deixar bem claro, o que o contain: style não oferece é o estilo com escopo, como aconteceria no Shadow DOM. A contenção aqui se resume apenas a limitar as partes da árvore que estão em consideração quando os estilos são modificados, e não quando são declarados.

Contenção de conteúdo e rigorosa

Também é possível combinar palavras-chave, como contain: layout paint, que vão aplicar somente esses comportamentos a um elemento. "Contem" também oferece suporte a dois outros valores:

  • contain: strict significa o mesmo que contain: size layout paint
  • contain: content significa o mesmo que contain: layout paint

Usar a contenção rígida é ótimo quando você sabe o tamanho do elemento com antecedência (ou quer reservar suas dimensões), mas lembre-se de que se você declarar contenção rígida sem dimensões, devido à contenção implícita de tamanho, o elemento pode ser renderizado como uma caixa de 0 x 0 px.

A contenção de conteúdo, por outro lado, oferece melhorias significativas de escopo, mas não exige que você saiba ou especifique as dimensões do elemento com antecedência.

Dos dois, contain: content é aquele que você deve usar por padrão. Trate a contenção rigorosa como uma solução de escape quando o contain: content não é forte o suficiente para você.

Conte-nos como você usa

A contenção é uma ótima maneira de começar a indicar ao navegador o que você pretende manter isolado na página. Experimente o Chrome 52 ou superior e nos conte o que você achou.