aprende-sass-parte4

A lo largo de las últimas semanas hemos aprendido a usar Sass; el proceso de instalación y sus características principales han sido descritas en esta serie.

Imagino que ustedes al igual que nosotros quieren seguir aprendiendo temas un poco más avanzados de la herramienta. Hoy hemos llegado al punto de corte entre lo muy básico y características más complejas. En el presente artículo, trataremos de explicarles con detalle un nuevo tipo de dato Maps y el uso de Funciones en Sass.

Tipo de dato Maps:

Este tipo de dato es relativamente nuevo, fue agregado en la versión 3.3 de Sass. Se trata de una lista con llaves y valores. Te sentirás muy cómodo con ellos si has tenido la oportunidad de leer un JSON. La sintaxis es muy similar y fácil de leer, a continuación un pequeño ejemplo:

$map: (key1: value1, key2: value2, key3: value3);

A simple vista podemos apreciar la declaración de una variable de la misma manera que venimos haciéndolo en los artículos anteriores, la diferencia la encontramos en el contenido. No guardamos un  solo valor sino un conjunto de ellos con sus respectivas llaves o identificadores.

Hagamos un ejemplo un poco más complejo para que se puede apreciar con mayor claridad el poder de esta característica:

Supongamos que necesitamos crear una serie de botones para compartir contenido y nos exigen tres: Twitter, Facebook y envío por correo. Declaramos una variable Maps y agregamos en ella los tres colores que vamos a utilizar en nuestros estilos:

$colors: (
  twitter: #55acee,
  facebook:  #3a5795,
  send-mail: #C25E30
);

Ahora utilizaremos la directiva @each para acceder a las llaves y valores de la variable $colors y con ello generaremos los estilos de los botones, de la siguiente manera:

@each $name-color, $bgcolor in $colors {
    .btn--#{$name-color} {
        background-color: $bgcolor;
    }
}

El CSS procesado por Sass será el siguiente:

.btn--twitter {
  background-color: #55acee;
}

.btn--facebook {
  background-color: #3a5795;
}

.btn--send-mail {
  background-color: #C25E30;
}

Los Maps, como los array o los objetos JSON, también pueden ser multidimensionales. Esto es muy poderoso, nos permite elaborar listas que solo cambien su valor dependiendo de las diferentes capas o llaves padres que implementemos.

Existen varias funciones que nos permiten manipular los Maps fácilmente:

map-get($map, $key):

Devuelve el valor de una llave.

map-merge($map1, $map2):

Une dos variables.

map-remove($map, $key…):

Borra llaves de una variable.

map-keys($map):

Devuelve una lista de todas las llaves en una variable.

map-values($map):

Devuelve una lista de todos los valores en una variable.

map-has-key($map, $key):

Devuelve si una variable Map cuenta con una llave del mismo nombre del segundo argumento ($key).

keywords($args):

Devuelve las palabras claves pasadas a una función que toma o recibe argumentos de variables.

Es posible crear funciones propias que se relacionen con los Maps.

Luego de toda esta teoría, hagamos una nueva práctica:

Vamos a crear un pequeño Mixin para generar media queries, usando los conceptos aprendidos a lo largo de este artículo:

Declaramos una variable con todos los puntos de quiebre o «breakpoints» que tendrá nuestro ejemplo:

// _vars.scss
$breakpoints: (
  mobile: 240px,
  tablet: 600px,
  desktop: 1024px  
);

Luego, creamos el Mixin que nos permite determinar los puntos de quiebre y agregar los estilos específicos para cada situación:

// Generate Media Queries
// @param $device (desktop | tablet | mobile);
// 
// @include breakpoint(desktop);
// 
@mixin breakpoint($device) {
  
  @if map-has-key($breakpoints, $device) {
    @media (min-width: #{map-get($breakpoints, $device)}) {
      @content;
    }
  } @else {
    @warn "Desafortunadamente el valor #{$device} es desconocido.";
  } 
}

Podemos apreciar que hacemos uso de $map-has-key, para comprobar si el argumento que le pasaremos al Mixin se encuentra en el Map breakpoint creado anteriormente.

Luego, hacemos uso de $map-get, para obtener e imprimir el valor del argumento.

La directiva @content, nos permite pasarle un bloque de estilos al Mixin.

Si la función $map-has-key, detecta que el argumento que le pasamos no se encuentra en el Map breakpoint, entonces imprimirá una alerta mediante la directiva @warn. También, podemos usar la directiva @error para imprimir errores fatales. Es una buena opción cuando falta algún argumento requerido y necesitamos que Sass detenga la conversión a CSS hasta tanto no se solucione el problema.

Como vimos en el tutorial anterior, podemos usar el mixin que creamos de esta forma:

body {
  @include breakpoint(mobile) {
    background-color: yellow;
  }  
  @include breakpoint(tablet) {
    background-color: blue;
  }  
  @include breakpoint(desktop) {
    background-color: red;
  }
}

Todo lo que agreguemos dentro de las llaves de cada declaración del Mixin Breakpoint, será recibido por la directiva @content. De esta manera podemos agregar fragmentos de código al momento de declarar el mixin.

Funciones:

Las Funciones en Sass, son primos (por llamarlas de algún modo) de los Mixins. Fueron agregadas en la versión 3.1.0. Su labor es permitirnos separar la lógica de los estilos, lo cual nos ayuda a elaborar mejores estructuras de proyectos que sean más fáciles de leer y entender.

Sass, viene por defecto con una serie de Funciones que nos ayudan a realizar infinidad de operaciones, en la documentación oficial pueden encontrar una lista completa. Para adelantarles un poco, en la lista encontrarán funciones para manipular colores, números, cadenas, entre otras funciones muy interesantes.

Si las funciones por defecto no cumplen nuestros requerimientos, Sass nos permite crearlas fácilmente. Para declarar una función debemos utilizar un arroba seguido de la palabra clave function (@function), luego el nombre y los argumentos requeridos.

Vamos a crear una Función básica en Sass:

@function saludo($nombre: "Mundo") {
  @return "Hola " + $nombre 
}

Para llamarla:

saludo("Manuel");

Imprimirá «Hola» seguido del argumento pasado «Manuel»: Hola Manuel.

Para probar la función desde el navegador, utilizaremos la etiqueta html y los Pseudo-elementos After y Before:

html {
  &:before {
    content: saludo("Manuel");
  }
  
  &:after {
    content: saludo();
  }
}

Ya tenemos un «Hola Mundo» escrito en Sass mediante las funciones. Ahora, vamos a realizar una práctica un poco más compleja:

Vamos a crear un componente muy importante en todo desarrollo, un pequeño grid que nos permita estructurar nuestro diseño pero sin utilizar clases de ayuda o helpers:

Creando un Grid con Sass

Primero, debemos crear un Map, que contenga todos los datos requeridos por nuestro Grid.

// vars
$grid: (
  cantidad-col: 12,
  ancho-col: 60px,
  margen: 20px,
  container: 960px
);

Seguidamente, creamos tres funciones. La primera para calcular el ancho del contenedor de nuestro grid, la segunda para obtener el ancho de cada columna y la tercera, el margen lateral de cada columna.

// ancho del contenedor
@function calc-container($grid: $grid) {
  @return (map-get($grid, ancho-col) + map-get($grid, margen)) * map-get($grid, cantidad-col);
}

// ancho de cada columna
@function calc-col($cantidad-col, $grid: $grid) {
  @return (map-get($grid, ancho-col) * $cantidad-col) + (map-get($grid, margen) * $cantidad-col) - map-get($grid, margen);
}

// margen para cada columna
@function calc-gutter($gutter) {
  @return $gutter / 2;
}

Ya contamos con todo lo necesario para que nuestro grid básico funcione correctamente, ahora, usando dicho grid, vamos a crear una estructura base tipo blog: un contenedor para centrar el contenido, un área para los artículos y una barra lateral:

.wrap {
  margin: 0 auto;
  width: calc-container();
  
  &:after {
    clear: both;
    content: '';
    display: block;
  } 
}

section {
  float: left;
  margin: 0 calc-gutter(map-get($grid, margen));  
  width: calc-col(8);
}

aside {
  float: left;
  margin: 0 calc-gutter(map-get($grid, margen));
  width: calc-col(4);
}

Nuestro HTML debería ser algo como esto:

<div class="warp">
  <section>
    Hola, soy el contenido principal.
  </section>
  <aside>
    Hola, soy una barra lateral.
  </aside>
</div>

Listo, ya tenemos funcionando un muy básico grid Aquí podemos apreciar mejor el ejemplo. Como podrán darse cuenta al grid le faltan muchísimas cosas para poder ser usado en un proyecto real, mi intención solo fue mostrarles el poder de las funciones a través de la elaboración de un grid básico.

Conclusión:

El tipo de dato Maps y las Funciones son características muy poderosas de Sass, nos permiten escribir mejor código. Tu yo del futuro te lo agradecerá :)

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.

Lección anterior Aprende Sass: Operators, Mixins y Extends Lección siguiente Cómo usar las directivas @warn y @error en Sass