sass
Conceptos Clave de Sass
- Sass/SCSS amplía CSS con:
- Partials
- Variables, Maps & Lists
- Nesting avanzado
- Mixins
- Funciones
- Herencia (
@extend) - Operadores y lógica
- Modularización real
Partials en Sass
- Los partials permiten dividir tu código en archivos reutilizables.
- Siempre deben comenzar con underscore:
- Ejemplo:
_variables.scss,_base.scss.
- Ejemplo:
- Se importan así:
@use "variables";
@use "mixins";
`
Nota moderna:
Evitar@import, ya está deprecated.
Usar@usey@forward.
Variables y Mapas
Variables simples
$color-primary: #4f46e5;
$spacing-base: 1rem;
Variables como listas
$sizes: 0.5rem, 1rem, 2rem;
Mapas para temas y colores
$colors: (
"primary": #4f46e5,
"secondary": #9333ea,
"success": #16a34a,
"warning": #eab308
);
Acceso:
color: map-get($colors, "primary");
Mixins (Incluye creación dinámica de variables)
- Los mixins permiten código reutilizable:
@mixin flex-center {
display: flex;
justify-content: center;
align-items: center;
}
Mixin para generar variables a partir de un mapa de colores
@mixin generate-color-vars($color-map) {
@each $name, $value in $color-map {
--#{$name}: #{$value};
}
}
:root {
@include generate-color-vars($colors);
}
Nesting Avanzado
Selector padre con &
Útil para BEM:
.button {
padding: 1rem;
&__icon {
margin-right: .5rem;
}
&--primary {
background: $color-primary;
}
}
&__ y metodología BEM
&__element→ elemento del bloque&--modifier→ variante
.card {
&__title { font-size: 1.2rem; }
&--highlight { border-color: map-get($colors, "warning"); }
}
Funciones útiles
Sass incluye funciones listas para usar:
lighten()darken()mix()adjust-hue()rgba()
Ejemplo:
.button {
background: lighten(map-get($colors, "primary"), 15%);
}
Operadores y Tamaños Dinámicos
$base: 1rem;
padding: $base * 2;
border-radius: $base / 2;
Recomendación Moderna: unidades dvh, svh, lvh
- Usar
dvh,svh,lvhen lugar devhpara vistas móviles:dvh: viewport dinámico realsvh: viewport estable (barra naveg.)lvh: viewport más grande
Ejemplo:
.hero {
min-height: 100dvh;
}
Prefixes — automatización
No escribas prefijos manualmente.
Usar Autoprefixer + Sass o Webpack/Vite.
Ejemplo de mixin manual (solo si es necesario):
@mixin transform($value) {
-webkit-transform: $value;
-ms-transform: $value;
transform: $value;
}
Estructura Sugerida de Proyecto Sass
/scss
/_variables.scss
/_mixins.scss
/_reset.scss
/_base.scss
/components/
_buttons.scss
_cards.scss
main.scss
main.scss:
@use "variables";
@use "mixins";
@forward "components/buttons";
@forward "components/cards";
Ejemplo Completo con BEM + Variables + Mixins
$colors: (
"primary": #6366f1,
"dark": #0f172a
);
@mixin shadow {
box-shadow: 0 5px 15px rgba(0,0,0,.1);
}
.card {
padding: 1.5rem;
background: white;
border-radius: .8rem;
@include shadow;
&__title {
color: map-get($colors, "primary");
margin-bottom: .5rem;
}
&__content {
color: map-get($colors, "dark");
line-height: 1.5;
}
}
Tips Rápidos Sass
- Evitar nesting profundo (+3 niveles).
- Centralizar colores y espacios en mapas.
- Usar mixins para media queries:
@mixin mq($size) {
@media (min-width: $size) { @content; }
}
Recursos
Sass — Patrones Avanzados para Proyectos Grandes
Arquitectura y Organización Avanzada
- 7-1 Pattern (adaptado)
abstracts/→ variables, funciones, mixins, placeholders.base/→ resets, tipografías, helpers globales.components/→ botones, cards, modales (modularidad estricta).layout/→ grid, header, footer, navegación.pages/→ estilos específicos por página.themes/→ dark/light y variantes de marca.vendors/→ libs externas.
- Reglas:
- Importar solo desde
main.scss. - Un módulo Sass = un único objetivo (SRP).
- Evitar dependencias cruzadas: los componentes no deben importar otros componentes.
- Importar solo desde
Variables y Configuración Escalable
- Usar mapas de configuración en vez de listas sueltas:
$grid: (
columns: 12,
gutter: 2rem,
max-width: 1200px
);
```
- Variables dependientes y calculadas:
```scss
$spacing-unit: 1rem;
$spacing-xl: $spacing-unit * 4;
```
- Uso de **CSS custom properties** generadas desde Sass:
```scss
:root {
@each $name, $value in $colors {
--#{$name}: #{$value};
}
}
```
## Mixins Profesionales y Reutilizables
- **media queries + maps**
```scss
$breakpoints: (
sm: 480px,
md: 768px,
lg: 1280px
);
@mixin respond($bp) {
@media (min-width: map-get($breakpoints, $bp)) {
@content;
}
}
```
- **Mixin para layout fluido con `clamp`**
```scss
@mixin fluid-size($min, $max) {
font-size: clamp(#{$min}, 1vw + #{$min}, #{$max});
}
```
- **Generación automática de utilidades**
```scss
$spacings: (0, 4px, 8px, 16px, 24px);
@each $space in $spacings {
.m-#{$space} { margin: $space; }
.p-#{$space} { padding: $space; }
}
```
## Patrones Avanzados de Anidación
- Uso estratégico de `&` sin romper BEM:
```scss
.card {
&__header { ... }
&__body { ... }
&--featured { ... }
&:hover &__header {
opacity: .8;
}
}
```
- Combinación de `@at-root` para evitar cascadas profundas:
```scss
.sidebar {
@at-root .is-collapsed & {
width: 60px;
}
}
```
## Patrones Avanzados con Placeholders
- Componentes base reutilizables:
```scss
%btn-base {
display: inline-flex;
align-items: center;
border-radius: .5rem;
font-weight: 600;
}
.btn-primary {
@extend %btn-base;
background: var(--primary);
}
```
- Extensiones condicionadas con mixins:
```scss
@mixin interactive {
@extend %btn-base;
transition: .2s;
cursor: pointer;
}
```
## Diseño Temático (Dark Mode, Brands)
- Múltiples temas usando mapas y loops:
```scss
$themes: (
dark: (bg: #111, text: #eee),
light: (bg: #fff, text: #111)
);
@each $theme, $props in $themes {
.theme-#{$theme} {
@each $prop, $val in $props {
--#{$prop}: #{$val};
}
}
}
```
- Componentes que usan solo variables CSS:
```scss
.card {
background: var(--bg);
color: var(--text);
}
```
## Patrones para Componentes Complejos
- **Cards configurables vía mixins**
```scss
@mixin card($padding: 1rem, $radius: .75rem) {
padding: $padding;
border-radius: $radius;
background: var(--bg);
box-shadow: 0 4px 12px rgba(0,0,0,.08);
}
.card { @include card(); }
.card--compact { @include card(.5rem, .5rem); }
```
- **Estados dinámicos reduciendo repetición**
```scss
$states: (success: #4caf50, error: #e53935, warning: #fb8c00);
@each $state, $color in $states {
.badge-#{$state} {
background: $color;
color: white;
}
}
```
## Optimización, Rendimiento y Mantenibilidad
- Evitar generar CSS gigantes:
- Revisar loops grandes.
- Generar utilidades solo si el proyecto lo requiere.
- Evitar `@extend` entre componentes no relacionados.
- Preferir **CSS custom properties** para:
- theming
- runtime changes
- animaciones dinámicas
- Mantener profundidad de anidación ≤ 3 niveles.
- Uso de `dvh`, `svh`, `lvh` en layout responsive:
```scss
min-height: 100dvh;
```
## Debugging Avanzado
- `@debug`, `@warn`, impresiones de mapas y estructuras:
```scss
@debug map-keys($themes);
@warn "Deprecado: usar spacing v2.";
```
- Inspección dentro de mixins:
```scss
@mixin check($value) {
@debug "Valor recibido: #{$value}";
}
```
# Sass Cheatsheet — Resumen Rápido
- [CSS](/frontend/css/)
- [Sass Documentation](https://sass-lang.com/documentation/)
## Sintaxis Básica
- Sass (indentation-based):
``` sass $color: #333
body
color: $color
- SCSS (CSS-like):
$color: #333; body { color: $color; }
Variables
$primary-color: #3498db; $spacing-unit: 1rem; body { color: $primary-color; margin: $spacing-unit * 2; }
- Mapas:
$colors: ( primary: #3498db, secondary: #2ecc71 ); color: map-get($colors, primary);
- Fallback:
color: var(--my-color, #333);
Nesting (Anidamiento)
.nav { ul { list-style: none; li { display: inline-block; } } }
- Operador
&:
.button { &--primary { background: blue; } &:hover { opacity: 0.8; } }
Mixins
@mixin respond($breakpoint) { @media (min-width: $breakpoint) { @content; } } .container { @include respond(768px) { width: 750px; } }
- Mixins con argumentos y contenido:
@mixin card($padding: 1rem) { padding: $padding; border-radius: .5rem; @content; } .card { @include card { background: #fff; } }
Partials & Imports
- Crear
_variables.scss,_mixins.scss
@import "variables"; @import "mixins";
- Compilación:
sass main.scss main.css --watch
Funciones
- Matemáticas:
+,-,*,/,% - Color:
lighten($color, 20%),darken($color, 10%),mix($color1, $color2, 50%) - Listas:
nth($list, 2),length($list),append($list, value) - Mapas:
map-get($map, key),map-keys($map),map-values($map)
Loops
@for:
@for $i from 1 through 5 { .col-#{$i} { width: 20% * $i; } }
@each:
$colors: red, blue, green; @each $color in $colors { .text-#{$color} { color: $color; } }
@while:
$i: 0; @while $i < 5 { .item-#{$i} { margin: $i * 1rem; } $i: $i + 1; }
Placeholders
%btn-base { display: inline-block; padding: .5rem 1rem; } .button { @extend %btn-base; }
Conditional Statements
$theme: dark; body { @if $theme == dark { background: #111; color: #eee; } @else { background: #fff; color: #111; } }
Functions Personalizadas
@function double($value) { @return $value * 2; } .box { width: double(10px); }
Media Queries Responsivas
- Usando mixins:
$breakpoints: (sm: 480px, md: 768px, lg: 1024px); @mixin respond($bp) { @media (min-width: map-get($breakpoints, $bp)) { @content; } } .container { @include respond(md) { width: 750px; } }
Generación Automática de Utilidades
$spacings: 0, 4px, 8px, 16px; @each $space in $spacings { .m-#{$space} { margin: $space; } .p-#{$space} { padding: $space; } }
Tips Avanzados
- Preferir mapas para theming y configuraciones.
- Evitar loops grandes en producción.
- Mantener anidamiento ≤ 3 niveles.
- Usar CSS variables para runtime changes:
:root { --primary: #3498db; }
dvh,svh,lvhpara layouts responsive:
min-height: 100dvh;
¿Te gusta este contenido? Suscríbete vía RSS