====== 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.