Una guía para la compatibilidad con CSS en los navegadores
Publicado: 2022-03-10Nunca viviremos en un mundo donde todos los que ven nuestros sitios tengan un navegador y una versión de navegador idénticos, así como nunca viviremos en un mundo donde todos tengan el mismo tamaño de pantalla y resolución. Esto significa que lidiar con navegadores antiguos, o navegadores que no admiten algo que queremos usar, es parte del trabajo de un desarrollador web. Dicho esto, las cosas están mucho mejor ahora que en el pasado, y en este artículo, voy a echar un vistazo a los diferentes tipos de problemas de soporte del navegador que podemos encontrar. Voy a mostrarles algunas formas de lidiar con ellos, y también miraré las cosas que podrían venir pronto y que pueden ayudar.
¿Por qué tenemos estas diferencias?
Incluso en un mundo donde la mayoría de los navegadores están basados en Chromium, no todos esos navegadores ejecutan la misma versión de Chromium que Google Chrome. Esto significa que un navegador basado en Chromium, como Vivaldi, podría estar algunas versiones por detrás de Google Chrome.
Y, por supuesto, los usuarios no siempre actualizan rápidamente sus navegadores, aunque esa situación ha mejorado en los últimos años con la mayoría de los navegadores actualizándose silenciosamente.
También está la forma en que las nuevas características ingresan a los navegadores en primer lugar. No es el caso que las nuevas características para CSS sean diseñadas por el Grupo de Trabajo de CSS, y se transmita una especificación completa a los proveedores de navegadores con instrucciones para implementarla. Muy a menudo, solo cuando ocurre una implementación experimental, se pueden resolver todos los detalles más finos de la especificación. Por lo tanto, el desarrollo de funciones es un proceso iterativo y requiere que los navegadores implementen estas especificaciones en el desarrollo. Si bien la implementación ocurre en estos días con mayor frecuencia detrás de una bandera en el navegador o está disponible solo en una versión Nightly o de vista previa, una vez que un navegador tiene una función completa, es probable que la active para todos, incluso si ningún otro navegador aún tiene soporte.
Todo esto significa que, por mucho que nos guste, nunca existiremos en un mundo en el que las funciones estén mágicamente disponibles en todos los equipos de escritorio y teléfonos al mismo tiempo. Si eres un desarrollador web profesional, entonces tu trabajo es lidiar con ese hecho.
Errores frente a falta de soporte
Hay tres problemas a los que nos enfrentamos con respecto a la compatibilidad con los navegadores:
- Sin soporte de una característica
El primer problema (y el más fácil de tratar) es cuando un navegador no admite la función en absoluto. - Tratar con los "errores" del navegador
La segunda es cuando el navegador afirma admitir la función, pero lo hace de una manera diferente a la forma en que otros navegadores admiten la función. Tal problema es lo que tendemos a referirnos como un "error del navegador" porque el resultado final es un comportamiento inconsistente. - Soporte parcial de propiedades CSS
Este se está volviendo más común; una situación en la que un navegador admite una función, pero solo en un contexto.
Es útil entender con qué está lidiando cuando ve una diferencia entre los navegadores, así que echemos un vistazo a cada uno de estos problemas a la vez.
1. Sin soporte de una característica
Si usa una propiedad CSS o un valor que un navegador no entiende, el navegador lo ignorará. Esto es lo mismo si usa una función que no es compatible o inventa una función e intenta usarla. Si el navegador no entiende esa línea de CSS, simplemente la omite y continúa con lo siguiente que entiende.
Este principio de diseño de CSS significa que puede usar alegremente nuevas funciones, sabiendo que nada malo le sucederá a un navegador que no tenga soporte. Para algunos CSS, usados puramente como una mejora, eso es todo lo que necesita hacer. Use la función, asegúrese de que cuando esa función no esté disponible, la experiencia siga siendo buena, y eso es todo. Este enfoque es la idea básica detrás de la mejora progresiva, utilizando esta característica de la plataforma que permite el uso seguro de cosas nuevas en navegadores que no las entienden.
Si desea verificar si una función que está utilizando es compatible con los navegadores, puede consultar el sitio web Can I Use. Otro buen lugar para buscar información detallada de soporte es la página de cada propiedad CSS en MDN. Los datos de soporte del navegador tienden a ser muy detallados.
El CSS nuevo entiende el CSS antiguo
A medida que se desarrollan nuevas características de CSS, se tiene cuidado en términos de cómo interactúan con el CSS existente. Por ejemplo, en la especificación Grid y Flexbox, se detalla en términos de cómo display: grid
y display: flex
se ocupan de escenarios como cuando un elemento flotante se convierte en un elemento de cuadrícula, o un contenedor multicol se convierte en una cuadrícula. Esto significa que se ignoran ciertos comportamientos, lo que le ayuda a simplemente sobrescribir el CSS para el navegador no compatible. Estas anulaciones se detallan en la página de mejora progresiva y diseño de cuadrícula en MDN.
Detección de soporte con consultas de funciones
El método anterior solo funciona si el CSS que necesita usar no necesita otras propiedades para acompañarlo. Es posible que deba agregar propiedades adicionales a su CSS para navegadores más antiguos que luego también serían interpretados por los navegadores que admiten la función.
Un buen ejemplo de esto se puede encontrar al usar Grid Layout. Si bien un elemento flotante que se convierte en un elemento de cuadrícula pierde todo el comportamiento de flotación, es probable que si intenta crear una alternativa para un diseño de cuadrícula con flotación, habrá agregado anchos porcentuales y posiblemente márgenes a los elementos.
.grid > .item { width: 23%; margin: 0 1%; }
Estos anchos y márgenes seguirán aplicándose cuando el elemento flotante sea un elemento de cuadrícula. El ancho se convierte en un porcentaje de la pista de cuadrícula en lugar del ancho total del contenedor; entonces se aplicará cualquier margen, así como un espacio que haya especificado.
.grid > .item { width: 23%; margin: 0 1%; } .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; column-gap: 1%; }
Afortunadamente, hay una función integrada en CSS e implementada en los navegadores modernos que nos ayuda a lidiar con esta situación. Las consultas de características nos permiten preguntar directamente al navegador qué admiten y luego actuar en respuesta. Al igual que una consulta de medios, que prueba algunas propiedades del dispositivo o la pantalla, las consultas de funciones prueban la compatibilidad con una propiedad y un valor de CSS.
Prueba de apoyo
La prueba de soporte es el caso más simple, usamos @supports
y luego probamos una propiedad y valor de CSS. El contenido dentro de la consulta de funciones solo se ejecutará si el navegador responde con verdadero, es decir, admite la función.
Prueba sin soporte
Puede preguntarle al navegador si no es compatible con una función. En este caso, el código dentro de Feature Query solo se ejecutará si el navegador indica que no tiene soporte.
@supports not (display: grid) { .item { /* CSS from browsers which do not support grid layout */ } }
Prueba para varias cosas
Si necesita que se admita más de una propiedad, use and
.
@supports (display: grid) and (shape-outside: circle()){ .item { /* CSS from browsers which support grid and CSS shapes */ } }
Si necesitas soporte de una propiedad u otra, usa or
.
@supports (display: grid) or (display: flex){ .item { /* CSS from browsers which support grid or flexbox */ } }
Elegir una propiedad y un valor para probar
No necesita probar cada propiedad que desea usar, solo algo que indicaría soporte para las funciones que planea usar. Por lo tanto, si desea utilizar Grid Layout, puede probar display: grid
. En el futuro (y una vez que el soporte de subcuadrícula llegue a los navegadores), es posible que deba ser más específico y probar la funcionalidad de subcuadrícula. En ese caso, probaría grid-template-columns: subgrid
para obtener una respuesta verdadera solo de aquellos navegadores que habían implementado la compatibilidad con subgrid.
Si ahora volvemos a nuestro ejemplo de respaldo flotante, podemos ver cómo las consultas de características lo resolverán por nosotros. Lo que debemos hacer es consultar el navegador para averiguar si admite el diseño de cuadrícula. Si es así, podemos volver a establecer el ancho del elemento en auto
y el margen en 0
.
.grid > .item { width: 23%; margin: 0 1%; } @supports(display: grid) { .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; column-gap: 1%; } .grid > .item { width: auto; margin: 0; } }
Tenga en cuenta que si bien he incluido todo el código de cuadrícula dentro de mi consulta de características, no es necesario. Si un navegador no entendiera las propiedades de la cuadrícula, las ignoraría para que pudieran estar fuera de la consulta de funciones de manera segura. Las cosas que deben estar dentro de una consulta de características en este ejemplo son las propiedades de margen y ancho, ya que son necesarias para el código del navegador anterior, pero también se aplicarían en los navegadores compatibles.
Abraza la cascada
Una forma muy sencilla de ofrecer alternativas es utilizar el hecho de que los navegadores ignoran el CSS que no entienden, y el hecho de que donde todo lo demás tiene la misma especificidad, el orden de origen se tiene en cuenta en términos de qué CSS se aplica a un elemento. .
Primero escribe su CSS para los navegadores que no admiten la función. Luego pruebe la compatibilidad con la propiedad que desea usar, si el navegador confirma que tiene compatibilidad, sobrescriba el código de respaldo con su nuevo código.
Este es más o menos el mismo procedimiento que puede usar cuando usa consultas de medios para un diseño receptivo, siguiendo un enfoque móvil primero. En ese enfoque, comienza con su diseño para pantallas más pequeñas, luego agrega o sobrescribe cosas para las más grandes a medida que avanza a través de sus puntos de interrupción.
La forma de trabajo anterior significa que no necesita preocuparse por los navegadores que no admiten Consultas de características. Como puede ver en Can I Use , las Consultas de características tienen un soporte realmente bueno. Los navegadores destacados que no los admiten son ninguna versión de Internet Explorer.
Sin embargo, es probable que la nueva función que desea utilizar tampoco sea compatible con IE. Por lo tanto, en la actualidad, casi siempre comenzará escribiendo CSS para navegadores sin soporte, luego probará con una consulta de funciones. Esta consulta de características debería probar la compatibilidad.
- Los navegadores que admiten Consultas de características devolverán verdadero si tienen soporte, por lo que se utilizará el código dentro de la consulta, sobrescribiendo el código de los navegadores más antiguos.
- Si el navegador admite Consultas de funciones pero no la función que se está probando, devolverá falso. El código dentro de la consulta de funciones se ignorará.
- Si el navegador no es compatible con las Consultas de funciones, se ignorará todo lo que se encuentre dentro del bloque Consulta de funciones, lo que significa que un navegador como IE11 usará el código de su antiguo navegador, ¡lo cual es muy probable que sea exactamente lo que desea!
2. Tratar con los "errores" del navegador
Afortunadamente, el segundo problema de soporte del navegador se está volviendo menos común. Si lee "Lo que deseamos" (publicado a fines del año pasado), puede hacer un pequeño recorrido por algunos de los errores de navegador más desconcertantes del pasado. Dicho esto, cualquier software puede tener errores, los navegadores no son una excepción. Y, si a eso le sumamos el hecho de que, debido a la naturaleza circular de la implementación de la especificación, a veces un navegador implementó algo y luego la especificación cambió, por lo que ahora necesitan emitir una actualización. Hasta que se envíe esa actualización, es posible que nos encontremos en una situación en la que los navegadores hagan algo diferente entre sí.
Las consultas de funciones no pueden ayudarnos si el navegador informa que admite algo que no lo admite. No existe un modo por el cual el navegador pueda decir: " Sí, pero probablemente no le gustará ". Cuando aparece un error de interoperabilidad real, es en estas situaciones en las que es posible que deba ser un poco más creativo.
Si cree que está viendo un error, lo primero que debe hacer es confirmarlo. A veces, cuando creemos que vemos un comportamiento defectuoso y los navegadores hacen cosas diferentes, la culpa es nuestra. Tal vez hemos utilizado alguna sintaxis no válida, o estamos tratando de diseñar HTML con formato incorrecto. En esos casos, el navegador intentará hacer algo; sin embargo, debido a que no está utilizando los idiomas tal como fueron diseñados, cada navegador puede funcionar de manera diferente. Una verificación rápida de que su HTML y CSS son válidos es un excelente primer paso.
En ese momento, probablemente haría una búsqueda rápida y vería si mi problema ya se entendía ampliamente. Hay algunos repositorios de problemas conocidos, por ejemplo, Flexbugs y Gridbugs. Sin embargo, incluso unas pocas palabras clave bien elegidas pueden mostrar publicaciones o artículos de desbordamiento de pila que cubren el tema y pueden brindarle una solución.
Pero digamos que realmente no sabe qué está causando el error, lo que hace que sea bastante difícil buscar una solución. Entonces, el siguiente paso es crear un caso de prueba reducido de su problema, es decir, eliminar todo lo irrelevante para ayudarlo a identificar exactamente qué desencadena el error. Si cree que tiene un error de CSS, ¿puede eliminar JavaScript o recrear el mismo estilo fuera de un marco? A menudo uso CodePen para crear un caso de prueba reducido de algo que estoy viendo; esto tiene la ventaja adicional de darme el código de una manera que puedo compartir fácilmente con alguien más si necesito preguntar al respecto.
La mayoría de las veces, una vez que haya aislado el problema, es posible pensar en una forma alternativa de lograr el resultado deseado. Descubrirá que a otra persona se le ocurrió una solución ingeniosa, o puede publicar en algún lugar para pedir sugerencias.
Dicho esto, si cree que tiene un error en el navegador y no puede encontrar a nadie más que hable sobre el mismo problema, es muy posible que haya encontrado algo nuevo que deba informar. Con todo el nuevo CSS que ha llegado recientemente, a veces pueden surgir problemas cuando las personas comienzan a usar cosas en combinación con otras partes de CSS.
Consulte esta publicación de Lea Verou sobre cómo informar tales problemas, “¡Ayuda a la comunidad! ¡Informe de errores del navegador!”. El artículo también tiene excelentes consejos para crear un caso de prueba reducido.
3. Soporte parcial de propiedades CSS
El tercer tipo de problema se ha vuelto más común debido a la forma en que se diseñan las especificaciones CSS modernas. Si pensamos en Grid Layout y Flexbox, estas especificaciones usan las propiedades y los valores en Box Alignment Level 3, para realizar la alineación. Por lo tanto, las propiedades como align-items
, justify-content
y column-gap
se especifican para usarse tanto en Grid como en Flexbox, así como en otros métodos de diseño.
Sin embargo, en el momento de escribir este artículo, las propiedades de gap
funcionan en Grid Layout en todos los navegadores compatibles con grid, y column-gap
funciona en Multicol; sin embargo, solo Firefox ha implementado estas propiedades para Flexbox.
Si tuviera que usar márgenes para crear un respaldo para Flexbox, luego probar el espacio entre column-gap
y eliminar los márgenes, mis cuadros no tendrán espacio entre ellos en los navegadores que admiten el espacio entre column-gap
en Grid o multicol, por lo que mi espacio de respaldo será remoto.
@supports(column-gap: 20px) { .flex { margin: 0; /* almost everything supports column-gap so this will always remove the margins, even if we do not have gap support in flexbox. */ } }
Esta es una limitación actual de las consultas de características. No tenemos una forma de probar la compatibilidad de una función con otra función. En la situación anterior, lo que quiero preguntarle al navegador es: "¿Tiene soporte para espacio entre columnas en Flexbox?" De esta manera, puedo obtener una respuesta negativa para poder usar mi respaldo.
Hay un problema similar con las propiedades de fragmentación de CSS break-before
, break-after
y break-inside
. Como estos tienen un mejor soporte cuando se imprime la página, los navegadores a menudo reclamarán soporte. Sin embargo, si está probando la compatibilidad con multicol, obtiene lo que parecen ser falsos positivos. He planteado un problema en el Grupo de trabajo de CSS para este problema, sin embargo, no es un problema sencillo de resolver. Si tiene ideas, agréguelas allí.
Prueba de soporte de selector
Actualmente, las consultas de características solo pueden probar propiedades y valores de CSS. Otra cosa que nos gustaría probar es la compatibilidad con los selectores más nuevos, como los del nivel 4 de la especificación de selectores. Hay una nota explicativa y también una implementación detrás de una bandera en Firefox Nightly de una nueva función para consultas de funciones que logrará esto.
Si visita about:config
en Firefox y habilita el indicador layout.css.supports-selector.enabled
, puede probar si se admiten varios selectores. Actualmente, la sintaxis es muy sencilla, por ejemplo, para probar el selector : :has
:
@supports selector(:has){ .item { /* CSS for support of :has */ } }
Esta es una especificación en desarrollo, sin embargo, puede ver cómo se están agregando funciones para ayudarnos a manejar los problemas siempre presentes de la compatibilidad del navegador mientras hablamos.
Otras lecturas
Puede parecer frustrante cuando desea usar una función y descubre que no es compatible con un navegador principal, o si las cosas parecen comportarse de manera diferente. He reunido algunas lecturas prácticas adicionales que podrían ayudar.
- "Uso de CSS Grid: compatibilidad con navegadores sin Grid" Opciones para manejar navegadores antiguos y CSS Grid
- Página de referencia de MDN "Consultas de funciones" para Consultas de funciones
- “CSS Grid and Progressive Enhancement” Guía de MDN para la mejora progresiva de Grid
- Guía de MDN "Compatibilidad con versiones anteriores de Flexbox" para el soporte de Flexbox que incluye detalles de implementaciones prefijadas más antiguas
- "Biblioteca de patrones primero" Cómo administrar el código de respaldo usando una biblioteca de patrones