Ayudando a los navegadores a optimizar con la propiedad CSS Contain
Publicado: 2022-03-10contain
CSS le brinda una manera de explicar su diseño al navegador, para que se puedan realizar optimizaciones de rendimiento. Sin embargo, viene con algunos efectos secundarios en términos de su diseño. En este artículo, voy a presentar una especificación CSS que acaba de convertirse en una recomendación W3C. La especificación de contención CSS define una propiedad única, contain
, y puede ayudarlo a explicarle al navegador qué partes de su diseño son independientes y no necesitarán volver a calcularse si alguna otra parte del diseño cambia.
Si bien esta propiedad existe por razones de optimización del rendimiento, también puede afectar el diseño de su página. Por lo tanto, en este artículo, explicaré los diferentes tipos de contención de los que puede beneficiarse, pero también las cosas que debe tener en cuenta si aplica la contain
a los elementos de su sitio.
El problema del recálculo del diseño
Si está creando páginas web sencillas que no agregan ni cambian elementos dinámicamente después de que se hayan cargado mediante JavaScript, no necesita preocuparse por el problema que resuelve CSS Containment. El navegador solo necesita calcular su diseño una vez, mientras se carga la página.
Donde la Contención se vuelve útil es cuando desea agregar elementos a su página sin que el usuario necesite volver a cargarla. En mi ejemplo, creé una gran lista de eventos. Si hace clic en el botón, se modifica el primer evento, se agrega un elemento flotante y se cambia el texto:
Cuando se cambia el contenido de nuestra casilla, el navegador tiene que considerar que alguno de los elementos puede haber cambiado. En general, los navegadores son bastante buenos para lidiar con esto, ya que es algo común que sucede. Dicho esto, como desarrollador, sabrá si cada uno de los componentes es independiente y que un cambio en uno no afecta a los demás, por lo que sería bueno que pudiera informar al navegador a través de su CSS. Esto es lo que le brinda la propiedad de contain
y CSS.
¿Cómo ayuda la contención?
Un documento HTML es una estructura de árbol que puede ver al inspeccionar cualquier elemento con DevTools. En mi ejemplo anterior, identifico un elemento que quiero cambiar usando JavaScript y luego realizo algunos cambios en las partes internas. (Esto significa que solo estoy cambiando cosas dentro del subárbol para ese elemento de la lista).
La aplicación de la propiedad de contain
a un elemento le dice al navegador que los cambios se limitan al subárbol de ese elemento, de modo que el navegador puede realizar cualquier optimización posible, con la certeza de que nada más fuera de ese elemento cambiará. Exactamente lo que un navegador en particular podría hacer depende del motor. La propiedad CSS simplemente le brinda, como desarrollador y experto en este diseño, la oportunidad de informarlo.
En muchos casos, estará seguro de seguir adelante y comenzar a usar la propiedad de contain
, sin embargo, los diferentes valores tienen algunos efectos secundarios potenciales que vale la pena comprender antes de agregar la propiedad a los elementos de su sitio.
Uso de contención
La propiedad contain
puede establecer tres tipos diferentes de contención:
-
layout
-
paint
-
size
Nota : Hay un valor de style
en la especificación de nivel 2. Se eliminó del Nivel 1, por lo que no aparece en la Recomendación y no está implementado en Firefox.
Disposición
La contención del diseño brinda los mayores beneficios. Para activar la contención de diseño, use el siguiente fragmento:
.item { contain: layout; }
Con la contención de diseño habilitada, el navegador sabe que nada fuera del elemento puede afectar el diseño interno, y nada dentro del elemento puede cambiar nada sobre el diseño de las cosas fuera de él. Esto significa que puede realizar cualquier optimización posible para este escenario.
Algunas cosas adicionales suceden cuando la contención de diseño está habilitada. Todas estas son cosas que aseguran que esta caja y su contenido sean independientes del resto del árbol.
El cuadro establece un contexto de formato independiente . Esto asegura que el contenido de la caja permanezca en la caja; en particular, los flotantes estarán contenidos y los márgenes no colapsarán a través de la caja. Este es el mismo comportamiento que activamos cuando usamos display: flow-root
como se explica en mi artículo "Comprender el diseño CSS y el contexto de formato de bloque". Si un flotador pudiera sobresalir de su caja, haciendo que el siguiente texto fluya alrededor del flotador, esa sería una situación en la que el elemento cambiaría el diseño de las cosas fuera de él, lo que lo convertiría en un mal candidato para la contención.
La caja contenedora actúa como el bloque contenedor para cualquier descendiente de posición absoluta o fija. Esto significa que actuará como si hubiera usado position: relative
en el cuadro que aplicó contain: layout
.
La caja también crea un contexto de apilamiento . Por lo tanto z-index
funcionará en este elemento, sus elementos secundarios se apilarán en función de este nuevo contexto.
Si nos fijamos en el ejemplo, esta vez con contain: layout
, puedes ver que cuando se introduce el elemento flotante ya no sobresale por la parte inferior de la caja. Este es nuestro nuevo contexto de formato de bloque en acción, que contiene el flotante.
Pintura
Para activar la contención de pintura, utilice lo siguiente:
.item { contain: paint; }
Con la contención de pintura habilitada, se producen los mismos efectos secundarios que se observan con la contención de diseño: el cuadro contenedor se convierte en un contexto de formato independiente, un bloque contenedor para elementos posicionados y establece un contexto de apilamiento.
Lo que hace la contención de pintura es indicarle al navegador que los elementos dentro del bloque contenedor no serán visibles fuera de los límites de ese cuadro. El contenido será esencialmente recortado a la caja.
Podemos ver que esto sucede con un ejemplo simple. Incluso si le damos una altura a nuestra tarjeta, el elemento flotante todavía sobresale por la parte inferior de la caja, debido al hecho de que el flotador está fuera del flujo.
Con la contención de pintura activada, el elemento flotante ahora se recorta al tamaño de la caja. No se puede pintar nada fuera de los límites del elemento con la contain: paint
aplicada.
Tamaño
La contención de tamaño es el valor que es más probable que le cause un problema si no está completamente consciente de cómo funciona. Para aplicar la contención de tamaño, utilice:
.item { contain: size; }
Si usa la contención de tamaño, le está diciendo al navegador que conoce el tamaño de la caja y que no va a cambiar. Esto significa que si tiene un cuadro cuyo tamaño se ajusta automáticamente en la dimensión del bloque, se tratará como si el contenido no tuviera tamaño, por lo tanto, el cuadro se colapsará como si no tuviera contenido.
En el siguiente ejemplo, no le he dado una altura a li
; también contain: size
aplicado. Puede ver que todos los elementos se han colapsado como si no tuvieran ningún contenido, lo que lo convierte en una lista de aspecto muy peculiar.
Si le da a las cajas una altura, se respetará la altura cuando se use el contain: size
Por sí sola, la contención de tamaño no creará un nuevo contexto de formato y, por lo tanto, no contiene flotadores ni márgenes como lo hará la contención de diseño y pintura. Es menos probable que lo use solo; en cambio, lo más probable es que lo aplique junto con otros valores de contain
para poder obtener la mayor contención posible.
Valores abreviados
En la mayoría de los casos, puede utilizar uno de los dos valores abreviados para sacar el máximo partido de la contención. Para activar el diseño y la contención de pintura, utilice contain: content;
, y para activar toda la contención posible (teniendo en cuenta que los elementos que no tienen un tamaño se colapsarán), use contain: strict
.
La especificación dice:
“contain: content
es razonablemente "seguro" para aplicarse ampliamente; sus efectos son bastante menores en la práctica, y la mayoría del contenido no entrará en conflicto con sus restricciones. Sin embargo, debido a que no aplica la contención de tamaño, el elemento aún puede responder al tamaño de su contenido, lo que puede provocar que la invalidación del diseño se filtre más arriba de lo deseado en el árbol. Usecontain: strict
cuando sea posible, para obtener la mayor contención posible”.
Por lo tanto, si no conoce el tamaño de los elementos de antemano y comprende el hecho de que se contendrán los espacios flotantes y los márgenes, utilice la función de contain: content
. Si conoce el tamaño de los elementos además de estar contento con los otros efectos secundarios de la contención, use contain: strict
. El resto depende del navegador, has puesto tu granito de arena explicando cómo funciona tu diseño.
¿Puedo usar la contención ahora?
La especificación de contención CSS ahora es una recomendación W3C, que es a lo que a veces nos referimos como un estándar web . Para que la especificación llegara a esta etapa, era necesario que hubiera dos implementaciones de la característica que podemos ver tanto en Firefox como en Chrome:
Como esta propiedad es transparente para el usuario, es completamente seguro agregarla a cualquier sitio, incluso si tiene muchos visitantes en navegadores que no la admiten. Si el navegador no es compatible con la contención, el visitante obtiene la experiencia que suele obtener, los navegadores compatibles obtienen un rendimiento mejorado.
Sugeriría que esto es una gran cosa para agregar a cualquier componente que cree en una biblioteca de componentes o patrones, si está trabajando de esta manera, es probable que cada componente esté diseñado para ser algo independiente que no afecta a otros elementos en el página, haciendo que el contain: content
una adición útil.
Por lo tanto, si tiene una página que está agregando contenido al DOM después de la carga, le recomendaría que lo pruebe. Si obtiene algún resultado interesante, ¡hágamelo saber en los comentarios!
Recursos Relacionados
Los siguientes recursos le brindarán más detalles sobre la implementación de la contención y los posibles beneficios de rendimiento:
- "La propiedad de
contain
CSS", documentos web de MDN - "Contención de CSS en Chrome 52", Google Developers
- “Módulo de contención CSS nivel 1”, recomendación del W3C
- “Introducción a la Contención CSS”, Manuel Rego Casasnovas