El browser recibe CSS compilado. El build forma parte del producto.
Aprendé SASS construyendo estilos que escalan.
Una ruta de cero a arquitectura modular: entendé por qué existe SASS, cómo organizar un proyecto real y cuándo conviene usar cada herramienta sin convertir el CSS en magia difícil de mantener.
Qué resuelve SASS y qué no
SASS es un preprocesador: escribís SCSS y una herramienta lo transforma en CSS que entiende el navegador. Su valor aparece cuando necesitás reutilizar decisiones de diseño, separar responsabilidades y reducir repetición.
Seguís necesitando dominar cascade, especificidad, layout y responsive.
$brand: #cf649a;
.button {
background: $brand;
&:hover { filter: brightness(1.1); }
}¿Quién interpreta finalmente los estilos?
Variables, nesting y decisiones reutilizables
Las variables representan decisiones del sistema visual. El nesting ayuda a expresar relaciones, pero debe mantenerse poco profundo para evitar selectores demasiado específicos.
$color-primary: #3178c6;
$space-md: 1rem;
$radius: .75rem;
.card {
padding: $space-md;
border-radius: $radius;
&__title { color: $color-primary; }
&:hover { transform: translateY(-2px); }
}$color-primary comunica mejor que $blue-500 cuando representa una decisión de producto.
Más profundidad suele indicar que el componente está demasiado acoplado al HTML.
Partials, @use y una base mantenible
Dividí los estilos por responsabilidad y componelos desde un único entry point. Preferí @use sobre el antiguo @import: evita fugas globales y hace explícitas las dependencias.
sass/
├── base/
│ ├── _variables.scss
│ ├── _mixins.scss
│ └── _reset.scss
├── components/
│ ├── _buttons.scss
│ └── _cards.scss
├── layout/
│ ├── _header.scss
│ └── _main.scss
└── styles.scss@use 'base/reset';
@use 'layout/header';
@use 'layout/main';
@use 'components/buttons';¿Qué estrategia reduce mejor el acoplamiento?
Mixins, funciones y cuándo usarlos
Un mixin es útil cuando reutilizás un patrón de declaraciones. Una función es mejor cuando necesitás calcular y devolver un valor. No abstraigas algo que sólo usás una vez.
@mixin focus-ring($color) {
outline: 3px solid rgba($color, .35);
outline-offset: 3px;
}
.button:focus-visible {
@include focus-ring(#3178c6);
}@function rem($px) {
@return calc($px / 16) * 1rem;
}
.title { font-size: rem(32); }Mobile first y breakpoints con intención
Empezá por el layout mínimo y agregá complejidad con min-width. Los breakpoints deberían responder al contenido, no a una lista arbitraria de dispositivos.
.cards {
display: grid;
gap: 1rem;
}
@media (min-width: 48rem) {
.cards { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 64rem) {
.cards { grid-template-columns: repeat(3, 1fr); }
}En mobile first, ¿qué suele contener la regla base?
Cómo escalar sin crear un laberinto
Una arquitectura profesional separa design tokens, base, layout y componentes. BEM u otra convención consistente ayuda a mantener selectores predecibles. La meta no es tener muchas carpetas: es encontrar rápido dónde vive cada responsabilidad.
Reset, tipografía y reglas globales inevitables.
Estructuras de página: header, shell, grids, footer.
Botones, cards, formularios y piezas reutilizables.
Colores, espacios, radios, sombras y breakpoints.
Build, watch y calidad de salida
En desarrollo conviene compilar en modo watch. Para producción generá CSS comprimido, sin source map si no lo necesitás, y verificá que el HTML sólo dependa del archivo compilado.
{
"scripts": {
"styles": "sass sass/styles.scss assets/css/styles.css --style=compressed",
"styles:watch": "sass sass/styles.scss assets/css/styles.css --watch"
}
}¿Qué archivo debería referenciar el navegador en producción?
Maps, listas y loops con una razón real
Los maps agrupan tokens relacionados y los loops generan patrones repetibles. Usalos cuando reduzcan duplicación real, no para convertir SCSS en una capa difícil de leer.
$spaces: (
xs: .25rem,
sm: .5rem,
md: 1rem,
lg: 2rem
);
@each $name, $value in $spaces {
.gap-#{$name} { gap: $value; }
}Design tokens y decisiones centralizadas
Un token representa una decisión reusable: color principal, radios, sombras, espacios o breakpoints. La meta es tener una fuente de verdad clara para el sistema visual.
$color-primary: #3178c6;
$radius-card: 1rem;
$space-section: 4rem;
$shadow-card: 0 24px 60px rgba(0,0,0,.22);SASS y CSS Custom Properties trabajan juntos
Las variables SASS existen en build time. Las Custom Properties viven en runtime. En sistemas modernos es normal combinar ambas: SASS para arquitectura y CSS variables para theming y valores dinámicos.
$primary: #3178c6;
:root {
--primary: #{$primary};
}
[data-theme="light"] {
--surface: #fff;
}
.button { background: var(--primary); }Focus, contraste y movimiento responsable
Los estilos también determinan accesibilidad. No elimines el foco visible sin reemplazo, no dependas sólo del color para comunicar estados y respetá prefers-reduced-motion.
:focus-visible {
outline: 3px solid rgba(#60a5fa, .65);
outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
transition-duration: .01ms !important;
}
}Performance, especificidad y CSS que envejece bien
SASS puede producir CSS excelente o una salida inflada. Revisá el CSS compilado, mantené nesting corto, evitá selectores innecesariamente específicos y validá la compilación en CI.
Reduce especificidad accidental.
No sobrearquitectures proyectos chicos.
Es el artefacto real enviado al navegador.
SCSS y CSS deben mantenerse coherentes.
Construí un sistema de tema claro/oscuro
Usá SASS para la arquitectura y CSS Custom Properties para los valores que deben cambiar en runtime. El resultado tiene que respetar foco visible y prefers-reduced-motion.
- Definí tokens semánticos.
- Expone los tokens dinámicos como Custom Properties.
- Creá una variante clara sin duplicar componentes.
- Verificá contraste y estados de interacción.
Ya tenés la ruta completa de SASS
Volvé al laboratorio para reconocer estas decisiones en el código real del proyecto o seguí con TypeScript para completar el stack.