Cómo funciona @supports

Índice
  1. Un caso de uso clásico
  2. Hay una lógica de “no” en los bloques @supports, pero eso no significa que deba usarse siempre
  3. Es probable que @supports sea más útil con el tiempo.
  4. Cuando @supports no hace nada útil
  5. Hay extensiones de navegador para jugar con @supports
  6. Más casos de uso del mundo real para @supports
  7. Lógica en @supports
  8. Variante de JavaScript
  9. Prueba de selectores
  10. ¿Tu?

CSS tiene una característica interesante que nos permite probar si el navegador admite una propiedad particular o una combinación de propiedad:valor antes de aplicar un bloque de estilos, como cómo @mediacoincide una consulta cuando, por ejemplo, el ancho de la ventana del navegador es más estrecho que un tamaño especificado. y luego el CSS que contiene entra en vigor. Del mismo modo, el CSS dentro de esta característica entrará en vigor cuando el valor por propiedad se esté probando sea compatible con el navegador actual. Esa característica se llama @supportsy se ve así:

@supports (display: grid) {  .main {    display: grid;  }}

¿Por qué? Bueno, eso es un poco complicado. Personalmente, creo que no lo necesito con tanta regularidad. CSS tiene mecanismos de respaldo naturales, de modo que si el navegador no comprende una combinación de propiedad: valor, la ignorará y usará algo declarado antes si hay algo, gracias a la cascada. A veces, esto se puede utilizar para solucionar problemas y el resultado final es un poco menos detallado. Ciertamente no soy del tipo que tiene que ser lo mismo en todos los navegadores, pero tampoco soy del tipo que escribe elaboradas alternativas para acercarse. Generalmente prefiero una situación en la que una falla natural de una propiedad: el valor no hace nada drástico para destruir la funcionalidad.

Dicho esto, @supportssin duda tiene casos de uso. Y, como descubrí mientras escribía esta publicación, muchas personas lo usan en muchas situaciones interesantes.

Un caso de uso clásico

El ejemplo que utilicé en la introducción es un ejemplo clásico que verás utilizado en muchos escritos sobre este tema. Aquí está un poco más desarrollado:

/* We're gonna write a fallback up here in a minute */@supports (display: grid) {  .photo-layout {    display: grid;    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));    grid-gap: 2rem;  }}

¡Buena cuadrícula! La repetición y el autocompletado de columnas es una característica interesante de la cuadrícula CSS. Pero, por supuesto, hay navegadores que no soportan grid, o no soportan todas las características específicas que estoy usando arriba.

Por ejemplo, iOS incluyó compatibilidad con CSS Grid en la versión 10.2, pero iOS tiene compatibilidad con FlexBox desde la versión 7. Hay una brecha considerable de personas con dispositivos iOS más antiguos que admiten FlexBox pero no Grid. Estoy seguro de que hay más brechas de ejemplo como esa, pero probablemente entiendas la idea.

Estaba ejecutando una versión anterior de Mobile Safari y muchos, muchos, muchos, muchos sitios estaban completamente rotos y usaban grid.

Estoy esperando un año más o menos antes de meterme con eso.

– David Wells (@DavidWells) 6 de febrero de 2019

Puede ser aceptable dejar que la alternativa sea nada, dependiendo de los requisitos. Por ejemplo, elementos a nivel de bloque apilados verticalmente en lugar de un diseño de cuadrícula de varias columnas. Eso suele estar bien para mí. Pero digamos que no está bien, como una galería de fotos o algo que absolutamente necesita tener una estructura básica similar a una cuadrícula. En ese caso, comenzar con flexbox como predeterminado y usarlo @supportspara aplicar funciones de cuadrícula donde sean compatibles puede funcionar mejor…

.photo-layout {  display: flex;  flex-wrap: wrap;   div {    flex: 200px;    margin: 1rem;  }}@supports (display: grid) {  .photo-layout {    display: grid;    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));    grid-gap: 2rem;     div {      margin: 0;    }  }}

El “retroceso” es el código fuera del @supportsbloque (las propiedades encima del bloque en el ejemplo anterior), y el código de la cuadrícula está dentro o después. El @supportsbloqueo no cambia ninguna especificidad, por lo que necesitamos el orden de origen para ayudar a garantizar que las anulaciones funcionen.

Observe que tuve que restablecer el margen de los divs dentro del @supportsbloque. Ese es el tipo de cosas que encuentro un poco molestas. Hay suficientes cruces entre los dos escenarios que requieren ser muy conscientes de cómo se impactan entre sí.

