Diseñando nuestras hojas de estilo con Sass

Detesto CSS. El 1, el 2 y el 3, especialmente el 3, porque debería de haber sido una versión que puliese y arreglase los problemas del 2 y en su lugar ha sido meramente un superconjunto de la versión anterior. A CSS le falta versatilidad, le falta poder tratar el formato como código y no meramente como un conjunto de reglas inmóviles.

Por suerte no soy el único que piensa así y alguien decidió crear una extensión del lenguaje que cubriese sus puntos débiles: Sass.

Qué es Sass y por qué lo quiero

Sass es una extensión de CSS3, principalmente de su sintaxis. Incluye modificaciones como anidamiento, variables, división en múltiples archivos e incluso un pequeño lenguaje de script llamado SassScript que permite añadir funcionalidades como estructuras de control (if-then-else y bucles for/foreach, entre otros).

Ahora bien, al ser una extensión de un lenguaje no es directamente compatible sino que el código escrito en Sass se debe compilar a CSS3.

Vamos a echar un vistazo a algunas de las funcionalidades que lo hacen particularmente atractivo.

Variables

Sass es capaz de hacer cosas que CSS3 debería y que inexplicablemente no lo hace, la verdad. A ver si con CSS4 espabilan. Una de ellas es poder usar variables dentro del código.

A veces nos habremos encontrado con el caso de tener que usar repetidamente un mismo valor dentro del código, cuando por ejemplo queremos definir un color que por razones de patrón se va a usar en múltiples partes de una web. Habremos pensado «ojalá pudiera difinir dicho color en una variable y usar esta variable en todas las instancias necesarias, para poder cambiarlo luego una sola vez». Pues con Sass, nuestros deseos son órdenes. Pongamos que tenemos este código en Sass:

$color-base: #123;

#menu h3 {
    font-size: 1.2em;
    color: $color-base;
}

#menu a {
    color: $color-base;
}

Va a generar el siguiente código en CSS3:

#menu h3 {
    font-size: 1.2em;
    color: #123;
}

#menu a {
    color: #123;
}

Como vemos, el compilador de Sass sustituye todas las instancias de la variable por el valor que le hemos dado. En este ejemplo, tanto el color del texto de las cabeceras como de los enlaces del selector menu tendrán el color hexadecimal #123. Si quisiéramos cambiar el color de ambos sólo tendríamos que cambiar el valor de la variable $color-base.

Anidamiento

Esto, en mi humilde opinión, debería de haber estado en CSS3 desde el principio. Joder, debería de haber estado en CSS2. Con Sass se pueden anidar reglas que compartan el mismo selector:

#menu {
    ul {
        width: 90%;

        li {
            display: inline;
        }
    }

    .cabecera {
        color: blue;
    }

    &:hover {
        background-color: #456;
    }

    &-submenu {
        background-color: #789;
    }
}

Va a acabar siendo:

#menu ul {
    width: 90%;
}

#menu ul li {
    display: inline;
}

#menu .cabecera {
    color: blue;
}

#menu:hover {
    background-color: #456;
}

#menu-submenu {
    background-color: #789;
}

El carácter & hace referencia al selector padre, en este caso menu, y es útil para los eventos (hover, click, etc) o para otros selectores que tienen al padre como prefijo.

Múltiples ficheros

Conforme una página web se nos hace grande vemos que el tamaño de la hoja de estilo crece hasta llegar a ser una columna interminable. CSS tiene una función llamada import que permite importar otros archivos o urls, habilitándonos así a separar nuestros estilos en múltiples ficheros. No obstante tiene un inconveniente: cada import implica una llamada HTTP y lo ideal es que el usuario reciba todo el CSS del sitio web de una vez y lo mantenga en la caché durante el resto de la visita.

Sass nos permite dividir nuestra hoja de estilos en varios ficheros, ideal para separar el código específico de cada subsección de la web, y luego compilarlos en un único fichero .css. Para ello hay que prefijar cada archivo parcial con un guión bajo (_): _blog.scss, _noticias.scss, etc.

En el archivo donde queramos importarlo debemos de usar el siguiente código:

@import 'blog';
@import 'noticias';

