40

Tutorial: Variables nativas en CSS

11703Puntos

hace 3 años

Curso de PostCSS
Curso de PostCSS

Curso de PostCSS

PostCSS facilita el proceso de implementación de diseños en tus sitios web, modulariza y escribe código CSS más legible. Además es compatible con todos los navegadores. Te permitirá transformar CSS con el poder de JavaScript.

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!

Curso de PostCSS
Curso de PostCSS

Curso de PostCSS

PostCSS facilita el proceso de implementación de diseños en tus sitios web, modulariza y escribe código CSS más legible. Además es compatible con todos los navegadores. Te permitirá transformar CSS con el poder de JavaScript.
Miguel
Miguel
miguelgilrosas

11703Puntos

hace 3 años

Todas sus entradas
Escribe tu comentario
+ 2
Ordenar por:
8
11703Puntos

Hola, soy el autor del artículo.
Me he pensado mucho si publicar esto o no, al final llegué a la conclusión de que debía decir lo que sentía y espero que se vea como una crítica constructiva.
Cuando remití el artículo a Platzi por primera vez se me pidió que hiciera un cambio, lo pensé, lo entendí y lo cambié porque vi que era un cambio positivo. Pasados unos días se publico mi escrito… sólo que no era completamente mi escrito.
Lo que se ha publicado es al 90% mi artículo pero, sin motivo aparente, se ha cambiado sin mi conocimiento una parte de él. Puedo entender que alguien en el flujo de trabajo de Platzi haya considerado que de la nueva forma se entendería mejor, pero yo creo que no tiene derecho a hacer cambios en el trabajo de otra persona y que está firmado por otra persona. Podría consultar el hacerlo con el autor y, por supuesto, tanto el autor como Platzi pueden negarse a hacer cambios y a publicar, respectivamente. Platzi es el medio que publica si cree que todo está bien, pero el autor es el que hace el artículo, no Platzi. Otra cosa es que fuera empleado de Platzi, que no lo soy.
Puede parecer que es una tontería de lo que me quejo y que esto no es un blog de literatura, pero para mi es muy importante.
Confío en Platzi, mi historial de pagos desde hace años lo atestiguan, así que espero que cambien de política en este tema pero mientras no publicaré nada más.

PD: Por un error de transcripción, se dice en el artículo que las variables nativas de CSS deben llevar un guion (‘-‘) al principio de su nombre. En realidad deben llevar dos (‘—‘), como se ve en el código.

0
12619Puntos
3 años

Muy interesante tu articulo.
Hay algún enlace donde pueda leer el original?

Saludos.

0
3 años

Tu articulo esta muy interesante y es un gran aporte, pero como hace parte de la comunidad Platzi pienso que es necesario que ellos lo ajusten y/o modifiquen si encuentran fallas en tu semantica o en los aspectos tecnicos de tu articulo, sin embargo si debieron informarte acerca de los cambios.

Pregunta por que no recibieron tu articulo como era, tal vez de ayude a mejorar.

Saludos.

3
19039Puntos
3 años

Hola Miguel.

Hemos estado en contacto contigo a lo largo de todo el proceso de edición del artículo, así que nos sorprendió ver esto aquí y no en la conversación por mail que teníamos.

Agradezco el feedback y felices de apoyar para modificar lo que sugieras o dar de baja el artículo si consideras que nuestra edición no fue positiva para el artículo.

Aquí lo importante es que te sientas cómodo y en ningún momento se hicieron los cambios con ninguna otra intención que ayudar a que se llegar a más estudiantes con el contenido.

1
7708Puntos

Excelente aporte Miguel, me sacas de una en la que estaba frito, como siempre, excelente comunidad y excelente platzi.