Home | Clases | Sass y SCSS | Variables, tipos de datos y operadores

Variables, tipos de datos y operadores


Introducción

En este apartado introduciremos los siguientes conceptos:

  • Variables
  • Variables por defecto (!default)
  • Ámbito de variables
  • Tipos de datos
  • Operadores


Variables

El uso de variables en Sass/SCSS es bastante simple: asignamos un valor a un nombre que empiece por $ (como en PHP) y luego podemos referirnos a él en cualquier lugar en vez de referirnos al valor.

Además de la evidentemente reducción de repeticiones y facilidad de refactorización, las variables nos van a permitir realizar operaciones matemáticas, configurar librerías y mucho más.

Las declaraciones de variable son como las declaraciones de propiedades, esto es, :, pero al contrario que las propiedades, las variables se pueden definir en cualquier lugar, sea dentro o fuera de las reglas.

Es importante saber que los nombres de variables son tratados como el resto de identificadores Sass, de modo que los guiones bajos y medios son tratados como iguales, y por tanto $font_size y $font-size harán referencia a la misma variable.

SCSS

$base-color: #c6538c;
$border-dark: rgba($base-color, 0.88);

.alert {
border: 1px solid $border-dark;
}


Sass

$base-color: #c6538c
$border-dark: rgba($base-color, 0.88)

.alert
border: 1px solid $border-dark


CSS

.alert {
border: 1px solid rgba(198, 83, 140, 0.88);
}


Importante: No hay que confundir las variables de Sass/SCSS con las variables de CSS. Éstas últimas pertenecen a CSS puro pero, como es sabido, tienen muchos problemas de compatibilidad entre navegadores, mientras que las variables de Sass/SCSS se trasladan a CSS puro mediante compilación, pero no aparecen en el archivo de salida, con lo que podemos utilizarlas sin problemas de compatibilidad.


Variables por defecto (!default)

Normalmente cuando asignas un valor a una variable que ya tenía un valor, éste se sobre-escribe. En algunos casos, como cuando estemos escribiendo librerías, puede que necesitemos que a la variable se le asigne un valor solo si no estaba definida o su valor era null. Para ello utilizamos el flag !default:

SCSS

// _library.scss
$black: #000 !default;
$border-radius: 0.25rem !default;
$box-shadow: 0 0.5rem 1rem rgba($black, 0.15) !default;

code {
border-radius: $border-radius;
box-shadow: $box-shadow;
}

// style.scss
$black: #222;
$border-radius: 0.1rem;

@import 'library';


Sass

// _library.sass
$black: #000 !default
$border-radius: 0.25rem !default
$box-shadow: 0 0.5rem 1rem rgba($black, 0.15) !default

code
border-radius: $border-radius
box-shadow: $box-shadow

// style.sass
$black: #222
$border-radius: 0.1rem

@import 'library'


CSS

