soy Kseso y esto EsCSS

CSS @apply & @extend Rules Unas ideas interesantes

Dos ideas CSS interesantes de Tab Atkins: las CSS at rules @apply y @extend. Su estado, ejemplos de uso y alguna opinión y discrepancias personales en la sintaxis de su construcción y uso.

CSS @apply & @extend Rules Unas ideas interesantes

·Por Kseso ✎ 4
CSS @apply Rule

Estos días[*1] está teniendo bastante eco la regla CSS @apply [ver CSS @apply Rule]. Posíblemente, a poco que te guste estar al día sobre CSS, también te haya llegado algo al respecto.

Y a poco curioso que hayas sido lo primero que habrás advertido es que en el corpus oficial de CSS no hay nada al respecto. Ni un simple borrador en todo el site del W3c.

Entonces, ¿de qué se está hablando?

Status CSS @apply Rule

Si vas al documento CSS @apply Rule lo primero que observarás es que su destino no es el consorcio W3c. Está alojado en github.io y su subtítulo ya da otra pista: A Collection of Interesting Ideas, 25 August 2015. Su autor o editor en la jerga CSS es Tab Atkins-Bittner (Google).

[*1]: Abril de 2016, fecha de publicación original del post.

Su autor: Tab Atkins

Tab Atkins desde su trabajo en Google es uno de los editores de documentos CSS del W3c más prolíficos. Muy activo tanto en la redacción de múltiples especificaciones CSS como en la lista de correo de CSS así como en Twitter (@tabatkins).

Otro aspecto, para mi muy reseñable y de agradecer, es que es muy accesible. Esto es, si te diriges a él vía Twitter con alguna cuestión, duda o comentario oportuno tienes casi garantizada la respuesta. Y en la lista de correo de CSS igual.

Además de sus ediciones "oficiales" también publica (últimamente las aloja en github) lo que él mismo llama Collection of Interesting Ideas que inicialmente son eso, ideas interesantes. Estas ideas puede que tengan desarrollo y continuidad y verse incorporadas al corpus oficial o que por cualquier motivo se queden en eso, ideas interesantes, como las "element @queries".

CSS @apply Rule ¿qué son?

Así las define Tab Atkins en su "idea":

La regla CSS @apply permite a un autor almacenar un conjunto de declaraciones CSS en una variable `de autor´ (a named variable), para a continuación, hacer referencia a ellas (incluirlas) en otras reglas de estilo.

Pero seguro que expresado en forma de código CSS lo comprendemos mejor:

/* 1º */ :root { --toolbar-theme: { background-color: blue; border-radius: 4px; border: 1px solid var(--theme-color late); }; /* Observa el ; tras el } de cierre */ --toolbar-title-theme: { color: green; }; /* Observa el ; tras el } de cierre */ } /* 2º */ .toolbar { @apply --toolbar-theme; } .toolbar > .title { @apply --toolbar-title-theme; }
  1. Como ves, lo que tenemos en el punto 1º es básicamente una regla CSS con su selector :root y dos declaraciones CSS en las que las 2 propiedades son dos "custom property" y el valor (o equivalencia) de cada una es un bloque de declaraciones:
    • dos `custom properties´ --toolbar-theme y --toolbar-title-theme seguidas cada una de ellas por el carácter : (dos puntos).
    • El valor de cada una de ellas en vez de ser un valor CSS está formado por un bloque de declaraciones, incluidas las llaves de apertura y cierre: {...} y el "punto y coma" ; que indica el final de las declaraciones.
  2. En 2º tenemos dos reglas CSS normales y corrientes, en las que aplicamos (a semejanza de las custom properties tradicionales) la equivalencia realizado en el punto 1º. Pero a diferencia de las custom properties tradicionales en vez de usar la nomenclatura var(--nombre) se usa @apply --nombre para hacer lo mismo con todo el grupo de declaraciones.

Al igual que ocurre con las custom properties que su valor puede ser reescrito o acotado podemos hacer lo mismo con con la regla CSS @apply.

Un `toolbar´ en el elemento `warning´ ignorará el color verde de la declaración anterior y se mostrará con color rojo declarando:

.warning { --toolbar-title-theme: { color: red; font-weight: bold; }; }

CSS @apply Rule estado de la cuestión

Y por qué tanto revuelo con algo que no deja de ser una idea interesante que de momento (hasta donde yo conozco) no ha sido trasladada al corpus CSS.

Porque da la casualidad (o no, que su autor trabaja en Google) que el navegador Chrome en su última versión de Chrome Canary ya las soporta habilitando la opción Experimental Web Platform Features en chrome://flags.

CSS @apply Rule en Chrome Canary
CSS @apply Rule en Chrome Canary. Origen imagen

Y a continuación un ejemplo en Codepen:

See the Pen Pure CSS @apply & custom properties by Kseso (@Kseso) on CodePen.

CSS @extend Rule

Ya metidos con ideas interesantes te presento otra del mismo autor: la regla CSS @extend. De ella dice su autor, también Tab Atkins, lo siguiente:

La regla CSS @extend permite que un elemento (del html) se comporte (estilice) como si fuese afectado por otro selector (css) diferente.

O lo que es lo mismo, permite añadir a un bloque de declaraciones de un selector todos los estilos declarados en cualquier otra regla CSS usando para ello el nombre de su selector.

En código, que es más sencillo de comprender y aplicar que explicar:

.error { color: red; border: thick dotted red; } .serious-error { @extend .error; font-weight: bold; }

El resultado de este código CSS será que un elemento del HTML con un valor serious-error en su atributo class además de mostrarse en negrita (`bold´) se le aplicarán los estilos declarados en el CSS para la regla del selector .error. Esto es, color rojo con el borde correspondiente.

Mi blog. Mi opinión

De entrada, para que no haya malas interpretaciones: me encantan todas las novedades de CSS y más aún poder jugar con ellas. Para ello es necesario que

  • 1º: que quienes saben ideen y pongan por escrito las novedades.
  • 2º: que haya al menos un solo navegador que las incorpore para explorar sus posibilidades y límites.
  • 3º: y con lo anterior a mi disposición compartir en el blog mis juegos y experiencias.

Pero como este juguete llamado EsCss es mio me voy a permitir meter mi opinión personal. Ya ves tú, un simple enredique amanuense de CSS que se viene arriba frente a toda una autoridad como Tab Atkins y un gigante como Google. Pero es que la ignorancia es muy atrevida.

Google Chrome

En primer lugar hay cosas del proceder de Chrome respecto a CSS que me tienen totalmente descolocado y que no acierto a comprender. Dos en particular:

  1. El sacar de su core soporte a novedades después de llevar un tiempo haciéndolo. Como con position: sticky o a las Regiones CSS.
  2. La inclusión y soporte de un sinfín de propiedades CSS ajenas por completo al corpus de CSS. Y no me refiero a las estándares a las que añade su prefijo privativo.

Me recuerda el proceder de Microsoft con sus IE´s cuando eran prácticamente monopolio (usados cuasi de forma universal) con sus filter´s y basuras por el estilo.

Esto supone romper la web. Volver a los tiempos salvajes donde el concepto "standard web" era un chiste, chascarrillo o sueño húmedo (dependiendo de quién lo invocase).

Además de este peligro ya estamos viendo otros efectos: la influencia que ejerce Google Chrome en otros equipos de desarrolladores de navegadores es tal que su mala praxis se extiende a ellos (incluyendo ellos también soporte al prefijo -webkit- y a esas propiedades no estándar.

Sintaxis @apply y @extend

Desde hace ya un tiempo hay un movimiento para uniformizar y mantener una sintaxis coherente a lo largo de todo el desarrollo de CSS. Un ejemplo de ellos es el uso del doble guión --* en todo aquello en nombrado (asignado nombre) por el usuario. Como las `custom properties´. Coherencia que se intenta extender también a lo que ya existía antes de esta idea, como el nombre de los contadores.

Hasta el momento en las reglas CSS de reglas (reglas @ o at rules) dicha sintaxis se venía respetando incluyendo aquellos casos en los que en una parte se define dicha regla y se hace uso en alguna otra regla.

Piensa en la similitud de @apply y @extend con las reglas @keyframes y la propiedad animation. En una parte se define y en otra se aplica.

Creo que @apply y @extend serían más coherentes en su sintaxis si:

  1. La regla CSS @apply

    A semejanza de las "custom properties" en su declaración de equivalencias como es una at rule de autor se identificase como tal: como "at rule" y como "custom named": @--*
    :root {
       @--miNombre {
         /*bloque declaraciones */
       };
     }
    .el {
     apply: var(@--miNombre);
     }
    y en el momento de su uso también se conservaría la coherencia de las declaraciones CSS y uso de una "custom named": propiedad: valor;
  2. La regla CSS @extend

    Aquí es el mismo caso que el segundo paso o uso de la regla @ de autor (custom at rule). De la forma que ahora está no hay concordancia a cómo se construyen las declaraciones CSS:
    propiedad: valor;
    Creo que sería más apropiado el uso de una la propiedad sin el símbolo @ en su nombre y como valor utilizar una función CSS. Esto es, el valor sería un identificador de la función y entre paréntesis el recurso a utilizar:
    .error {
      color: red;
    }
    
    .serious-error {
      extend: selector(.error);
      font-weight: bold;
    }
    A semejanza de los filtros CSS cuando se usa un id (filter: url(#id); o cualquier otro recurso (i.e. imágenes en los fondos).

Ahora te toca a ti decirnos qué te parecen estas dos "ideas interesantes" y además darme algún palito o colleja por mis opiniones al respecto de la forma en que están definidas sus sintaxis y forma de uso.

Adenda

Un signo de estos tiempos es que los comentarios a los artículos de cualquier blog o página se diluyen y dispersan mucho en las distintas redes sociales. Y aunque los usuarios de este blog son/sois (por lo general) parcos en las opiniones y discretos en nuestra relación de vez en cuando esto cambia.

En esta ocasión me parece más que interesante la conversación e intercambio de ideas con Lionel (aka @elrumordelaluz). La puedes ver aquí y su continuación aquí.

avatar del Editor del blog

Ramajero Argonauta, Enredique Amanuense de CSS.
#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Don Kseso Kseso