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.
  • Se importan así:
@use "variables";
@use "mixins";

`

Nota moderna:
Evitar @import, ya está deprecated.
Usar @use y @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, lvh en lugar de vh para vistas móviles:
    • dvh: viewport dinámico real
    • svh: 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.

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, lvh para layouts responsive:

min-height: 100dvh;