code {
border-radius: 0.1rem;
box-shadow: 0 0.5rem 1rem rgba(#222, 0.15);
}



Ámbito de variables

Como en cualquier lenguaje de programación, debemos considerar el ámbito de las variables. De este modo, cualquier variable declarada al principio de la hoja de estilos será considerada como global y accesible desde cualquier lugar a partir del cual ha sido declarada (incluso en otra hoja de estilos).

SCSS

$global-variable: global value;

.content {
$local-variable: local value;
global: $global-variable;
local: $local-variable;
}

.sidebar {
global: $global-variable;

// Esto fallará porque $local-variable no están en el ámbito:
// local: $local-variable;
}


Sass

$global-variable: global value

.content
$local-variable: local value
global: $global-variable
local: $local-variable


.sidebar
global: $global-variable

// Esto fallará porque $local-variable no están en el ámbito:
// local: $local-variable


CSS

.content {
global: global value;
local: local value;
}

.sidebar {
global: global value;
}



Por el contrario, una variable declarada dentro de un bloque (llaves en Sass o código indentado en SCSS) será considerada como local y solo será accesible dentro de dicho bloque. Además, dicha variable local podría tener incluso el mismo nombre que una global y no afectaría a la anterior. es lo que se conoce como variable local de tipo shadow.

SCSS

$variable: global value;

.content {
$variable: local value;
value: $variable;
}

.sidebar {
value: $variable;
}


Sass

$variable: global value

.content
$variable: local value
value: $variable


.sidebar
value: $variable


CSS

.content {
value: local value;
}

.sidebar {
value: global value;
}



También es posible modificar el valor de una variable global dentro de un ámbito local o bloque (por ejemplo, para un mixin) mediante el uso del flag !global.

SCSS

$variable: first global value;

.content {
$variable: second global value !global;
value: $variable;
}

.sidebar {
value: $variable;
}


Sass

$variable: first global value

.content
$variable: second global value !global
value: $variable


.sidebar
value: $variable


CSS

.content {
value: second global value;
}

.sidebar {
value: second global value;
}


Importante: El flag !global no debe usarse para nuevas variables, solo para aquellas que ya estaba declaradas como globales con anterioridad.


Por último, merece una mención especial el ámbito de variables dentro de las estructuras de control, ya que en este caso lo que hará no será crear una variable local de tipo shadow sino asignar un valor a la variable global original (siempre que dicha variable ya exista, claro).

SCSS

$dark-theme: true !default;
$primary-color: #f8bbd0 !default;
$accent-color: #6a1b9a !default;

@if $dark-theme {
$primary-color: darken($primary-color, 60%);
$accent-color: lighten($accent-color, 60%);
}

.button {
background-color: $primary-color;
border: 1px solid $accent-color;
border-radius: 3px;
}


Sass

$dark-theme: true !default
$primary-color: #f8bbd0 !default
$accent-color: #6a1b9a !default

@if $dark-theme
$primary-color: darken($primary-color, 60%)
$accent-color: lighten($accent-color, 60%)


.button
background-color: $primary-color
border: 1px solid $accent-color
border-radius: 3px


CSS

.button {
background-color: #750c30;
border: 1px solid #f5ebfc;
border-radius: 3px;
}



Tipos de datos

Sass/SCSS permiten trabajar con muchos tipos de datos, muchos de los cuales provienen directamente de CSS:

  • Números, que pueden tener unidades o no, como 12 o 200px.
  • Strings, que pueden tener comillas o no, como "Helvetica Neue" o bold.
  • Colores, que pueden indicarse en hexadecimal (#F00), por el nombre (red), o como funciones (rgb(255,0,00) o hsl(0, 100%, 50%))
  • Listas de valores, que pueden estar separadas por espacios (1.5em 1em 0 2em), comas (Helvetica, Arial) o corchetes ([col1-start]).


y otros son más específicos de Sass/SCSS, siendo los más comunes:

  • Mapas que permiten asociar valores con claves, como ("background": red, "foreground": pink).
  • Booleanos, cuyos posibles valores serán true o false.
  • Null o ausencia de valor, muy útil para el retorno de funciones.


Números

Los números tienen dos componentes, el número en sí y sus unidades, que son opcionales.

La precisión de los valores es de 10 dígitos decimales, lo cual afectará a los operadores y al redondeo, si fuera el caso.

Además, si realizamos operaciones con números, con las unidades también se realizarán dichas operaciones, al igual que en cualquier fórmula matemática del mundo real.

SCSS

@debug 100; // 100
@debug 0.8; // 0.8
@debug 16px; // 16px

@debug 5.2e3; // 5200
@debug 6e-2; // 0.06

@debug 4px * 6px; // 24px*px (serían "square pixels")
@debug 5px / 2s; // 2.5px/s (serían "pixels per second")
@debug 5px * 30deg / 2s / 24em; // 3.125px*deg/s*em, (serían "pixel-degrees per second-em")

$degrees-per-second: 20deg/1s;
@debug $degrees-per-second; // 20deg/s
@debug 1 / $degrees-per-second; // 0.05s/deg

// CSS define una pulgada (inch) como 96 pixeles.
@debug 1in + 6px; // 102px or 1.0625in

@debug 1in + 1s;
// ^^^^^^^^
// Error: Incompatible units s and in.

@debug 0.012345678912345; // 0.0123456789
@debug 0.01234567891 == 0.01234567899; // true
@debug 1.00000000009; // 1
@debug 0.99999999991; // 1


Sass

@debug 100 // 100
@debug 0.8 // 0.8
@debug 16px // 16px

@debug 5.2e3 // 5200
@debug 6e-2 // 0.06

@debug 4px * 6px // 24px*px (serían "square pixels")
@debug 5px / 2s // 2.5px/s (serían "pixels per second")
@debug 5px * 30deg / 2s / 24em // 3.125px*deg/s*em (serían "pixel-degrees per second-em")

$degrees-per-second: 20deg/1s
@debug $degrees-per-second // 20deg/s
@debug 1 / $degrees-per-second // 0.05s/deg

// CSS define una pulgada (inch) como 96 pixeles.
@debug 1in + 6px // 102px or 1.0625in

@debug 1in + 1s
// ^^^^^^^^
// Error: Incompatible units s and in.

@debug 0.012345678912345 // 0.0123456789
@debug 0.01234567891 == 0.01234567899 // true
@debug 1.00000000009 // 1
@debug 0.99999999991 // 1



Por último, es posible operar con unidades e incluso que se realice la conversión necesaria si fuera el caso, aunque hay que asegurarse de que el resultado en unidades sea compatible con CSS.

SCSS

$transition-speed: 1s/50px;

@mixin move($left-start, $left-stop) {
position: absolute;
left: $left-start;
transition: left ($left-stop - $left-start) * $transition-speed;

&:hover {
left: $left-stop;
}
}

.slider {
@include move(10px, 120px);
}


Sass

$transition-speed: 1s/50px

@mixin move($left-start, $left-stop)
position: absolute
left: $left-start
transition: left ($left-stop - $left-start) * $transition-speed

&:hover
left: $left-stop



.slider
@include move(10px, 120px)


CSS

.slider {
position: absolute;
left: 10px;
transition: left 2.2s;
}
.slider:hover {
left: 120px;
}



Strings

Podemos encontrar cadenas de caracteres entre comillas, como "Helvetica Neue" o cadenas de caracteres sin comillas, como bold, así como convertir entre uno y otro mediante las funciones quote() y unquote().

SCSS

@debug unquote(".widget:hover"); // .widget:hover
@debug quote(bold); // "bold"


Sass

@debug unquote(".widget:hover") // .widget:hover
@debug quote(bold) // "bold"



También es posible escapar código de la misma manera que en CSS e incluso usar interpolación o usar índices que devuelven posiciones de caracteres en una cadena.

SCSS

@debug "\""; // '"'
@debug \.widget; // \.widget
@debug "\a"; // "\a" (a string containing only a newline)
@debug "line1\a line2"; // "line1\a line2"

@debug "Helvetica Neue"; // "Helvetica Neue"
@debug "C:\\Program Files"; // "C:\\Program Files"
@debug "\"Don't Fear the Reaper\""; // "\"Don't Fear the Reaper\""
@debug "line1\a line2"; // "line1\a line2"

$roboto-variant: "Mono";
@debug "Roboto #{$roboto-variant}"; // "Roboto Mono"

@debug bold; // bold
@debug -webkit-flex; // -webkit-flex
@debug --123; // --123

$prefix: ms;
@debug -#{$prefix}-flex; // -ms-flex

@debug \21; // \!
@debug \7Fx; // \7f x
@debug str-length(\7Fx); // 5

@debug str-index("Helvetica Neue", "Helvetica"); // 1
@debug str-index("Helvetica Neue", "Neue"); // 11
@debug str-slice("Roboto Mono", -4); // "Mono"


Sass

@debug "\"" // '"'
@debug \.widget // \.widget
@debug "\a" // "\a" (a string containing only a newline)
@debug "line1\a line2" // "line1\a line2" (foo and bar are separated by a newline)

@debug "Helvetica Neue" // "Helvetica Neue"
@debug "C:\\Program Files" // "C:\\Program Files"
@debug "\"Don't Fear the Reaper\"" // "\"Don't Fear the Reaper\""
@debug "line1\a line2" // "line1\a line2"

$roboto-variant: "Mono"
@debug "Roboto #{$roboto-variant}" // "Roboto Mono"

@debug bold // bold
@debug -webkit-flex // -webkit-flex
@debug --123 // --123

$prefix: ms
@debug -#{$prefix}-flex // -ms-flex

@debug \21 // \!
@debug \7Fx // \7f x
@debug str-length(\7Fx) // 5

@debug str-index("Helvetica Neue", "Helvetica") // 1
@debug str-index("Helvetica Neue", "Neue") // 11
@debug str-slice("Roboto Mono", -4) // "Mono"



Colores

Sass/SCSS permiten trabajar en el espacio de color sRGB en cualquiera de las variantes ya conocidas de CSS, pero ademas incluye varias funciones de color, de las cuales se adjunta algún ejemplo a continuación, aunque se explicarán en detalle en apartados posteriores:

SCSS

@debug #f2ece4; // #f2ece4
@debug #b37399aa; // rgba(179, 115, 153, 67%)
@debug midnightblue; // #191970
@debug rgb(204, 102, 153); // #c69
@debug rgba(107, 113, 127, 0.8); // rgba(107, 113, 127, 0.8)
@debug hsl(228, 7%, 86%); // #dadbdf
@debug hsla(20, 20%, 85%, 0.7); // rgb(225, 215, 210, 0.7)

@debug scale-color($venus, $lightness: +15%); // #a893a8 // cambiar la escala de color
@debug mix($venus, midnightblue); // #594d85 //mezclar colores


Sass

@debug #f2ece4 // #f2ece4
@debug #b37399aa // rgba(179, 115, 153, 67%)
@debug midnightblue // #191970
@debug rgb(204, 102, 153) // #c69
@debug rgba(107, 113, 127, 0.8) // rgba(107, 113, 127, 0.8)
@debug hsl(228, 7%, 86%) // #dadbdf
@debug hsla(20, 20%, 85%, 0.7) // rgb(225, 215, 210, 0.7)

$venus: #998099

@debug scale-color($venus, $lightness: +15%) // #a893a8 cambiar la escala de color
@debug mix($venus, midnightblue) // #594d85 //mezclar colores



Listas

Las listas contienen secuencias de valores, normalmente separados por comas o espacios, y encerrados entre corchetes de manera opcional. A efectos prácticos, podemos decir que cualquier valor individual es tratado como una lista con un único valor.

Hay una serie de funciones que nos permiten trabajar con listas de valores, de las cuales se adjunta algún ejemplo a continuación, aunque se explicarán en detalle en apartados posteriores:

SCSS

//Acceder a un elemento
@debug nth(10px 12px 16px, 2); // 12px
@debug nth([line1, line2, line3], -1); // line3

//Añadir a la lista
@debug append(10px 12px 16px, 25px); // 10px 12px 16px 25px
@debug append([col1-line1], col1-line2); // [col1-line1, col1-line2]

//Buscar en la lista
@debug index(1px solid red, 1px) // 1
@debug index(1px solid red, solid) // 2
@debug index(1px solid red, dashed) // null


Sass

//Acceder a un elemento
@debug nth(10px 12px 16px, 2) // 12px
@debug nth([line1, line2, line3], -1) // line3

//Añadir a la lista
@debug append(10px 12px 16px, 25px) // 10px 12px 16px 25px
@debug append([col1-line1], col1-line2) // [col1-line1, col1-line2]

//Buscar en la lista
@debug index(1px solid red, 1px) // 1
@debug index(1px solid red, solid) // 2
@debug index(1px solid red, dashed) // null


Importante: Las listas de Sass/SCSS son inmutables, esto es, todas las funciones devolverán una nueva lista sin afectar a la original. Para modificar la lista original, debemos asignar a esa misma variable el valor modificado.


Mapas

Los mapas contienen pares de índices y valores, y hacen más sencillo asignar un valor a partir de su correspondiente índice.

Es posible añadir elementos al mapa mediante la función map-merge(), pero hay que tener en cuenta que los mapas son inmutables, por lo que en ningún caso estaremos modificando la lista original, a no ser que asignemos el neuvo mapa a otra variable.

SCSS

$font-weights: ("regular": 400, "medium": 500, "bold": 700);

@debug map-get($font-weights, "medium"); // 500
@debug map-get($font-weights, "extra-bold"); // null

$light-weights: ("lightest": 100, "light": 300);
$heavy-weights: ("medium": 500, "bold": 700);

@debug map-merge($light-weights, $heavy-weights);
// (
// "lightest": 100,
// "light": 300,
// "medium": 500,
// "bold": 700
// )

$font-weights: ("regular": 400, "medium": 500, "bold": 700);

@debug map-merge($font-weights, ("extra-bold": 900));
// ("regular": 400, "medium": 500, "bold": 700, "extra-bold": 900)

$font-weights: ("regular": 400, "medium": 500, "bold": 700);

@debug map-merge($font-weights, ("medium": 600));
// ("regular": 400, "medium": 600, "bold": 700)

$prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms);

@mixin add-browser-prefix($browser, $prefix) {
$prefixes: map-merge($prefixes-by-browser, ($browser: $prefix));
}

@include add-browser-prefix("opera", o);
@debug $prefixes-by-browser;
// ("firefox": moz, "safari": webkit, "ie": ms, "opera": o)


Sass

$font-weights: ("regular": 400, "medium": 500, "bold": 700)

@debug map-get($font-weights, "medium") // 500
@debug map-get($font-weights, "extra-bold") // null

$light-weights: ("lightest": 100, "light": 300)
$heavy-weights: ("medium": 500, "bold": 700)

@debug map-merge($light-weights, $heavy-weights)
// (
// "lightest": 100,
// "light": 300,
// "medium": 500,
// "bold": 700
// )

$font-weights: ("regular": 400, "medium": 500, "bold": 700)

@debug map-merge($font-weights, ("extra-bold": 900))

$font-weights: ("regular": 400, "medium": 500, "bold": 700)

@debug map-merge($font-weights, ("medium": 600))
// ("regular": 400, "medium": 600, "bold": 700)

$prefixes-by-browser: ("firefox": moz, "safari": webkit, "ie": ms)

@mixin add-browser-prefix($browser, $prefix)
$prefixes: map-merge($prefixes-by-browser, ($browser: $prefix))


@include add-browser-prefix("opera", o)
@debug $prefixes-by-browser
// ("firefox": moz, "safari": webkit, "ie": ms, "opera": o)



Además, podemos trabajar con el mapa de modo que hagamos algo para cada par valor e índice:


SCSS

$icons: ("eye": "\f112", "start": "\f12e", "stop": "\f12f");

@each $name, $glyph in $icons {
.icon-#{$name}:before {
display: inline-block;
font-family: "Icon Font";
content: $glyph;
}
}