Esto insertará el contenido de los archivos parciales en el archivo donde se le invoca y al compilarse se obtendrá un único archivo con el contenido de todos.

Herencia

A veces queremos hacer una clase genérica que luego vamos a ampliar modificando sólo unos pocos parámetros. Por ejemplo, queremos hacer una clase para mostrar mensajes con una serie de características (fondo blanco, margen 15 pixeles, borde negro), y luego querremos diferencias mensajes de aviso (mismas propiedades pero fondo verde) y mensajes de error (fondo rojo).

Con Sass podemos hacer lo siguiente:

.mensaje {
    background-color: white;
    border: 1px solid black;
    margin: 15px;
}

.aviso {
    @extend .mensaje;
    background-color: green;
}

.error {
    @extend .mensaje;
    background-color: red;
}

Con @extend le indicamos que esta regla heredará las propiedades de la clase mensaje, o lo que es lo mismo, que añada esta regla a una lista junto con .mensaje. Esto nos generaría el siguiente código:

.mensaje, .aviso, .error {
    background-color: white;
    border: 1px solid black;
    margin: 15px;
}

.aviso {
    background-color: green;
}

.error {
    background-color: red;
}

Mixins

No tengo ni idea de cómo traducirlo, pero es algo similar a una macro. Sirve para agrupar propiedades dentro de una regla e incluso permite el paso de parámetros. El ejemplo que tienen en la guía oficial da en el clavo sobre su uso: como hay algunas partes de CSS3 que son experimentales y por lo tanto no están oficialmente aceptadas o implementadas, tenemos los prefijos de los fabricantes que pueden o pueden no funcionar en otros navegadores. El siguiente código en Sass:

@mixin border-radius($radius) {
  -webkit-border-radius: $radius;
     -moz-border-radius: $radius;
      -ms-border-radius: $radius;
          border-radius: $radius;
}

.box { @include border-radius(10px); }

Nos daría el siguiente CSS:

.box {
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  -ms-border-radius: 10px;
  border-radius: 10px;
}

Como vemos, el mixin lo declaramos con @mixin y lo invocamos con @include, y podemos pasar uno o más parámetros (separados por comas). En este caso le pasamos el radio del borde, 10 pixeles, que se tomará mediante la variable $radius.

Estructuras de control

Para usos más avanzados y requisitos muy complejos, se pueden usar estructuras de control: desde condicionales if-then-else hasta bucles for, foreach (en Sass les llaman each) y while.

Por ejemplo, imaginemos que tenemos una serie de elementos con un selector que tiene el mismo prefijo pero va numerado:

<ul>
    <li id="item-1">1</li>
    <li id="item-2">2</li>
    <li id="item-3">3</li>
    <li id="item-4">4</li>
</ul>

Y el siguiente código en Sass:

@for $i from 1 through 4 {
    .item-#{$i} { background-color: #fff * $i; }
}

Vamos a iterar, mediante un bucle for, con la variable $i, que recibirá inicialmente el valor 1 y se incrementará hasta el valor 4. En cada iteración se generará una nueva regla para cada ítem, multiplicando un valor de fondo base (#fff) por el valor de $i. Generará el siguiente código:

.item-1 { background-color: #fff; }
.item-2 { background-color: #1ffe; }
.item-3 { background-color: #2ffd; }
.item-4 { background-color: #3ffc; }

Otras funciones

Sass soporta muchas otras funcionalidades: operaciones aritméticas, operaciones lógicas (and, or y not), listas, definición de funciones…
Incluso tienen una lista enorme de funciones predefinidas.

Para más información os recomiendo la documentación oficial.

The following two tabs change content below.

Borja V. Muñoz

Head of Technology Development at Inercia Digital S.L.
Yo solía tener tiempo libre hasta que me metí en esto de los proyectos europeos. Ingeniero e instructor, a veces a la vez, a veces por separado. borjavmunoz (arroba) inerciadigital.com

Borja V. Muñoz

Yo solía tener tiempo libre hasta que me metí en esto de los proyectos europeos. Ingeniero e instructor, a veces a la vez, a veces por separado. borjavmunoz (arroba) inerciadigital.com

También te podría gustar...

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *