43

Tutorial: Variables nativas en CSS

14493Puntos

hace 5 años

El uso de variables es común dentro de los lenguajes de programación. Como CSS no es uno de ellos no contaba con variables hasta hace muy poco.

Hace ya un tiempo que disfrutamos del uso de variables en los preprocesadores de CSS como Stylus, SASS, LESS, Myth y PostCSS. A mí me gusta Stylus pero me tengo que adaptar a la mayoría y cuando trabajo en equipo tengo que usar SASS.

Hay dos diferencias fundamentales entre las variables de los preprocesadores y las nativas.
La primera es que las de los preprocesadores sólo están vivas (funcionan) en el intervalo de tiempo que lleva compilar a CSS. El navegador no las conoce ya que sus posibles valores ya han sido fijados en el CSS final, como en el siguiente ejemplo:

El código completo del ejemplo de variables de preprocesador lo encuentras en:
https://codepen.io/miguelgilrosas/pen/wPreQp

Código en HTML:

<divclass="contenedor"><divclass="celda celda1">div>
  <divclass="celda celda2">div>
  <divclass="celda celda3">div>
  <divclass="celda celda4">div>
  <divclass="celda celda5">div>
  <divclass="celda celda6">div>
div>

Código en SCSS (SASS):

No es buena práctica anidar tanto cuando no es necesario, pero quería demostrar el alcance de la variable y la anidación de selectores

.contenedor {
  display: flex;
  & .celda { // '&' sustituye al selector del bloque superior, aquí '.contenedor'
    width: 100px;
    height: 100px;
    //Aquí definimos una variable SASS
    $colores: red green blue peru tomato steelblue;
    @for $i from 1 through 6 {
      &.celda#{$i} { // '&' sustituye al selector del bloque superior, aquí '.contenedor .celda'
        background-color: nth($colores, $i);
      }
    }
  }
}

Resultado en CSS (la especificidad de selectores está exagerada) (para verlo, elegir opción de ver el CSS compilado en el botón de lista desplegable a la derecha del título de la sección de CSS):

.contenedor {
  display: flex;
}
.contenedor.celda {
  width: 100px;
  height: 100px;
}
.contenedor.celda.celda1 {
  background-color: red;
}
.contenedor.celda.celda2 {
  background-color: green;
}
.contenedor.celda.celda3 {
  background-color: blue;
}
.contenedor.celda.celda4 {
  background-color: peru;
}
.contenedor.celda.celda5 {
  background-color: tomato;
}
.contenedor.celda.celda6 {
  background-color: steelblue;
}

El navegador muestra:

Screen Shot 2017-11-22 at 5.31.57 PM.png

Como vemos, el preprocesador no envía sus variables al resultado final. Dichas variables han sido usadas para producir el resultado final pero no existen en él. El uso más común de los preprocesadores es el de evitar repeticiones como hemos visto en el ejemplo con el bucle ‘@for’, pero no es el único y se pueden hacer maravillas con ellos.

Al contrario de las de preprocesador, las variables nativas están vivas mientras dure en el navegador la página web y podemos cambiar sus valores con JavaScript, como veremos después en otro ejemplo.

La segunda diferencia es la del alcance o ámbito de las variables (‘scope’). En los preprocesadores se suele usar como delimitador el bloque definido con las llaves, como en JavaScript. En Stylus el bloque lo define la indentación, una variable definida fuera de bloque es global, dentro de un bloque ‘X’ alcanza a ‘X’ y a los bloques que ‘X’ contiene, pero no a los bloques que contienen a ‘X’. En el ejemplo anterior de SASS la variable ‘$colores’ tiene un alcance que va de la línea 5 hasta la antepenúltima.

Sin embargo, cuando usamos las variables nativas de CSS, debemos recordar su otro nombre: ‘propiedades personalizadas de CSS’. Son propiedades de los elementos HTML que forman el DOM que tiene forma de árbol y que también define su alcance. Una variable definida en un elemento ‘X’ tiene un alcance que abarca a ‘X’ y a los descendientes de ‘X’.

Las variables nativas de CSS se crean como una propiedad más, pero su nombre siempre debe ir precedido por --, por ejemplo --color: blue;. Para usar su valor usaremos la función de CSS var(), por ejemplo color: var(--color);. Pondré un ejemplo que espero sirva para aclarar (propongo que se use codepen.io para experimentar con el código):

Ejemplo de variables nativas:
https://codepen.io/miguelgilrosas/pen/eezrMO

Código en HTML:

<divclass="cara"><divclass="ojo ojoD"><divclass="pupila pupilaD">div>
  div>
  <divclass="ojo ojoI"><divclass="pupila pupilaI">div>
  div>
div>

Código en CSS (sin preprocesador):

.cara {
  /* variables nativas CSS */--lado-cara: 300px;
  --color: peru;
  height: var(--lado-cara);
  width: var(--lado-cara);
  border: 4px solid;
  border-radius: 50%;
  position: relative;
  background-color: var(--color);
}
.ojo {
  position: absolute;
  top: 15%;
  border: inherit;
  height: calc(var(--lado-cara) / 4);
  width: calc(var(--lado-cara) / 4);
  border-radius: inherit;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: var(--color);
}
.ojoD {
  left: 15%;
}
.ojoI {
  right: 15%;
}
.pupila {
  border: inherit;
  height: calc(var(--lado-cara) / 16);
  width: calc(var(--lado-cara) / 16);
  border-radius: inherit;
  background-color: var(--color);
}

Código en JavaScript:

Array.from(document.getElementsByClassName('cara')).forEach(
  el => el.style.setProperty('--color', ‘blue’)
)

El navegador muestra:

Screen Shot 2017-11-22 at 5.55.45 PM.png

Es importante ver que aunque claramente especifico en la línea 4 del CSS que el valor de ‘–color’ (que es la variable que uso para asignar el color de fondo) es ‘peru’ (sí, también me fascina que haya un color ‘peru’, sin tilde), la cara aparece azul. Es así porque con JavaScript le asigno a esa variable en el elemento antecesor de todos (‘.cara’) el valor ‘blue’.

Para experimentar, sugiero cambiar en el código JavaScript el nombre de la clase del elemento o los elementos que queremos seleccionar y el color a asignar. Las clases ‘cara’, ‘ojoD’, ‘pupilaD’, ‘ojoI’ y ‘pupilaI’ seleccionan elementos únicos y las clases ‘ojo’ y ‘pupila’ seleccionan dos elementos cada una. Veremos que los cambios afectan a los elementos seleccionados y, por alcance (‘scope’), a sus descendientes. Si ponemos ‘ojoD’ en vez de ‘cara’ en la línea 1 del JavaScript vemos que sólo serían azules el ojo derecho y la pupila derecha

¿Qué pasaría si ponemos ‘ojo’? Ahí se ve lo que pasa cuando cambiamos el valor de una variable y nos damos cuenta de que el alcance (ámbito, ‘scope’) viaja de los elementos más externos a los más internos y no al contrario.

Puedes usar estas variables para un montón de cosas, la imaginación es tu límite. Además, puedes usarlas sin problemas ya que las soportan todos los navegadores que hay que tener en cuenta. Si tienes preguntas déjame un comentario abajo, estaré atento para responder.

¡Gracias por leer!

Miguel
Miguel
miguelgilrosas

14493Puntos

hace 5 años

Todas sus entradas
Escribe tu comentario
+ 2