Sass

$icons: ("eye": "\f112", "start": "\f12e", "stop": "\f12f")

@each $name, $glyph in $icons
.icon-#{$name}:before
display: inline-block
font-family: "Icon Font"
content: $glyph


CSS

@charset "UTF-8";
.icon-eye:before {
display: inline-block;
font-family: "Icon Font";
content: "";
}

.icon-start:before {
display: inline-block;
font-family: "Icon Font";
content: "";
}

.icon-stop:before {
display: inline-block;
font-family: "Icon Font";
content: "";
}


Importante: Al igual que las listas, los mapas de Sass/SCSS son inmutables, esto es, todas las funciones devolverán un nuevo mapa sin afectar al original. Para modificar el mapa original, debemos asignar a esa misma variable el valor modificado.


Booleanos

Como en muchos lenguajes de programación, los booleanos, ademas de como valores literales, son usados por las funciones de comparación y relación para devolver resultados.

SCSS

@debug 1px == 2px; // false
@debug 1px == 1px; // true
@debug 10px < 3px; // false
@debug comparable(100px, 3in); // true (tiene uniddaes compatibles para operar con ellas)

@debug true and true; // true
@debug true and false; // false

@debug true or false; // true
@debug false or false; // false

@debug not true; // false
@debug not false; // true

