Sass
Sass
Extensiones CSS
Este captulo explica las caractersticas que Sass aade a CSS para
hacer que tu trabajo como diseador/a sea ms productivo.
#main p {
color: #00ff00;
width: 97%;
.redbox {
background-color: #ff0000;
color: #000000;
}
El cdigo Sass anterior se convierte automticamente en el siguiente
cdigo CSS:
#main p {
color: #00ff00;
width: 97%;
#main p .redbox {
background-color: #ff0000;
color: #000000;
}
Gracias a las reglas anidadas, se evita tener que repetir una y otra vez
los mismos selectores y se simplifica enormemente la creacin de
hojas de estilos complejas. Ejemplo:
#main {
width: 97%;
p, div {
font-size: 2em;
a { font-weight: bold; }
}
El cdigo Sass anterior se transforma en el siguiente cdigo CSS:
#main {
width: 97%;
font-size: 2em;
font-weight: bold;
}
#main pre {
font-size: 3em;
a {
font-weight: bold;
text-decoration: none;
}
El cdigo Sass anterior se compila de la siguiente manera:
a {
font-weight: bold;
text-decoration: none;
a:hover {
text-decoration: underline;
}
body.firefox a {
font-weight: normal;
}
El carcter especial & siempre se reemplaza por el selector padre tal y
como aparece en el archivo CSS. Esto significa que si tiene una regla
anidada, primero se calcula el selector padre completo y despus se
reemplaza por &. Ejemplo:
#main {
color: black;
a {
font-weight: bold;
}
El cdigo Sass anterior se compila de la siguiente manera:
#main {
color: black;
#main a {
font-weight: bold;
#main a:hover {
color: red;
}
El carcter & siempre debe aparecer al principio de los selectores
compuestos, pero s que puede ir seguido de un sufijo que se aplicar
al selector padre. Ejemplo:
#main {
color: black;
}
El cdigo Sass anterior se compila de la siguiente manera:
#main {
color: black;
#main-sidebar {
}
Si por cualquier circunstancia no se puede aplicar el sufijo al selector
padre, Sass mostrar un mensaje de error indicndote la causa.
.funky {
font: {
family: fantasy;
size: 30em;
weight: bold;
}
El cdigo Sass anterior se compila de la siguiente manera:
.funky {
font-family: fantasy;
font-size: 30em;
font-weight: bold;
}
Tambin es posible aplicar un valor al propio nombre que agrupa las
propiedades:
.funky {
font: 2px/3px {
family: fantasy;
size: 30em;
weight: bold;
}
El cdigo Sass anterior se compila de la siguiente manera:
.funky {
font: 2px/3px;
font-family: fantasy;
font-size: 30em;
font-weight: bold;
Puesta a punto
XHTML
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <title>Proyecto Saas</title>
6 <link rel="stylesheet" href="css/main.css">
7 </head>
8 <body>
9 <nav id="nav" role="navigation">
10 <ul class="menu">
11 <li><a href="#" title="Inicio" >Inicio</a></li>
12 <li><a href="#" title="Quienes Somos">Quienes Somos</a></li>
13 <li><a href="#" title="Contacto">Contacto</a></li>
14 </ul>
15 </nav>
16
17 <div class="contenedor">
18 <h1>Proyecto Sass</h1>
19 <p>Este es nuestro primer proyecto con Sass</p>
20 </div>
21 </body>
22
23 </html>
Dentro de la carpeta scss creamos un archivo que se llame main.scss,
de momento vaco.
Voy a usar Codekit, pero podis usar si tenis Windows Prepos u otro
similar. Tambin podis realizar todo el pre-compilado desde el
Terminal.
Comentarios en Sass
CSS
CSS
1 /* Este comentario s saldr*/
2 body {
3 font-family: Arial, sans-serif;
4 font-size: 100%;
5 font-weight: normal; }
Como veis el comentario con las dos barras inclinadas ha
desaparecido, mientras que el otro s aparece.
Importando en Sass
CSS
1 /*
2 * Importamos los estilos de menu.css
3 */
4 @import "menu.css";
En Sass es diferente. La importacin en un archivo .scss o .sass
se produce durante la compilacin. Adems no tenemos por qu
poner la extensin del archivo.
CSS
1 .menu {
2 margin: 0;
3 padding: 0;
4 list-style-type: none;
5}
6 .menu > li {
7 display: inline-block;
8 margin: 0 0 10px 10px;
9}
Y en main.css ponemos:
CSS
CSS
Anidando Selectores
Esto es probablemente lo primero que empezars a hacer con Sass.
Supongamos que tenemos un cdigo CSS como este:
CSS
1 .contenido {
2 width: 300px;
3 background: #eaeaea;
4}
5 .contenido h2 {
6 font-size: 18px;
7}
8 .contenido p {
9 font-size: 14px;
En un archivo .scss podemos hacer:
CSS
1 .contenido {
2 width: 300px;
3 background: #eaeaea;
4
5 h2 {
6 font-size: 18px;
7 }
8
9 p{
10 font-size: 14px;
11 }
12 }
Esto nos permitir estructurar mucho mejor nuestro cdigo y
simplificarlo.
Anidando propiedades
CSS
1 .boton {
2 text: {
3 decoration: none;
4 transform: uppercase;
5 }
6}
que se transformar en:
CSS
1 .boton {
2 text-decoration: none;
3 text-transform: uppercase;
4}
CSS
1 .contenido {
2 border: 1px solid #999;
3 padding: 10px;
4
5 a{
6 text-decoration: underline;
7
8 &:hover {
9 color: green;
10 }
11 }
aqu & se refiere al elemento a. El resultado ser:
CSS
1 .contenido {
2 border: 1px solid #999;
3 padding: 10px;
4 }
5 .contenido a {
6 text-decoration: undeline;
7 }
8 .contenido a:hover {
9 color: green;
10 }
Tambin se pueden situar selectores antes del smbolo &:
CSS
1 .contenido {
2 width: 300px;
3
4 .esp & {
5 width: 400px;
6 }
7}
en este ejemplo, & equivale a .contenido. El resultado ser:
CSS
1 .contenido {
2 width: 300px;
3}
4 .esp .contenido {
5 width: 400px;
6}
CSS
1 .contenido {
2 background: #eaeaea;
3 .principal {
4 h2 {
5 a{
6 color: blue;
7 &:hover {
8 color: red;
9 }
10 }
11 }
12 }
13 }
obteniendo como resultado un archivo css como este:
CSS
1 .contenido {
2 background: #eaeaea;
3}
4 .contenido .principal h2 a {
5 color: blue;
6}
7 .contenido .principal h2 a:hover {
8 color: red;
9}
lo cual no supone seguir una prctica recomendable en CSS, adems
de introducir unos niveles de especificidad peligrosos para tu hoja de
estilos.
Por regla general intenta limitar el nivel de anidacin a 3 como mucho
(segn las circunstancias).
CSS
1 /* style.css */
2 .btn-a {
3 background: blue;
4 color: white;
5 width: 30px;
6 border-radius: 10px;
7 }
8 .btn-b {
9 background: black;
10 color: white;
11 width: 30px;
12 border-radius: 10px;
13 }
Como vemos, todo se repite salvo el color de fondo. Este es un
ejemplo de repeticin de cdigo que probablemente queramos evitar
en nuestra hoja .scss, y lo podemos hacer gracias a los Mixins (en el
siguiente artculo veremos tambin otra opcin para hacerlo, Extend,
quizs incluso ms recomendada para el caso que acabamos de ver)
CSS
1 /* style.scss */
2 @Mixin botones {
3 color: white;
4 width: 30px;
5 border-radius: 10px;
6 }
7 .btn-a {
8 @include botones;
9 background: blue;
10 }
11 .btn-b {
12 @include botones;
13 background: black;
14 }
Puntos a tener en cuenta:
CSS
1 /* style.css */
2 .btn-a {
3 background: blue;
4 color: white;
5 width: 30px;
6 border-radius: 10px;
7 }
8 .btn-b {
9 background: black;
10 color: white;
11 width: 30px;
12 border-radius: 10px;
13 }
Estaris de acuerdo conmigo que el CSS generado no es muy bueno.
Aunque en el archivo .scss no estbamos repitiendo cdigo, en el
archivo .css resultante s lo estamos haciendo. Sera mucho mejor
generar algo as:
CSS
1 /* style.css */
2 .btn-a, .btn-b {
3 background: blue;
4 color: white;
5 width: 30px;
6 border-radius: 10px;
7 }
8 .btn-b {
9 background: black;
10 }
Pero esto no lo podemos hacer con Mixins, sino con Extend, que
veremos en el siguiente artculo. Lo que acabamos de ver sin embargo
nos sirve apara ver cmo funcionan los Mixins y para qu no son
tiles.
CSS
1 /* style.scss */
2
3 @mixin rounded($radio) {
4 border-radius: $radio;
5 -moz-border-radius: $radio;
6 -webkit-border-radius: $radio;
7 }
8
9 #footer { @include rounded(5px); }
10 #sidebar { @include rounded(8px); }
Como vemos hemos creado un Mixin llamado rounded que tiene como
argumento $radio, que es el radio que se aplicar en border-
radius. El CSS resultante ser:
CSS
1 /* style.css */
2
3 #footer {
4 border-radius: 5px;
5 -moz-border-radius: 5px;
6 -webkit-border-radius: 5px; }
7
8 #sidebar {
9 border-radius: 8px;
10 -moz-border-radius: 8px;
11 -webkit-border-radius: 8px; }
A los argumentos del mixin se les puede dar tambin un valor por
defecto, de tal manera que si al usar el Mixin no se pasa ese
argumento, se le asignar el valor por defecto.
CSS
1 /* style.scss */
2
3 @mixin rounded($radio: 10px)) {
4 border-radius: $radio;
5 -moz-border-radius: $radio;
6 -webkit-border-radius: $radio;
7 }
8
9 #navbar li { @include rounded; }
10 #footer { @include rounded(5px); }
11 #sidebar { @include rounded(8px); }
Y ahora tendramos para #navbar li:
CSS
1 /* style.css */
2
3 #navbar li {
4 border-radius: 10px;
5 -moz-border-radius: 10px;
6 -webkit-border-radius: 10px; }
El uso de Mixins es tan potente que encontraris libreras, pginas
web y artculos de blogs dedicados exclusivamente a compartir Mixins.
Ejemplos (podis encontrar ms implemente buscando en Google):
Bourbon.io
Handy Sass Mixins
Sass Mixins
Mltiples argumentos
CSS
1 /* style.scss */
2 @mixin botones($radio, $color) {
3 border-radius: $radio;
4 color: $color;
5}
6
7 .btn-a
8 @include botones(10px, #000);
que nos dar como resultado:
CSS
1 /* style.css */
2 .btn-a {
3 border-radius: 10px;
4 color: #000;
5}
Los argumentos hay que pasarlos en el @include en el mismo orden
en el que estn definidos en el Mixin. Si nos falta alguno obtendremos
un mensaje de error, a no ser que definamos alguno por defecto:
CSS
1 /* style.scss */
2 @mixin botones($radio, $color:#000 )
3 border-radius: $radio;
4 color: $color;
5}
6 .btn-a {
7 @include botones(10px);
8}
Debemos tener cuidado a la hora de crear la lista de argumentos, ya
que los argumentos por defecto deben ir siempre al final de la
cadena. Es decir, esto nos dar un error:
CSS
1 /* style.scss */
2 @mixin botones($color:#000, $radio)
3 border-radius: $radio;
4 color: $color;
5}
Si son muchos los argumentos que pasamos en nuestro Mixin nos
ayudar utilizar en el @include los nombres de las variables. De
esta manera podemos pasar los argumentos en el orden que
queramos y adems no nos equivocaremos a la hora de asignar los
valores:
CSS
1 /* style.scss */
2 @mixin botones($radio, $color:#000 )
3 border-radius: $radio;
4 color: $color;
5}
6 .btn-a {
7 @include botones($color: #333, $radio: 10px);
8}
Argumentos variables
CSS
1 /* style.css */
2 .btn-a {
3 -webkit-transition: color 0.2s ease-in, background 0.5s ease-out;
4 -moz-transition: color 0.2s ease-in, background 0.5s ease-out;
5 transition: color 0.2s ease-in, background 0.5s ease-out;
6}
Si intentamos pasar este valor con comas como argumento:
CSS
1 /* style.scss */
2 @mixin transition($val) {
3 -webkit-transition: $val;
4 -moz-transition: $val;
5 transition: $val;
6}
7 .btn-a {
8 @include transition(color 0.3s ease-in, background 0.5s ease-out);
9}
Obtendremos el error:
Mixin transition takes 1 argument but 2 were passed (Mixin transition
necesita 1 argumento pero se han pasado 2)
CSS
1 @mixin transition($val...) {
2 /* style.scss */
3 -webkit-transition: $val;
4 -moz-transition: $val;
5 transition: $val;
6 }
7
8 .btn-a {
9 @include transition(color 0.2s ease-in, background 0.5s ease-out);
10 }
Entonces el resultado ser ahora correcto:
CSS
1 /* style.css */
2 .btn-a {
3 -webkit-transition: color 0.2s ease-in, background 0.5s ease-out;
4 -moz-transition: color 0.2s ease-in, background 0.5s ease-out;
5 transition: color 0.2s ease-in, background 0.5s ease-out;
6}
Tambin podemos utilizar los Argumentos Variables en el include,
de tal manera que pasamos todos los valores separados por comas en
una sola variable. Por ejemplo si utilizamos un ejemplo anterior:
CSS
1 /* style.scss */
2 @mixin botones($radio, $color:#000 )
3 border-radius: $radio;
4 color: $color;
5 }
6
7 $propiedades = 10px, #333, ;
8
9 .btn-a {
10 @include botones($propiedades...);
11 }
Como veis pasamos en un argumento variable una lista de valores
separados por comas que es dividida por el Mixin. Hay que tener
cuidado con el orden de los valores.
Interpolacin y Mixins
Cuando hablbamos de variables en Sass nos referamos a la
interpolacin. Recordemos que podemos utilizar #{$variable} para
introducir variables en selectores, nombres de propiedades y cadenas
de texto. Esto nos permitir crear un cdigo ms eficiente en nuestros
mixins. Por ejemplo (este ejemplo es de la propia web de Sass), si
hacemos un mixin para border radius que permita redondear varias
esquinas segn el caso, tendramos que escribir un mixin para cada
combinacin de esquinas. Gracias a la interpolacin lo podemos hacer
con un slo mixin:
Sass
1 /* style.scss */
2
3 @mixin rounded($vert, $horz, $radius: 10px) {
4 border-#{$vert}-#{$horz}-radius: $radius;
5 -moz-border-radius-#{$vert}#{$horz}: $radius;
6 -webkit-border-#{$vert}-#{$horz}-radius: $radius;
7 }
8
9 #navbar li { @include rounded(top, left); }
10 #footer { @include rounded(top, left, 5px); }
11 #sidebar { @include rounded(top, left, 8px); }
y obtendremos:
CSS
1 /* style.css */
2
3 #navbar li {
4 border-top-left-radius: 10px;
5 -moz-border-radius-topleft: 10px;
6 -webkit-border-top-left-radius: 10px; }
7
8 #footer {
9 border-top-left-radius: 5px;
10 -moz-border-radius-topleft: 5px;
11 -webkit-border-top-left-radius: 5px; }
12
13 #sidebar {
14 border-top-left-radius: 8px;
15 -moz-border-radius-topleft: 8px;
16 -webkit-border-top-left-radius: 8px; }
Bueno, eso es todo. En el prximo artculo veremos @extend, ms
recomendable que mixins para ciertas ocasiones (como en el caso del
ejemplo con el que empezamos este artculo).