Consultas de elementos y cómo puede usarlas hoy

Publicado: 2022-03-10
Resumen rápido ↬ Durante algún tiempo, nos hemos topado con los límites de lo que CSS puede hacer . Aquellos que crean diseños receptivos admitirán libremente las frustraciones y las deficiencias de CSS que nos obligan a buscar preprocesadores, complementos y otras herramientas de CSS para ayudarnos a escribir los estilos que no podemos escribir solo con CSS. Aún así, nos encontramos con limitaciones con lo que las herramientas actuales nos ayudan a lograr.

Piensa por un momento en una estructura física. Si está construyendo un edificio grande con material débil, se requiere una gran cantidad de apoyo externo para mantenerlo unido, y las cosas deben construirse en exceso para que se mantengan sólidas. Cuando está creando un sitio web a partir de HTML, CSS y JavaScript, este soporte externo puede verse como marcos, complementos, preprocesadores, transpiladores, herramientas de edición, administradores de paquetes y procesos de construcción.

¡Más después del salto! Continúe leyendo a continuación ↓

En lugar de agregar otro complemento a la parte superior de la pila, me preguntaba si, al extender uno de los lenguajes principales, CSS , podríamos fortalecer el material del que se construyen los sitios web, desarrollando sitios web mejores y más fuertes que requieren menos herramientas y soporte externo. para construir.

El estado actual de las consultas de elementos

Con herramientas como los preprocesadores de CSS, escribimos CSS de forma abreviada, para luego expandirlo en su forma completa (antes de verlo en un navegador). Los complementos pueden operar en la página junto con los elementos a los que afectan, pero para aplicar estilos, escriben estilos CSS directamente en HTML o alternan nombres de clase que aplican diferentes reglas CSS. En ambos casos, necesitamos escribir o generar el CSS que necesitaremos antes de que la página realmente se cargue.

El problema

El problema con este método es que incluso los mejores complementos a menudo requieren personalización y configuración en cada diseño que utilice. Además, cuando JavaScript escribe estilos para usted, puede ser difícil mantener juntos la lógica basada en complementos y los estilos CSS al refactorizar o reutilizar el código.

Otro problema con los preprocesadores es que cualquier error escrito en forma abreviada se convierte rápidamente en un lío mucho mayor una vez que el CSS se expande en su forma completa. Cuando usamos complementos, agregamos muchos puntos potenciales de falla. Es posible que estemos usando múltiples complementos para lograr un puñado de cosas diferentes que podrían ser innecesarias si CSS fuera un poco más poderoso. Esto crea una carga adicional para que los desarrolladores la mantengan, para que los navegadores la rendericen y para que los usuarios la descarguen.

¿Hay alguna esperanza para el futuro del desarrollo web?

En 2013, Tyson Matanich escribió un artículo titulado "Las consultas de medios no son la respuesta: Polyfill de consulta de elementos", que introdujo el concepto de consultas de elementos a una gran audiencia. Inició una discusión sobre cómo se podrían construir complementos y polyfills para sortear las deficiencias de CSS.

Desde entonces, mientras esperamos que avancen las funciones de CSS, se han lanzado una serie de complementos que permiten a los desarrolladores utilizar consultas de elementos de diferentes maneras.

¿Qué son las consultas de elementos?

Las consultas de elementos son como las consultas de medios, excepto que sus reglas se aplican a las propiedades de los elementos reales, en lugar de las de la ventana gráfica del navegador.

Cómo surgió EQCSS

A fines de 2013, me encontré trabajando en la interfaz de una aplicación web de Ruby on Rails. La aplicación necesitaba mostrar información detallada a los usuarios, y el objetivo era crear una interfaz receptiva que funcionara igual de bien en teléfonos, tabletas y navegadores de escritorio. Esto planteó algunos desafíos, uno de los cuales era que gran parte del contenido importante que se mostraba se mostraba mejor en tablas; sí, elementos de table reales (para mostrar transacciones financieras, registros deportivos, etc.).

El proyecto EQCSS surgió como resultado de una investigación sobre consultas de medios de elementos. Ahora, finalmente se lanzó y puede usarlo hoy. Consulta las demostraciones.

Creé estilos receptivos usando consultas de medios que mostraban el elemento de la table correctamente para navegadores de diferentes tamaños. Pero tan pronto como se mostraba una de esas tablas receptivas en una plantilla que contenía una barra lateral, de repente todos mis puntos de interrupción receptivos se convertían en puntos de interrupción receptivos. Simplemente no tuvieron en cuenta la barra lateral de 200 píxeles de ancho, lo que provocó que las cosas se superpusieran y aparecieran rotas.

Otro obstáculo: los nombres de usuario variaban en longitud de 3 a 20 caracteres, y me encontré deseando poder ajustar automáticamente el tamaño de fuente de cada nombre de usuario según la cantidad de caracteres que contenía. Necesitaba poner cada nombre de usuario en la barra lateral, y era complicado elegir un tamaño de fuente lo suficientemente pequeño para que cupiera un nombre de usuario de 20 caracteres pero lo suficientemente grande para que el espectador viera un nombre de usuario de 3 caracteres.

Para solucionar problemas como estos, a menudo me encontraba copiando consultas de medios completas, duplicando grandes secciones de mi base de código, simplemente porque necesitaba una forma más inteligente de aplicar los estilos receptivos en cada diseño. Confié en JavaScript como otra solución improvisada, escribiendo muchas funciones casi idénticas que vigilarían una página y aplicarían estilos en lugares donde CSS no podía llegar. Después de un tiempo, la carga adicional de todo este código duplicado comenzó a agobiar la base del código y dificultó la realización de cambios.

Sabía que tenía que haber una mejor solución y, después de un tiempo, comencé a pensar: no necesito consultas de medios, ¡lo que necesito son consultas de elementos!

Investigación y desarrollo

A lo largo de 2014, comencé a experimentar con diferentes formas de informar a CSS sobre las propiedades de los elementos tal como aparecían en la página, para poder aplicar mejores estilos. Esperaba descubrir un enfoque que me permitiera escribir estilos que combinaran la belleza de CSS con el poder de JavaScript.

Algunos enfoques abandonados a los que me rendí incluyen agregar atributos a las etiquetas HTML para agregar soporte receptivo e intentar encontrar formas de incrustar bloques completos de código CSS dentro de declaraciones if basadas en JavaScript para producir algún tipo de monstruo de Frankenstein parcheado desde JavaScript. y CSS.

Pero en lugar de facilitar las cosas, todos mis enfoques fallidos tenían una cosa en común: ¡añadían más trabajo! Sabía que la solución correcta simplificaría y reduciría el trabajo que hay que hacer, así que seguí buscando. A través de estos experimentos, terminé con una idea refinada del tipo de sintaxis que sería necesaria para que las consultas de elementos funcionaran bien.

Como se mencionó, para un sitio web construido a partir de HTML, CSS y JavaScript, el soporte externo viene en forma de marcos, complementos, preprocesadores, transpiladores, herramientas de edición, administradores de paquetes y procesos de construcción. En lugar de agregar otro complemento a la parte superior de la pila, me preguntaba si, al extender uno de los lenguajes centrales, CSS, podríamos fortalecer el material con el que se construyen los sitios web, creando sitios web mejores y más fuertes que requieren menos apoyo externo y herramientas para construir.

El nacimiento de una sintaxis

A finales de 2014, equipado con una mejor visión de la sintaxis necesaria, me puse en contacto con Maxime Euziere, un golfista fenomenal del código JavaScript y le pedí su opinión sobre la posibilidad de extender CSS usando JavaScript en el navegador en tiempo de ejecución. ¡No solo me informó que es posible, sino que se ofreció a ayudarme a hacerlo! Llamamos a la sintaxis EQCSS, abreviatura de "element query CSS". El nombre también es un guiño a la palabra "exceso", porque todo lo que hace excede lo que CSS puede hacer.

La necesidad

Mi requisito para la sintaxis era que fuera lo más parecido posible a CSS , tan parecido que los resaltadores de sintaxis se dejarían engañar pensando que era CSS estándar. Entonces, tracé la sintaxis de CSS para las consultas de elementos que tenían sentido: el tipo de sintaxis que sorprende a la gente aún no existe.

Sabía que si íbamos a ampliar la compatibilidad del navegador con CSS mediante JavaScript, el complemento tendría que ser lo más ligero y sencillo posible para realizar el trabajo, lo que descartaba el uso de bibliotecas como jQuery para crear el complemento. Necesitaba una biblioteca de JavaScript puro que agregara las funciones que quiero en el futuro a los navegadores que tengo que admitir hoy.

En este momento, la discusión en la comunidad de CSS se centra en las reglas @ personalizadas, y hablar sobre las consultas de elementos aún es preliminar. Es probable que aún nos falten años para cualquier especificación oficial de CSS para funciones como esta, e incluso después de una especificación, aún tendremos que esperar a que el navegador admita lo suficiente antes de poder usar esas funciones en los sitios web.

Esperar a que se agreguen estas características a CSS no tiene sentido cuando necesitamos esta funcionalidad para crear y reparar sitios web hoy.

El resultado

El resultado de esta investigación ha sido la creación de una sintaxis que incluye un nuevo conjunto de condiciones de respuesta avanzadas, estilos de alcance y nuevos selectores para elementos de destino, así como una biblioteca de JavaScript puro denominada EQCSS.js. Además, se ha proporcionado soporte para Internet Explorer (IE) 8 en un polyfill externo opcional. Tanto el complemento como el polyfill se han lanzado bajo la licencia MIT y son gratuitos para que todos los usen.

Casos de uso para consultas de elementos

Desarrolladores de complementos

Al crear componentes y widgets de la interfaz de usuario, los desarrolladores a menudo se ven limitados por las consultas de los medios. A menudo tenemos que elegir entre crear muchos diseños diferentes que la persona que usa el complemento puede configurar y simplificar la interfaz hasta el punto de que puede crear una solución única para la mayoría.

Pero cuando diseñamos complementos e interfaces con consultas de elementos, podemos escribir fácilmente estilos receptivos que cubran todas las situaciones que anticipamos, haciéndolos realmente a prueba de balas, sin importar qué contenido coloque el usuario o dónde aparezca el complemento. Supongamos que pudiéramos diseñar un widget con diseños que van desde 150 a 2000 píxeles de ancho. Entonces, no importa dónde se muestre ese widget en un sitio web, siempre se verá genial.

Constructores de plantillas

Cuando crea un prototipo de un sitio web, es común reorganizar los elementos de diseño en la página y pensar en el diseño como una colección de componentes modulares. Si ha escrito consultas de medios CSS, a veces esto puede ser un caso de optimización prematura . Al diseñar con consultas de elementos, mantiene las condiciones de respuesta independientes del diseño, lo que le brinda mucha más flexibilidad para mover las cosas sin tener que volver a trabajar tanto en los estilos.

Las cosas que he encontrado especialmente útiles para diseñar o simular usando consultas de elementos incluyen:

  • barras de navegación,
  • modales,
  • formularios de registro e inicio de sesión,
  • pies de página,
  • tablas de precios,
  • páginas de destino,
  • mesas,
  • cajas de pestañas,
  • acordeones,
  • widgets de la barra lateral,
  • reproductores multimedia,
  • secciones testimoniales.

Cualquier elemento de diseño puede tener un "ámbito" y trasladarse a cualquier lugar: página a página o sitio web a sitio web.

Soporte de dispositivos

Uno de los problemas a los que se enfrenta cuando admite la web en dispositivos móviles es la abundancia de hardware. El mercado de dispositivos está más fragmentado que nunca y todos los días aparecen nuevos dispositivos. Ya no podemos mantener una lista de los navegadores y dispositivos que admitimos, por lo que es crucial saber que un diseño funciona en todas partes, incluso en dispositivos que aún no se han lanzado.

Mediante el uso de consultas de elementos, puede diseñar sitios web de una mejor manera y eliminar algunas de estas diferencias entre navegadores.

Muchos artículos escritos recientemente sobre la necesidad de consultas de elementos ilustran muchos de los casos de uso en detalle. Entonces, ¡sigamos adelante con cómo usarlos!

Cómo escribir consultas de elementos

Comenzar con EQCSS es fácil. Todo lo que necesita para comenzar a usar la sintaxis EQCSS es incluir JavaScript en algún lugar de su HTML.

Descargando EQCSS.js

Si desea clonar el proyecto EQCSS de GitHub, puede escribir:

 git clone https://github.com/eqcss/eqcss.git

Si usa npm, puede agregar EQCSS a su proyecto con el siguiente comando:

 npm install eqcss

Agregar EQCSS.js a su HTML

Una vez que haya descargado EQCSS, puede agregarlo a su HTML con una etiqueta de secuencia de script :

 <script src="EQCSS.js"></script>

Este archivo ( EQCSS.js ) incluye soporte para todos los navegadores actuales, incluido IE 9 y versiones posteriores. Para soportar IE 8, tendríamos que haber usado muchos otros polyfills. Tenga en cuenta que IE 8 ni siquiera es compatible con las consultas de medios CSS sin un relleno polivalente, por lo que es bastante sorprendente que podamos hacer que las consultas de elementos también funcionen allí. Para incluir compatibilidad con IE 8 para un sitio web que usa EQCSS, agregue el siguiente enlace antes de su enlace al complemento principal:

 <!‐‐[if lt IE 9]><script src="EQCSS‐polyfills.js"></script><![endif]‐‐>

Ejecutando EQCSS

De forma predeterminada, el complemento EQCSS calculará cualquier estilo que encuentre una vez que se cargue la página, y también cada vez que detecte que se está cambiando el tamaño del navegador, de forma similar a las consultas de medios. También puede llamar a EQCSS.apply() manualmente con JavaScript para volver a calcular los estilos en cualquier momento, lo que puede ser útil una vez que se haya actualizado el contenido en la página.

Elemento de escritura Consulta CSS

El complemento EQCSS.js puede leer estilos en un par de formas diferentes. Puede incluir EQCSS en cualquier etiqueta de style en una página HTML. También puede escribir EQCSS en una hoja de estilo CSS externa.

Si desea mantener su código basado en EQCSS separado de su CSS, puede cargar la sintaxis de EQCSS utilizando la etiqueta de secuencia de script con el tipo establecido en text/eqcss . Puede agregar estilos en línea en una etiqueta como esta, o enlazar a una hoja de estilo .eqcss externa con <script type=“text/eqcss” src=styles.eqcss></script> , que cargaría un archivo llamado styles.eqcss .

Anatomía de una consulta de elementos

Ámbito de estilo

La sintaxis en EQCSS para escribir consultas de elementos es muy similar al formato de las consultas de medios CSS, pero en lugar de @media , comenzamos la consulta con @element . La única otra información que necesitamos proporcionar es al menos un selector al que se deben aplicar estos estilos. Así es como crearía un nuevo ámbito para un elemento llamado <div class=“widget”> :

 @element '.widget' { }

El elemento entre comillas (en este caso, .widget ) puede ser cualquier selector de CSS válido. Con esta consulta, hemos creado un nuevo alcance en el elemento .widget . Todavía no hemos incluido ninguna condición de respuesta para el ámbito, por lo que cualquier estilo en una consulta como esta se aplicaría al elemento del ámbito en todo momento.

Sin la capacidad de aplicar estilos a uno o más elementos (en lugar de toda la página a la vez), no podríamos aplicar consultas receptivas solo a esos elementos. Una vez que hemos creado ese alcance a nivel de elemento, usar las funciones más avanzadas de la sintaxis de EQCSS se vuelve fácil, como el metaselector $parent , por ejemplo, porque JavaScript ahora tiene un punto de referencia desde el cual calcular cosas como el parentNode del alcance. elemento. ¡Esto es enorme!

Es cierto que CSS ya incluye un selector de descendientes directos, con > , que nos permite seleccionar elementos que son hijos directos del elemento especificado. Pero CSS actualmente no ofrece ninguna forma de viajar en la otra dirección hacia arriba en el árbol genealógico, para seleccionar un elemento que contenga otro elemento, que uno llamaría su elemento principal. La especificación "CSS Selectors Level 4" ahora incluye un selector :has() , que funciona de manera similar al selector :has() de jQuery, pero actualmente el soporte del navegador es nulo. Scoped CSS hace posible un tipo diferente de selector principal.

Ahora que hemos abierto un alcance en el contexto del elemento .widget , podemos escribir estilos desde su perspectiva para apuntar a su propio elemento principal:

 @element '.widget' { $parent { /* These styles apply to the parent of .widget */ } }

Otro ejemplo de selectores especiales que se pueden usar en cualquier consulta de elementos son los selectores $prev y $next , que representan los elementos hermanos anterior y siguiente. Aunque CSS puede llegar al siguiente hermano de nuestro widget con un selector como .widget + * , CSS no tiene forma de retroceder y seleccionar el elemento que viene directamente antes de otro elemento.

 <section> <div>This will be the previous item</div> <div class="widget">This is the scoped element</div> <div>This will be the next item</div> </section> <style> @element '.widget' { $prev { /* These styles apply to the element before .widget */ } $next { /* These styles apply to the element after .widget */ } } </style>

Consultas de elementos

Los desarrolladores utilizan con mayor frecuencia las consultas de medios CSS para un diseño receptivo mediante la aplicación de estilos basados ​​en la altura o el ancho de la ventana gráfica del navegador. La sintaxis de EQCSS admite muchos tipos nuevos de condiciones de respuesta. En lugar de trabajar solo con el ancho y el alto del navegador, puede escribir estilos que se apliquen a los elementos en función de sus propias propiedades, como cuántos elementos secundarios contiene o cuántos caracteres o líneas de texto hay en el elemento en este momento. .

Agregar estas condiciones receptivas a sus estilos de alcance es similar a cómo daría formato a las consultas de medios: agregaría and (condition: value) para cada condición que desea verificar. En este ejemplo, verificaremos si algún elemento .widget se muestra al menos 500 píxeles de ancho en la página.

 @element '.widget' and (min‐width: 500px) { /* CSS rules here */ }

La sintaxis de una consulta de elementos se divide de la siguiente manera:

  • consulta de elemento @element selector_list [ condition_list ] { css_code }
  • lista de selectores " css selector [ "," css selector ]* "
  • lista de condiciones and ( query_condition : value ) [ "and (" query condition ":" value ")" ]*
  • número de valor number [ css unit ]
  • condición de consulta min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x
  • unidad css % | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax % | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax

Como otro ejemplo, aquí se explica cómo escribir una consulta que convierte el elemento del body en rojo cuando el elemento .widget alcanza los 500 píxeles de ancho:

 @element '.widget' and (min‐width: 500px) { body { background: red; } }

Tenga en cuenta que el elemento del body cambia cuando el .widget alcanza un cierto ancho, ¡no el elemento .widget en sí mismo!

Condiciones de consulta de elementos

A continuación se muestra la lista completa de condiciones de respuesta que admite EQCSS.

Condiciones basadas en ancho

  • demostración de min-width para píxeles, demostración para porcentajes
  • demostración de max-width para píxeles, demostración para porcentajes

Condiciones basadas en la altura

  • demostración de min-height para píxeles, demostración para porcentajes
  • demostración de max-height para píxeles, demostración para porcentajes