@debug if(true, 10px, 30px); // 10px
@debug if(false, 10px, 30px); // 30px


Sass

@debug 1px == 2px // false
@debug 1px == 1px // true
@debug 10px < 3px // false
@debug comparable(100px, 3in) // true

@debug true and true // true
@debug true and false // false

@debug true or false // true
@debug false or false // false

@debug not true // false
@debug not false // true

@debug if(true, 10px, 30px) // 10px
@debug if(false, 10px, 30px) // 30px



Nota: A diferencia de otros lenguajes, Sass/SCSS no considera valores vacíos o 0 como false.

También es posible utilizar booleanos para evaluar si se debe hacer algo o no en un mixin, por ejemplo:

SCSS

@mixin avatar($size, $circle: false) {
width: $size;
height: $size;

@if $circle {
border-radius: $size / 2;
}
}

.square-av { @include avatar(100px, $circle: false); }
.circle-av { @include avatar(100px, $circle: true); }


Sass

@mixin avatar($size, $circle: false)
width: $size
height: $size

@if $circle
border-radius: $size / 2

.square-av
@include avatar(100px, $circle: false)
.circle-av
@include avatar(100px, $circle: true)


CSS

.square-av {
width: 100px;
height: 100px;
}

.circle-av {
width: 100px;
height: 100px;
border-radius: 50px;
}