¿Eso no te hace desear que se pudiera separar de manera completamente lógica?

Hay una lógica de “no” en los bloques @supports, pero eso no significa que deba usarse siempre

Jen Simmons puso este ejemplo en un artículo llamado Uso de consultas de funciones en CSS hace unos años:

/* Considered a BAD PRACTICE, at least if you're supporting IE 11 and iOS 8 and older */@supports not (display: grid) {   /* Isolated code for non-support of grid */}@supports (display: grid) {   /* Isolated code for support of grid */}

Observar al notoperador en el primer bloque. Se trata de buscar navegadores que no admiten grid para poder aplicar ciertos estilos a esos navegadores. La razón por la que este enfoque se considera una mala práctica es que se debe considerar la compatibilidad del navegador con @supports. . Eso es lo que hace que esto sea tan complicado.

Es muy atractivo escribir código en @supportsbloques lógicamente separados como ese porque entonces se comienza desde cero cada vez y no es necesario anular valores anteriores y lidiar con esos cambios de mentalidad lógicos. Pero volvamos a la misma situación de iOS que consideramos antes… @supportsenviado en iOS en la versión 9 (justo entre el momento en que flexbox se envió en iOS 7 y el grid en iOS 10.2). Eso significa que cualquier código de reserva de Flexbox en un @supportsbloque que use el notoperador para verificar la (display: grid) {}compatibilidad no funcionará ni en iOS 7 ni en 8, lo que significa que la reserva ahora necesita una reserva para que no funcione en navegadores que de otro modo tendría. ¡Uf!

La razón principal para hacerlo @supportses tener en cuenta implementaciones muy diferentes de algo dependiendo del soporte de características, donde resulta más fácil razonar y distinguir entre esas implementaciones si los bloques de código están separados.

Probablemente lleguemos a un punto en el que podamos usar bloques mutuamente excluyentes como ese sin preocupaciones. Hablando de que...

Es probable que @supports sea más útil con el tiempo.

Una vez que @supportssea compatible con todos los navegadores que necesita, entonces es bueno comenzar a usarlo de manera más agresiva y sin tener que tener en cuenta la complicación de considerar si @supportses compatible. Aquí está la tabla de soporte al respecto:

Estos datos de soporte del navegador son de Caniuse, que tiene más detalles. Un número indica que el navegador admite la función en esa versión y superiores.

Escritorio

Cromo Firefox ES DECIR Borde Safari
28 22 No 12 9

Móvil/Tableta

Android Cromo Android Firefox Androide Safari en iOS
125 126 4.4 9.0-9.2

Básicamente, IE 11 y cualquier dispositivo iOS atascado en iOS 8 son los puntos débiles. Si sus requisitos ya los han superado, entonces puede usarlos @supportsmás libremente.

La ironía es que no se han enviado muchas funciones CSS que tengan @supportscasos de uso grandes y claros, ¡pero hay algunas! Aparentemente, es posible probar cosas nuevas y sofisticadas como Houdini:

Utilizándolo en el sitio web de mi boda para comprobar el soporte de Houdini

– Sam Richard (@Snugug) 6 de febrero de 2019

(No estoy completamente seguro de qué pondrías en el @supportsbloque para hacer eso. ¿Alguien más ha hecho esto?)

Cuando @supports no hace nada útil

He visto una buena cantidad de @supportsusos en la naturaleza donde el resultado final es exactamente como sería sin usar. Por ejemplo…

@supports (transform: rotate(5deg)) {  .avatar {    transform: rotate(5deg);  }}

En cierto nivel, eso tiene perfecto sentido lógico. Si se admiten transformaciones, úselas. Pero es innecesario si no sucede nada diferente en un escenario sin soporte. En este caso, la transformación puede fallar sin el @supportsbloque y el resultado es el mismo.

Aquí hay otro ejemplo de esa sacudida.

Hay extensiones de navegador para jugar con @supports

¡Hay dos de ellos!

  • Administrador de consultas de funciones por Ire Aderinokun
  • Extensión de alternancia de funciones CSS de Keith Clark

Ambos se centran en la idea de que podemos escribir @supportsbloques en CSS y luego activarlos y desactivarlos como si estuviéramos viendo una representación del código en un navegador que admite o no esa característica.

Aquí hay un video de la herramienta de Keith aplicada al escenario usando una cuadrícula con un respaldo de flexbox:

La herramienta de Ire, sobre la que escribió en el artículo Creación de la extensión DevTools del Administrador de consultas de funciones, tiene un enfoque ligeramente diferente en el sentido de que muestra las consultas de funciones que realmente escribieron en su CSS y proporciona opciones para activarlas. y desactivarlas. Sin embargo, no creo que funcione a través de iframes, así que abre el modo de depuración para usarlo en CodePen.

Más casos de uso del mundo real para @supports

Aquí hay uno de Erik Vorhes. Aquí estamos diseñando algunas casillas de verificación y botones de opción personalizados, pero los envuelve todo en un @supportsbloque. Ninguno de los estilos se aplica a menos que el bloque pase la verificación de soporte.

@supports (transform: rotate(1turn)) and (opacity: 0) {  /* all the styling for Erik's custom checkboxes and radio buttons */}

Aquí hay varios más con los que me encontró:

  • Joe Wright y Tiago Nunes mencionaron que lo usan para position: sticky;. ¡Me encantaría ver una demostración aquí! Es decir, cuando buscas position: sticky;, pero luego tienes que hacer algo diferente además de dejar que falle en un navegador que no lo soporta.
  • Keith Grant y Matthias Ott mencionan su uso para object-fit: contain;. Matthias tiene una demostración en la que se utilizan trucos de posicionamiento para hacer que una imagen llene un contenedor, lo que luego se hace más fácil y mejor a través de esa propiedad cuando está disponible.
  • Ryan Filler menciona usarlo para mix-blend-mode. Su ejemplo establece más opacidad en un elemento, pero si mix-blend-modees compatible, usa un poco menos y esa propiedad que puede tener el efecto de ver a través de un elemento por sí sola.
  • .thing {  opacity: 0.5;}@supports (mix-blend-mode: multiply) {  .thing {    mix-blend-mode: multiply;    opacity: 0.75;  }}
  • Rik Schennink mencionó la backdrop-filterpropiedad. Dice que “cuando es compatible, la opacidad del color de fondo a menudo necesita algunos ajustes”.
  • Nour Saud mencionó que se puede utilizar para detectar Edge a través de una propiedad específica con el prefijo del proveedor: @supports (-ms-ime-align:auto) { }.
  • Amber Weinberg mencionó usarlo clip-pathporque ajustar el tamaño o el relleno de un elemento se adaptará cuando el recorte no esté disponible.
  • Ralph Holzmann mencionó usarlo para probar esas cosas de “muesca” (variables ambientales).
  • Stacy Kvernmo mencionó su uso para la variedad de propiedades necesarias para los caracteres de discapacidad. Jen Simmons también menciona este caso de uso en su artículo. Hay una initial-letterpropiedad CSS que es bastante fantástica para las mayúsculas, pero se usa junto con otras propiedades que quizás no quieras aplicar en absoluto si initial-letterno son compatibles (o si hay un escenario alternativo totalmente diferente).

Aquí hay un bono de Nick Colley que no es @supports, ¡ @mediasino! El espíritu es el mismo. Puede evitar ese estado de “ataque” en dispositivos táctiles como este:

@media (hover: hover) {  a:hover {    background: yellow;  }}

Lógica en @supports

Básico:

@supports (initial-letter: 4) {}

No:

@supports not (initial-letter: 4) {}

Y:

@supports (initial-letter: 4) and (transform: scale(2)) {}

O:

@supports (initial-letter: 4) or (-webkit-initial-letter: 4) {}

Combinaciones:

@supports ((display: -webkit-flex) or          (display: -moz-flex) or          (display: flex)) and (-webkit-appearance: caret) {}

Variante de JavaScript

JavaScript tiene una API para esto. Para probar si existe…

if (window.CSS  window.CSS.supports) {  // Apparently old Opera had a weird implementation, so you could also do:  // !!((window.CSS  window.CSS.supports) || window.supportsCSS || false)}

Para usarlo, pásele la propiedad en un parámetro y el valor en otro:

const supportsGrid = CSS.supports("display", "grid");

…o ponerlo todo en una cadena reflejando la sintaxis CSS:

const supportsGrid = CSS.supports("(display: grid)");

Prueba de selectores

Al momento de escribir este artículo, solo Firefox admite este tipo de pruebas (detrás de un indicador experimental), pero hay una manera de probar la compatibilidad de selectores con @supports. Demostración de MDN:

@supports selector(A  B) {}

¿Tu?

Por supuesto, nos encantaría ver bolígrafos de @supportscasos de uso en los comentarios. ¡Así que compártelos!

SUSCRÍBETE A NUESTRO BOLETÍN 
No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir

Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion