====== 4. SASS Avanzado ======
Veamos ahora funcionalidades mas avanzadas de SASS
==== Mas información ====
Enlaces con mas información de SASS:
* [[https://sass-guidelin.es/|Sass Guidelines]]
* [[https://sass-lang.com/documentation/at-rules/mixin/|Sass: @mixin and @include]]
* [[https://sass-lang.com/documentation/at-rules/function/|Sass: @function]]
* [[http://thesassway.com/intermediate/if-for-each-while|Sass control directives: @if, @for, @each and @while]]
* [[https://sass-lang.com/documentation/at-rules/control/if|Sass: @if and @else]]
* [[https://sass-lang.com/documentation/at-rules/control/for|Sass: @for]]
* [[https://sass-lang.com/documentation/at-rules/control/each#with-maps|sass: @each with maps]]
===== Mixings =====
Son como trozos de código CSS que puedes añadir en otra clase CSS. Es como llamar a una "función" pero con CSS. Son muy útiles para evitar repetir código CSS.
@mixin box-shadow($color) {
-webkit-box-shadow: 2px 10px 24px $color;
-moz-box-shadow: 2px 10px 24px $color;
box-shadow: 2px 10px 24px $color;
}
.c-button {
color: #FF0000;
@include box-shadow(#FF0000);
}
.c-panel {
color: #00FF00;
@include box-shadow(#00FF00);
}
se transforma en
.c-button {
color: #FF0000;
-webkit-box-shadow: 2px 10px 24px #FF0000;
-moz-box-shadow: 2px 10px 24px #FF0000;
box-shadow: 2px 10px 24px #FF0000;
}
.c-panel {
color: #00FF00;
-webkit-box-shadow: 2px 10px 24px #00FF00;
-moz-box-shadow: 2px 10px 24px #00FF00;
box-shadow: 2px 10px 24px #00FF00;
}
===== Funciones =====
En SASS también existen funciones "normales" que calculan un valor.
@function getBorderSize($size) {
@return 10px * $size;
}
.c-button {
color: #FF0000;
border: getBorderSize(2) solid #00FF00;
}
se transforma en
.c-button {
color: #FF0000;
border: 20px solid #00FF00;
}
===== Arrays =====
Veamos ahora como usar los arrays
* Para acceder a un elemento de un array se usa la función ''nth''. **El índice empieza por 1 y no por cero**.
$lista:(10px,12px,20px,40px);
$indice:1;
$valor:nth($lista,$indice);
* Para obtener el tamaño de un array se usa la función ''length'':
$lista:(10px,12px,20px,40px);
$tamanyo:length($lista);
===== Mapas =====
Veamos ahora las funciones de maps
* Para acceder a un elemento de un map se usa la función ''map-get'':
$mapa:(
"a": enero,
"b": febrero
);
$clave:a;
$valor:map-get($mapa,$clave);
* Para obtener las claves de un map.:
$mapa:(
"a": enero,
"b": febrero
);
$keys:map-keys($mapa);
Se obtiene un array los valores ''a'' y ''b''.
===== Bucle @for to =====
Se usa para hacer un bucle desde ''0'' a ''n-1''
* Bucle con índice.
@for $i from 0 to 4 {
.g--border-#{$i} {
border: 10px * $i solid #00FF00;
}
}
se transforma en
.g--border-0 {
border: 0px solid #00FF00;
}
.g--border-1 {
border: 10px solid #00FF00;
}
.g--border-2 {
border: 20px solid #00FF00;
}
.g--border-3 {
border: 30px solid #00FF00;
}
===== Bucle @for through =====
Se usa para hacer un bucle desde ''1'' hasta ''n''
* Bucle con índice.
@for $i from 1 through 4 {
.g--border-#{$i} {
border: 10px * $i solid #00FF00;
}
}
se transforma en
.g--border-1 {
border: 10px solid #00FF00;
}
.g--border-2 {
border: 20px solid #00FF00;
}
.g--border-3 {
border: 30px solid #00FF00;
}
.g--border-4 {
border: 40px solid #00FF00;
}
===== Bucle @each de un array =====
Recorre los elementos de una lista
$lista:(3px,6px,7px,9px);
@each $value in $lista {
.g--padding-#{$value} {
padding: $value;
}
}
.g--padding-3px {
padding: 3px;
}
.g--padding-6px {
padding: 6px;
}
.g--padding-7px {
padding: 7px;
}
.g--padding-9px {
padding: 9px;
}
===== Bucle @each de un Map =====
Para recorrer un map la forma más sencilla es la siguiente:
$map:(
"s":3px,
"m":6px,
"l":7px,
"xl":9px
);
@each $key,$value in $map {
.g--padding-#{$key} {
padding: $value;
}
}
.g--padding-s {
padding: 3px;
}
.g--padding-m {
padding: 6px;
}
.g--padding-l {
padding: 7px;
}
.g--padding-xl {
padding: 9px;
}
===== Condicional @if =====
@mixin border($size) {
$color:#00FF00;
@if $size>=3 {
$color:#FF0000;
}
border: $size*2 solid $color;
}
.c-caja1 {
color: #FF0000;
@include border(2px);
}
.c-caja2 {
color: #FF0000;
@include border(5px);
}
se transforma en
.c-caja1 {
color: #FF0000;
border: 4px solid #00FF00;
}
.c-caja2 {
color: #FF0000;
border: 10px solid #FF0000;
}
===== Funciones de Color =====
Ya existen una serie de funciones predefinidas en SASS: [[https://www.w3schools.com/sass/sass_functions_color.asp|Sass Color Functions]]
Entre las mas útiles están:
* lighten: Incrementa la luminosidad de un color
* darken: Decrementa la luminosidad de un color
* saturate: Incrementa la saturación de un color
* desaturate: Decrementa la saturación de un color
$color-fondo: #F456E3;
$color-borde: darken($color-fondo,30%);
.c-caja {
background-color: $color-fondo;
border: 4px solid $color-borde;
}
se transforma en
.c-caja {
background-color: #F456E3;
border: 4px solid #a60b95;
}
===== Variables CSS =====
En CSS existen las variables. La ventaja de las variables CSS vs las de SASS son:
* Se pueden cambiar en tiempo de ejecución desde JavaScript
* Pueden existir a nivel local dentro de los selectores.
Veamos como funcionan.
* Los nombres de las variables debe empezar por ''--''
* Para usar las variables en CSS se usa ''var(--nombre-variable)''
* Las variables de CSS se crean así:
:root {
--color-alternativo-5: #0056b8;
}
* Desde CSS se usan así.
.c-button {
background-color:var(--color-alternativo-5)
}
* Se puede definir un valor por defecto como segundo parámetro
.c-button {
background-color:var(--color-alternativo-5,#FF0000)
}
Esto permite que podamos crear más valores por defecto con el siguiente truco de forma que si no está una variable, usemos otra y sino otra ,etc.:
.c-button {
background-color:var(--color-alternativo-5,var(--color-alternativo,#FF0000))
}
Es este caso el ''background-color'' se usa la variable ''--color-alternativo-5'' pero si no existe esa variable se usaría la variable ''--color-alternativo'' pero si esa tampoco existe se usará ''#FF0000''
* Desde JavaScript se modifican así:
let root = document.documentElement;
root.style.setProperty('--color-normal-5', "#FF0000");
* Desde JavaScript se leen así:
let root = document.documentElement;
let colorNormal=getComputedStyle(root).getPropertyValue("--color-normal-5");
==== Creación de variables ====
A lo largo del curso hemos visto que debemos limitar nuestras opciones a usar serie de valores. Ahora esa serie de valores deben ser variables.
$paddings:(
"xs":"1px",
"s":"2px",
"m":"6px",
"l":"12px",
"xl":"20px"
);
:root {
@each $key,$value in $paddings {
--padding-#{$key}:$value;
}
}
Que generá en CSS
:root {
--padding-xs:1px;
--padding-s:2px;
--padding-m:6px;
--padding-l:12px;
--padding-xl:20px;
}
Esa variables se usarán siempre tanto en los componentes , como layouts, como globales.
.c-button {
--c-button-padding-vertical:var(--padding-s,6px);
--c-button-padding-horizontal:var(--padding-m,8px);
padding-top: var(--c-button-padding-vertical);
padding-bottom: var(--c-button-padding-vertical);
padding-left: var(--c-button-padding-horizontal);
padding-right: var(--c-button-padding-horizontal);
}
.g--padding-vertical-m {
padding-top: var(--padding-m);
padding-bottom: var(--padding-m);
}
El usar variable nos lleva a tener muchísimas variables en CSS lo que nos puede llevar a pensar si eso afectará al rendimiento. En el documento {{ :clase:daw:diw:1eval:css_variables_performance_benchmark_2021_by_konrad_fedorczyk_medium.pdf |CSS Variables performance benchmark 2021}} nos indica que no afecta prácticamente nada al rendimiento.
===== Bootstrap =====
En el siguiente artículo [[https://getbootstrap.com/docs/5.0/utilities/api/|Utility API]], vemos como Boostrap ha creado algo muy similar a lo que estamos haciendo en clase.
===== Ejercicios =====
==== Ejercicio 1 ====
{{:clase:daw:diw:1eval:sombras_y_profundidad.png|}}
* Crea los globales de forma que retorne cada una de los sombreados. Sabiendo que las claves empiezan en 1 y hay otra que será ''none''.
g--shadow-none { }
g--shadow-1 { }
g--shadow-2 { }
g--shadow-3 { }
g--shadow-4 { }
g--shadow-5 { }
* Crea las variables CSS correspondientes.
* Crea el mixing ''box-shadow($key)''. Usará las funciones que has creado antes y de forma que tenga las propiedades css de:
* ''-webkit-box-shadow''
* ''-moz-box-shadow''
* ''box-shadow''
==== Ejercicio 2 ====
Haz una función llamada ''getFontSize($index)'' para ayudar a generar tamaños de fuentes. Siendo el parámetro ''$index'' un número entero.
Calcula el tamaño de la fuente con la siguiente fórmula:
$$ {Tamaño \quad fuente \quad en \quad px}=1.2^{\$index}*16 $$
La función retornará el tamaño de la fuente en base al parámetro ''$index''. Este función tiene 2 números //mágicos//. El 16 es el tamaño base de la fuente. Es decir cuando vale 0. Y el 1,2 es la tasa de crecimiento. Cuando mayor sea ese número mas rápidamente se hacen grandes los tamaños de fuentes. Una página que hace estos mismos cálculos es [[https://www.modularscale.com/?16&px&1.2|Modularscale]].
Para hacer los cálculos de potencias en SASS puedes consultar el siguiente artículo: [[https://css-tricks.com/snippets/sass/power-function/|SASS Power Function]]
Haz que usando la función ''getFontSize($tamanyo)'' y un bucle se generen automáticamente las siguientes clases CSS:
g--font-size-3s { font-size:9.25px; }
g--font-size-2s { font-size:11,11px; }
g--font-size-1s { font-size:13,33px; }
g--font-size { font-size:16px; }
g--font-size-1l { font-size:19.2px; }
g--font-size-2l { font-size:23.04px; }
.....
g--font-size-6l { font-size:47.775px; }
==== Ejercicio 3 ====
Crea los globales y las variable CSS de los siguientes colores:
{{:clase:daw:diw:1eval:paleta_de_colores.png|}}
==== Ejercicio 4 ====
Modifica la clase ''c-button'' del tema 1 para que ahora haga uso de variables CSS en los paddings, etc.