Condiciones basadas en conteo

  • demostración de min-characters mínimos para elementos de bloque, demostración para entradas de formulario
  • demostración de max-characters para elementos de bloque, demostración para entradas de formulario
  • demostración min-lines mínimas
  • demostración max-lines
  • demostración min-children
  • demostración max-children

Condiciones basadas en desplazamiento

  • demostración min-scroll-y
  • demostración max-scroll-y
  • demostración min-scroll-x
  • demostración max-scroll-x

Puede combinar cualquier cantidad de estas condiciones en sus consultas de elementos para obtener estilos receptivos verdaderamente multidimensionales. Esto le brinda mucha más flexibilidad y control sobre cómo se procesan los elementos. Por ejemplo, para reducir el tamaño de fuente de un encabezado que tiene más de 15 caracteres cuando hay menos de 600 píxeles de espacio disponible para mostrar, puede combinar las condiciones para max‐characters: 15 y max‐width: 600px :

 h1 { font‐size: 24pt; } @element 'h1' and (min‐characters: 16) and (max‐width: 600px) { h1 { font‐size: 20pt; } }

Metaselectores

Uno de los problemas con los que se puede encontrar una vez que comienza a escribir estilos con alcance con condiciones receptivas es que, cuando hay varias instancias del mismo selector en una página, usar ese selector en su consulta de elementos aplicará estilos a todas las instancias de ese selector en la página. página cuando alguno de ellos cumpla las condiciones. Tomando nuestros ejemplos de .widget de antes, supongamos que tenemos dos widgets en la página (quizás uno en la barra lateral y otro que se muestra a todo lo ancho) y escribimos nuestra consulta de elementos de esta manera:

 @element '.widget' and (min‐width: 500px) { .widget h2 { font‐size: 14pt; } }

Esto significaría que cuando cualquiera de los elementos .widget de la página tiene al menos 500 píxeles de ancho, el estilo se aplicaría a ambos elementos .widget . Esto probablemente no es lo que queremos que suceda en la mayoría de los casos. ¡Aquí es donde entran los meta selectores!

Las dos partes que componen nuestra consulta de elementos son el selector y la condición de respuesta. Por lo tanto, si queremos apuntar solo a los elementos de la página que coinciden con el selector y las condiciones de respuesta al mismo tiempo, podemos usar el metaselector $this . Podemos reescribir nuestro último ejemplo para que el estilo se aplique solo a los elementos .widget que coincidan con la condición min‐width: 500px :

 @element '.widget' and (min‐width: 500px) { $this h2 { font‐size: 14pt; } }

La sintaxis de EQCSS admite varios selectores nuevos que no se encuentran en CSS normal. Aquí está la lista completa:

  • $this demostración
  • $parent demostración principal
  • demostración $root
  • demostración $prev
  • $next demostración

Estos selectores solo funcionarán en una consulta de elementos.