Null

El valor null representa la ausencia de valor, y es devuelto por funciones para indicar que no hay resultado.

SCSS

@debug str-index("Helvetica Neue", "Roboto"); // null
@debug map-get(("large": 20px), "small"); // null
@debug &; // null

//Si la lista contiene un null, éste es omitido en el CSS generado
$fonts: ("serif": "Helvetica Neue", "monospace": "Consolas");

h3 {
font: 18px bold map-get($fonts, "sans");
}

//Si el valor de la propiedad es null, la propiedad se omite por completo
$fonts: ("serif": "Helvetica Neue", "monospace": "Consolas");

h3 {
font: {
size: 18px;
weight: bold;
family: map-get($fonts, "sans");
}
}


Sass

@debug str-index("Helvetica Neue", "Roboto") // null
@debug map-get(("large": 20px), "small") // null
@debug & // null

//Si la lista contiene un null, éste es omitido en el CSS generado
$fonts: ("serif": "Helvetica Neue", "monospace": "Consolas")

h3
font: 18px bold map-get($fonts, "sans")

//Si el valor de la propiedad es null, la propiedad se omite por completo
$fonts: ("serif": "Helvetica Neue", "monospace": "Consolas")

h3
font:
size: 18px
weight: bold
family: map-get($fonts, "sans")



