@supports: Navegadores y prefijos

publicado en la categoría CSS
La w3.org es la encargada de establecer los estándares para que los navegadores interpreten las páginas web pero estas recomendaciones se van incorporando lentamente y además, algunas de esas reglas se encuentran en proceso de estudio o son exclusivas de alguno de ellos.

Tendemos a creer que la tecnología web está estandariza, que todos los dispositivos entienden los mismos lenguajes y que todos los usuarios verán lo mismo cuando naveguen pero eso no es así en absoluto.

El CSS no es la excepción.

La w3.org es la encargada de establecer esos estándares pero quienes desarrollan páginas web se topan con tres inconvenientes. Por un lado, los navegadores van incorporando esas recomendaciones lentamente; además, muchas de esas reglas o propiedades se encuentran en proceso de estudio y para colmo, los navegadores proponen el uso de otras o insisten en crear sus propias reglas.

Es por eso que al no haber un estándar que respeten todos en un 100%, a veces se requiere que ciertas propiedades se definan anteponiéndoles un prefijo (vendor prefixes). En este momento, los más comunes son tres:

-moz- para navegadores basados en Gecko como Firefox
-webkit- para navegadores basados en Webkit como Chrome, Safari, Android y Opera
-ms- para Internet Explorer y Microsoft Edge

Cada uno de esos prefijos se aplica exclusivamente en un navegador y por lo tanto si queremos utilizar alguna de esas propiedad y que se aplicara lo más genéricamente posible, deberíamos escribirlos agregarlos a todos.

El orden en que las listamos carece de importancia pero siempre hay que tomar la precaución de agregar la propiedad sin prefijo al final de la regla.

Por ejemplo, aunque la propiedad appearance aún es experimental podría usarse en algunos navegadores de este modo:

	.demo {
		-moz-appearance: valor;
		-webkit-appearance: valor;
		appearance: valor;
	}

Es muy importante saber que la lista de propiedades que necesitan un prefijo cambia constantemente. Si miramos el código fuente de muchos sitios, veremos que están agregadas algunas que son innecesarias ya que los navegadores ya aceptan las propiedades estándar (border-radius, linear-gradient, box-shadow, etc). Además, tampoco parece recomendable utilizar prefijos para soportar navegadores obsoletos.

Existen muchas propiedades experimentales y la mayoría de ellas pueden ser utilizadas porque funcionarán correctamente pero, siempre es bueno preguntarse si deberíamos hacerlo o si existe alguna alternativa estandarizada y podemos prescindir de ellas.

Por otro lado, la guerra de mercados hace que ciertos navegadores pretendan imponer sus propias reglas y eso, sólo es posible si los desarrolladores juegan a su favor, olvidándose de la gente. Esto se ve muy claro cuando se recorren sitios donde se muestran supuestas soluciones a determinados problemas que utilizan propiedades que sólo funcionan en un navegador y cuando alguien osa preguntar qué hacer si se usa otro, responden que cambien de navegador o les cantan loas como si ellos fueran socios de esas empresas.

Si alguien tiene problemas con los prefijos y cómo usarlos, hay decenas de librerías de JavaScript que pueden ayudar a rescribir las reglas aunque, a mi juicio, la mayoría de ellas terminan agregando clases, ensuciando el código y enlenteciendo la carga de las páginas.

Si hablamos de propiedades experimentales, hay una que ya ha pasado esa etapa y está clasificada como candidate, es decir, casi está a punto de ser incluida en los estándares; se trata de @supports y por ahora funciona en los navegadores de escritorio más modernos pero no lo hace en los dispositivos móviles.

Lo que hace es asociar reglas con una condición y de esta manera, comprobar si están disponibles ciertas propiedades; por ejemplo, supongamos que quisiéramos utilizar la propiedad display con un valor flex en un elemento pero queremos evitar que ese elemento se muestre mal si el navegador no soporta ese valor; lo que deberíamos hacer es establecer una regla general alternativa y luego, establecer la regla de la cual dudamos, dentro de @supports:

.demo {
	display: block;
}
@supports (display:flex) {
	.demo {
		display: flex;
	}
}

Esta verificación también admite condiciones y para eso se usan operadores como and or y not; por ejemplo:

@supports (display:flex) and (transform: rotate(180deg) {
	.demo {
		display: flex;
		transform: rotate(180deg);
	}
}

De este modo podemos verificar cualquier propiedad incluso aquellas que incluyan prefijos.

En el ejemplo siguiente se verán cuadros en color verde si el navegador soporta determinadas propiedades con cierto valor, caso contrario, se verán de color balnco:

flex apperance -ms-input-placeholder perspective transition -webkit-touch-callout