Abriendo el portal entre JavaScript y CSS

  • eval(') demostración

La última y última característica de EQCSS es la más salvaje de todas: eval(') . A través de esta puerta se encuentra todo el poder de JavaScript, accesible desde CSS. Aunque JavaScript puede aplicar estilos a los elementos, actualmente tiene dificultades para llegar a algunas cosas, como los pseudoelementos :before y :after . Pero, ¿y si CSS pudiera llegar a JavaScript desde la otra dirección? En lugar de que JavaScript configure las propiedades de CSS, ¿qué pasaría si CSS pudiera reconocer JavaScript?

Aquí es donde entra en eval(') . Puede acceder y evaluar cualquier JavaScript, ya sea para usar el valor de una variable de JavaScript en su CSS, para ejecutar una sola línea de JavaScript (como eval('new Date().getFullYear()') ), para determinar valores sobre el navegador y otros elementos que JavaScript puede medir (como eval('innerHeight') ) o para ejecutar una función de JavaScript y usar el valor que devuelve en sus estilos CSS. Aquí hay un ejemplo que genera 2016 en un elemento <footer> :

 @element 'footer' { $this:after { content: " eval('new Date().getFullYear()')"; } }

Usando $it dentro de eval(')

Al evaluar JavaScript, eval(') también funciona desde el contexto del elemento de ámbito activo, el mismo elemento al que se aplican los estilos para $this . Puede usar $it en JavaScript escrito en eval(') como marcador de posición para el elemento del ámbito si le ayuda a estructurar el código, pero si se omite, funcionará de la misma manera. Por ejemplo, digamos que tenemos un div con la palabra "hola". El siguiente código generaría "hola, hola":

 <div>hello</div> <style> @element 'div' { div:before { content: "eval('$it.textContent') "; } } </style>

Aquí, $it refiere al div porque es el selector de alcance actual. También puede omitir $it y escribir el siguiente código para mostrar lo mismo:

 @element 'div' { div:before { content: "eval('textContent') "; } }

eval(') puede ser útil en situaciones en las que CSS no está al tanto de las medidas o eventos que ocurren en la página después de que se ha cargado. Por ejemplo, los elementos iframe utilizados para incrustar videos de YouTube vienen con un ancho y alto específicos. Si bien puede configurar el ancho en auto en CSS, no hay una manera fácil de mantener la relación de aspecto correcta de ancho a alto cuando el video se expande para llenar el espacio disponible.

Una solución común para mantener relaciones de aspecto receptivas mientras se escala es colocar el contenido que necesita mantener su relación de aspecto en un contenedor y luego agregar relleno al contenedor con un valor basado en la relación de ancho a alto que desea mantener. Esto funciona, pero requiere que conozca la relación de aspecto de todos los videos por adelantado, así como también requiere más marcado HTML (un elemento de envoltura) para cada video que desea incrustar de manera receptiva. Multiplique eso en todos los sitios web que tienen videos receptivos, y eso es mucho cruft que no necesitaría estar allí si CSS fuera un poco más inteligente.

Tal vez un mejor enfoque para las relaciones de aspecto responsivas consiste en colocar cada video en un envoltorio sin relleno y luego escribir una biblioteca de JavaScript que calcule la relación de aspecto de cada video que encuentre y aplique la cantidad correcta de relleno a cada envoltorio.

Pero, ¿y si CSS pudiera acceder a esas medidas directamente? No solo podríamos consolidar el CSS para todas las relaciones de aspecto diferentes en una sola regla, sino que si pudiéramos evaluarlo una vez que se carga la página, podríamos escribir una regla que cambie el tamaño de cualquier video que le demos en el futuro. ¡Y podríamos hacerlo todo sin envoltorios!

Si esto parece demasiado bueno para ser verdad, échale un vistazo. Así de simple es escribir elementos de iframe de cambio de tamaño receptivo sin envoltorio en EQCSS:

 @element 'iframe' { $this { margin: 0 auto; width: 100%; height: eval('clientWidth/(width/height)'); } }

Aquí, width y height se refieren a los atributos width=“” y height=“” en el iframe en HTML. JavaScript puede realizar el cálculo de (width/height) , lo que nos da la relación de aspecto; y para aplicarlo a cualquier ancho, simplemente dividiríamos el ancho actual del elemento iframe por la proporción.

Esto tiene la concisión y la legibilidad de CSS, y todo el poder de JavaScript. No se requieren envoltorios adicionales, ni clases adicionales ni CSS adicional.

Sin embargo, tenga cuidado con eval(') . Hay una razón por la que las expresiones CSS se consideraban peligrosas en el pasado, y también hay una razón por la que probamos la idea. Si no tiene cuidado con la cantidad de elementos a los que los aplica en la página o con la frecuencia con la que recalcula los estilos, entonces JavaScript podría terminar ejecutando las cosas cientos de veces más de lo necesario. Afortunadamente, EQCSS nos permite invocar EQCSS.apply() o EQCSS.throttle() para volver a calcular los estilos manualmente, de modo que tengamos más control sobre cuándo se actualizan los estilos.

¡La zona de peligro!

Pueden ocurrir otros problemas si crea consultas con condiciones o estilos en conflicto. EQCSS, como CSS, se lee de arriba a abajo usando una jerarquía de especificidad. Aunque CSS es un lenguaje declarativo, contiene algunas características avanzadas. Está a solo un par de pasos de ser Turing-completo como lenguaje de programación. Hasta ahora, la depuración de CSS ha sido un asunto bastante sencillo, pero EQCSS cambia el CSS de ser simplemente un lenguaje declarativo interpretado a ser un lenguaje de hoja de estilo dinámico con una capa adicional de interpretación entre CSS y el navegador. Con este nuevo territorio viene una variedad de posibles nuevos escollos.

Aquí hay un ejemplo de un bucle recíproco en EQCSS, algo a lo que las consultas de medios CSS normales son inmunes por diseño:

 @element '.widget' and (min‐width: 300px) { $this { width: 200px; } }

Llamo a esto jekyll: hide; CSS. Pero además de un estilo que se activa continuamente, también existe la posibilidad de escribir múltiples consultas que se activan entre sí, en lo que llamamos un "bucle recíproco de doble inversión", el más desagradable de todos:

 @element '.widget' and (min‐width: 400px) { $this { width: 200px; } } @element '.widget' and (max‐width: 300px) { $this { width: 500px; } }

En teoría, ese desafortunado widget estaría atascado en un bucle, cambiando de tamaño entre 200 y 500 píxeles hasta el final de los tiempos, sin poder establecer un ancho. Para casos como este, EQCSS simplemente calcula las reglas en el orden en que se evalúan, premia al ganador y continúa. Si tuviera que reorganizar el orden en que aparecen estas reglas, el último estilo siempre ganaría si tienen la misma especificidad.

Algunas personas dicen que la capacidad de crear bucles (o incluso bucles recíprocos doblemente invertidos) es una falla de diseño, pero para evitar que los bucles sean posibles, debe limitar el poder de EQCSS de una manera que elimine la mayor parte de el valor que proporciona la sintaxis. Por otro lado, crear bucles infinitos en JavaScript es muy fácil, pero eso no se ve como una falla del lenguaje, ¡se ve como una evidencia de su poder! Es lo mismo con las consultas de elementos.

Consultas de elementos de depuración

Actualmente, la depuración de consultas de elementos puede parecerse un poco a la depuración de consultas de medios antes de que tuviéramos herramientas como el inspector web para mostrarnos los estilos tal como se calcularon en la página. Por ahora, la depuración y el desarrollo de consultas de elementos requieren que el desarrollador mantenga un modelo mental de qué comportamiento de respuesta debería estar ocurriendo. En el futuro, podría ser posible crear herramientas para desarrolladores compatibles con EQCSS, pero a partir de ahora, las herramientas para desarrolladores en todos los navegadores principales solo conocen los estilos que EQCSS ya ha aplicado a los elementos de la página y no conocen las condiciones de respuesta que EQCSS está observando.

Cómo diseñar con consultas de elementos

La forma más sencilla de hacer uso de consultas de elementos es convertir diseños existentes mediante consultas de medios en consultas de elementos, "liberando" elementos y sus estilos de respuesta de un diseño y facilitando la reutilización de ese código en otras páginas y proyectos. La siguiente consulta de medios y consulta de elementos podría significar lo mismo:

 footer a { display: inline-block; } @media (max‐width: 500px) { footer a { display: block; } }
 footer a { display: inline-block; } @element 'footer' and (max‐width: 500px) { $this a { display: block; } }

La diferencia es que, en el ejemplo original, los enlaces de pie de página permanecen como display: block hasta que el navegador tenga al menos 500 píxeles de ancho. El segundo ejemplo, utilizando consultas de elementos, se vería igual pero solo si el elemento de footer de página fuera de ancho completo.

Después de liberar este estilo de su consulta de medios original, ahora podemos colocar el pie de página en un contenedor de cualquier ancho y asegurarnos de que cuando el pie de página necesite que se aplique el estilo receptivo (es decir, cuando sea más estrecho que 500 píxeles), será aplicado.

  1. Asegúrese de que EQCSS.js esté presente en el HTML del documento de destino.
  2. Reemplace @media con @element en el CSS.
  3. Agregue un selector de CSS al alcance de cada consulta @element .
  4. Opcional: reemplace las ocurrencias del elemento del ámbito con $this en las consultas de elementos.

A menos que el componente de diseño que está convirtiendo se haya diseñado originalmente para mostrarse usando todo el ancho de la ventana gráfica del navegador, es probable que tenga que ajustar los puntos de interrupción después de convertir a consultas de elementos.

Evitar el encierro

La experiencia de crear estilos EQCSS es similar a la experiencia de escribir CSS normal: todas sus propiedades y técnicas favoritas de CSS siguen ahí, solo con algunas características adicionales que las ayudan a trabajar juntas de nuevas maneras. Debido a que EQCSS genera CSS estándar en el navegador, cualquier característica de CSS para la que su navegador tenga soporte integrado funcionará cuando se use con EQCSS. Si algún día se especifican funciones como consultas de elementos y estilos de alcance en CSS y son compatibles con los navegadores, entonces podrá comenzar a usarlas en su código EQCSS de inmediato, mientras sigue confiando en EQCSS para las otras funciones que el navegador no tiene. sin embargo, admite de forma nativa.

Debido a que puede usar la sintaxis de EQCSS tanto directamente en CSS como en su propia secuencia de comandos, con el tipo text/eqcss , si CSS alguna vez desarrolla una sintaxis para consultas de elementos nativos, aún podrá cargar EQCSS como secuencia de comandos y evitar conflictos. .

De cara al futuro, una solución con la que los desarrolladores de navegadores están experimentando en este momento es Houdini, que abriría el acceso a los desarrolladores de complementos para ampliar CSS de nuevas formas, como agregar soporte al propio navegador. Algún día, podría ser posible escribir complementos más eficientes que interpreten la sintaxis de EQCSS y llevar estas funciones a los navegadores de una manera más directa y eficaz de lo que permite la biblioteca JavaScript actual.

Entonces, ¿deberíamos seguir usando consultas de medios?

Sí, aunque las consultas de elementos brindan muchas formas nuevas y emocionantes de orientar elementos con estilos, las consultas de medios (aunque limitadas) siempre se ejecutarán más rápido en el navegador que un estilo que se basa en JavaScript para calcular. Sin embargo, las consultas de medios CSS son para algo más que diseñar HTML para pantallas. Las consultas de medios CSS también admiten consultas impresas y otras formas en que los sitios web muestran información. EQCSS se puede usar junto con consultas de medios para cosas como estilos de impresión, por lo que no es necesario retirar la consulta de medios solo porque ahora también se pueden usar consultas de elementos.

Diseñando con Visión 2020

Lo mejor que podemos hacer por el futuro de CSS es experimentar con estas ideas tanto como sea posible hoy. Ninguna lluvia de ideas y teorías sobre estas características será tan útil como intentar implementarlas y ponerlas en uso, descubriendo las técnicas que las hacen útiles y poderosas.

Además de proporcionar una solución para consultas de elementos, se espera que EQCSS.js también sirva como plataforma para otros experimentos en la extensión de CSS. Si tiene una idea para una nueva condición receptiva, una nueva propiedad de CSS o un nuevo selector para usar en su código, bifurcar EQCSS.js y modificarlo para incluir su idea puede ayudarlo a llegar hasta allí con poco esfuerzo.

Modular Design

In designing layouts using element queries, the biggest shift is learning how to stop viewing the DOM from the top down and from the perspective of only the root HTML element, and to start thinking about individual elements on the page from their own perspectives within the document.

The old paradigms of “desktop-first” and “mobile-first” responsive design aren't relevant any longer — the new way of building layouts approaches design “element-first.” Using element queries enables you to work on the individual parts that make up a layout, in isolation from one another, styling them to a greater level of detail. If you are using a modular approach for your back-end code already but have so far been unable to package your CSS with your modules because of the difficulties of styling with media queries alone, then element queries will finally allow you to modularize your styles in the same way.

Thinking Element-First

Element-first design is in the same spirit as the atomic design principle but looks different in practice from how most people have implemented atomic design in the past.

For example, let's say you have some HTML like the following, and the desired responsive behavior can be explained as, “The search input and button are displayed side by side until the form gets too narrow. Then, both the input and the button should be stacked on top of each other and displayed full width.”

 <form> <input type=search> <input type=button value=Search> </form>

Desktop-First Approach

In a desktop-first mindset, you would write styles for the desktop layout first and then add responsive support for smaller screens.

 input { width: 50%; float: left; } @media (max‐width: 600px) { input { width: 100%; float: none; } }

Mobile-First Approach

In a mobile-first mindset, you would design the mobile view first and add support for the side-by-side view only when the screen is wide enough.

 input { width: 100%; } @media (min‐width: 600px) { input { width: 50%; float: left; } }

Element-First Approach

In the first two examples, the media breakpoint was set to 600 pixels, and not because that's how wide the inputs will be when they switch. Chances are, the search input is probably inside at least one parent element that would have margins or padding. So, when the browser is 600 pixels wide, those inputs might be somewhere around 550 or 525 pixels wide on the page. In a desktop-first or mobile-first approach, you're always setting breakpoints based on the layout and how elements show up within it. With an element-first layout, you're saying, “I don't care how wide the browser is. I know that the sweet spot for where I want the inputs to stack is somewhere around 530 pixels wide.” Instead of using a media query to swap that CSS based on the browser's dimensions, with element-first design, we would scope our responsive style to the form element itself, writing a style like this:

 input { width: 100% } @element 'form' and (min‐width: 530px) { $this input { width: 50%; float: left; } }

The code is similar to that of the two previous methods, but now we are free to display this search input anywhere — in a sidebar or full width. We can use it in any layout on any website, and no matter how wide the browser is, when the form itself doesn't have enough room to display the inputs side by side, it will adapt to look its best.

Resources For Getting Started

EQCSS-Enabled Template

 <!DOCTYPE html> <html> <head> <meta charset="utf‐8"> <title></title> <style></style> </head> <body> <!‐‐[if lt IE 9]><script src="https://elementqueries.com/EQCSS‐polyfills.min.js"></script><![endif]‐‐> <script src="https://elementqueries.com/EQCSS.min.js"></script> </body> </html>

Demos

  • Responsive Aspect Ratio
  • Sticky Scroll Header
  • Blockquote Style
  • Calendario
  • Content Demo
  • Counting Children Demo
  • Date Demo
  • Zastrow-style Element Query Demo Demo
  • Flyout Demo
  • Headline Demo
  • Media Player Demo
  • Message Style Demo
  • Modal Demo
  • Nav Demo
  • Parent Selector Demo
  • Pricing Chart Demo
  • Responsive Tables Demo
  • Scroll-triggered Blocker Demo
  • Signup Form Demo
  • Testimonials Block Demo
  • Tweet-Counter Demo
  • JS Variables Demo
  • Responsive Scaling Demo
  • Geometric Design Demo
  • Responsive Order Form
  • Element Query Grid
  • JS Functions in CSS
  • Responsive Content Waterfall

Otras lecturas

You can find the EQCSS project on GitHub, demos, documentation and articles on the EQCSS website. An ever-growing number of Codepens use EQCSS, and you can create your own pen by forking the batteries-included template that comes hooked up with EQCSS. You can also play with the EQCSS tool that I built to preview if your EQCSS code is working as expected.

Happy hacking!