CSS

h3 {
font: 18px bold;
}

h3 {
font-size: 18px;
font-weight: bold;
}



Operadores

Como en la mayoría de los lenguajes, podemos utilizar diferentes tipos de operadores, tanto matemáticos como relacionales o de comparación, el funcionamiento es bastante similar:

  • == y != se usan para comprobar si dos valores son iguales o no
  • +, -, *, / y % efectúan la correspondiente operación matemática entre los valores
  • <, <=, > y >= son los operadores de comparación
  • and, or y not tienen el comportamiento usual de los operadores booleanos
  • +, - y / también se pueden usar para encadenar strings, si bien - y / funcionan como operadores unarios y están en desuso


Por último, es importante saber cuál es el orden de mayor a menor prioridad en el que se efectúan las operaciones (y aplicar paréntesis de forma matemática en nuestras expresiones si fuera necesario):

  • Los operadores unarios not, +, - y /
  • Los operadores matemáticos *, / y %
  • Los operadores matemáticos + y -
  • Los operadores de comparación <, <=, > y >=
  • Los operadores de igualdad == y !=
  • El operador booleano and
  • El operador booleano or
  • El operador = (en desuso, antes se usaba en funciones para mantener la compatibilidad con Internet Explorer)


Referencias


Fecha de publicación: 15/04/2019
Asignaturas: aplicaciones webdiseño de interfaces web
Temas: css css3 sass scss less preprocesadores
Utilizamos cookies propias y de terceros para mejorar su experiencia en la navegación. Al seguir navegando entendemos que acepta su uso.
Si lo desea, consulte nuestras políticas de privacidad y cookies
ENTENDIDO
[X] Cerrar

Contacta conmigo


[X] Cerrar

Acceso alumnos