Cómo utilizar mixins en Sass: Ventajas y ejemplos útiles

Cuando un proyecto web empieza a crecer, el CSS también crece con él. Lo que al principio parecía una hoja de estilos sencilla puede convertirse, poco a poco, en un conjunto de reglas repetidas, pequeñas variaciones, media queries duplicadas y patrones difíciles de mantener.

En ese punto, Sass sigue siendo una herramienta muy útil para escribir estilos de forma más ordenada, especialmente cuando trabajamos con arquitectura CSS, componentes reutilizables o sistemas de diseño.

Uno de los recursos más prácticos de Sass son los mixins. Entender cómo utilizar mixins en Sass te permite escribir código más limpio, evitar repeticiones innecesarias y crear patrones reutilizables para botones, layouts, breakpoints, estados visuales, sombras, animaciones o cualquier bloque de estilos que aparezca varias veces en un proyecto.

Si ya has trabajado con Sass o estás valorando incorporarlo a tu flujo de trabajo, puede que también te interese leer este artículo sobre 10 razones para utilizar Sass en tu próximo proyecto, donde explico por qué sigue teniendo sentido en muchos proyectos frontend actuales.

En este artículo vamos a ver qué son los mixins, cuáles son sus ventajas, cuándo conviene utilizarlos, cuándo es mejor evitarlos y varios ejemplos útiles de mixins en Sass que puedes adaptar a tus propios proyectos.

Qué son los mixins en Sass

Un mixin en Sass es un bloque reutilizable de código CSS que se define con @mixin y se utiliza con @include.

Dicho de forma sencilla: un mixin funciona como una pequeña plantilla de estilos. Puedes definir un conjunto de propiedades una sola vez y reutilizarlas en distintos selectores sin tener que copiar y pegar el mismo código una y otra vez.

Por ejemplo, imagina que en tu proyecto utilizas muchas veces el mismo patrón para centrar elementos con Flexbox:

.card {
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal {
  display: flex;
  align-items: center;
  justify-content: center;
}

.hero-content {
  display: flex;
  align-items: center;
  justify-content: center;
}

El código funciona, pero es repetitivo. Si más adelante quieres cambiar la forma de centrar los elementos, tendrás que modificarlo en varios lugares.

Con un mixin, puedes centralizar ese patrón:

@mixin flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

.card {
  @include flex-center;
}

.modal {
  @include flex-center;
}

.hero-content {
  @include flex-center;
}

El resultado compilado seguirá siendo CSS normal, pero tu código fuente será más claro, más breve y más fácil de mantener.

Sintaxis básica de un mixin

La sintaxis mínima de un mixin en Sass es esta:

@mixin nombre-del-mixin {
  propiedad: valor;
  propiedad: valor;
}

Y para utilizarlo dentro de un selector:

.selector {
  @include nombre-del-mixin;
}

Un ejemplo muy básico podría ser el de una tarjeta reutilizable:

@mixin card-base {
  border-radius: 1rem;
  padding: 1.5rem;
  background-color: #ffffff;
  box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.08);
}

.article-card {
  @include card-base;
}

.project-card {
  @include card-base;
}

Este mixin crea una base visual común para tarjetas. Después, cada componente puede añadir sus propias variaciones:

.project-card {
  @include card-base;
  border: 1px solid #e8e8e8;
}

Así consigues una base consistente sin renunciar a la personalización.

Resultado CSS compilado

Cuando Sass compila el código anterior, el navegador no ve @mixin ni @include. Solo recibe CSS estándar:

.article-card {
  border-radius: 1rem;
  padding: 1.5rem;
  background-color: #ffffff;
  box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.08);
}

.project-card {
  border-radius: 1rem;
  padding: 1.5rem;
  background-color: #ffffff;
  box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.08);
  border: 1px solid #e8e8e8;
}

Esto es importante: Sass no se ejecuta directamente en el navegador. Sass se compila antes y genera CSS final. Por eso, los mixins son una herramienta de organización en tiempo de desarrollo.

Ventajas de utilizar mixins en Sass

Los mixins no sirven únicamente para escribir menos código. Bien utilizados, pueden mejorar la arquitectura de estilos de un proyecto completo.

Reducen la repetición de código

La ventaja más evidente es que ayudan a evitar bloques repetidos. Esto encaja con el principio DRY, es decir, Don’t Repeat Yourself, muy habitual en desarrollo.

Si repites muchas veces el mismo patrón visual, un mixin puede ayudarte a mantenerlo en un único lugar. Por ejemplo:

@mixin transition-base {
  transition: all 0.25s ease;
}

.button {
  @include transition-base;
}

.card {
  @include transition-base;
}

.nav-link {
  @include transition-base;
}

Ahora, si decides ajustar la duración de la transición, solo tienes que cambiar el mixin:

@mixin transition-base {
  transition: all 0.2s ease-in-out;
}

Ese cambio se aplicará a todos los selectores que incluyan el mixin.

Si quieres profundizar más en cómo funcionan las transiciones y cuándo conviene usarlas frente a las animaciones, puedes leer también el artículo sobre la diferencia entre transition y animation en CSS.

Mejoran la consistencia visual

En proyectos con muchas páginas, componentes o personas tocando el mismo código, es fácil que aparezcan pequeñas inconsistencias: botones con radios diferentes, sombras ligeramente distintas, espaciados no alineados o breakpoints duplicados con valores diferentes.

Los mixins ayudan a crear patrones compartidos. Por ejemplo, puedes definir una sombra estándar:

@mixin soft-shadow {
  box-shadow: 0 0.75rem 2rem rgba(0, 0, 0, 0.08);
}

Y aplicarla en todos los componentes que necesiten ese mismo tratamiento visual:

.pricing-card {
  @include soft-shadow;
}

.testimonial {
  @include soft-shadow;
}

Esto no solo mejora el código, también mejora la coherencia de la interfaz.

Permiten crear patrones flexibles con argumentos

Una de las grandes ventajas de los mixins es que pueden recibir argumentos. Esto significa que no tienen por qué generar siempre el mismo CSS exacto.

Puedes pasarles valores para crear variaciones controladas:

@mixin button-variant($bg-color, $text-color) {
  background-color: $bg-color;
  color: $text-color;
  border: none;
  border-radius: 999px;
  padding: 0.75rem 1.25rem;
  font-weight: 600;
  cursor: pointer;
}

.button-primary {
  @include button-variant(#cc2b5e, #ffffff);
}

.button-secondary {
  @include button-variant(#f8e0ea, #753a88);
}

Este mixin permite crear variantes de botón sin repetir toda la estructura.

También puedes usar valores por defecto:

@mixin button-variant($bg-color: #cc2b5e, $text-color: #ffffff) {
  background-color: $bg-color;
  color: $text-color;
  border: none;
  border-radius: 999px;
  padding: 0.75rem 1.25rem;
  font-weight: 600;
}

Así puedes llamar al mixin sin argumentos:

.button-primary {
  @include button-variant;
}

O sobrescribir solo cuando lo necesites:

.button-light {
  @include button-variant(#ffffff, #020101);
}

Facilitan la gestión de media queries

Uno de los usos más habituales de los mixins en Sass es la gestión de breakpoints. En lugar de escribir media queries manualmente en cada componente, puedes centralizarlas.

@mixin respond-to($breakpoint) {
  @if $breakpoint == tablet {
    @media (min-width: 768px) {
      @content;
    }
  }

  @if $breakpoint == desktop {
    @media (min-width: 1024px) {
      @content;
    }
  }

  @if $breakpoint == wide {
    @media (min-width: 1280px) {
      @content;
    }
  }
}

Después puedes usarlo así:

.hero {
  padding: 3rem 1.5rem;

  @include respond-to(tablet) {
    padding: 4rem 2rem;
  }

  @include respond-to(desktop) {
    padding: 6rem 4rem;
  }
}

Aquí aparece @content, una característica muy útil de Sass que permite pasar un bloque de estilos dentro del @include.

Este patrón resulta especialmente interesante cuando trabajas con diseño responsive. En ese contexto, también puedes revisar el artículo sobre cómo utilizar media queries internas en imágenes SVG.

Cómo utilizar mixins en Sass paso a paso

Para sacarles partido, no basta con saber escribir @mixin. También conviene pensar dónde colocarlos, cómo nombrarlos y cómo evitar que se conviertan en una capa de abstracción innecesaria.

Paso 1: detecta patrones repetidos

Antes de crear un mixin, pregúntate si ese bloque de estilos se repite de verdad, si lo vas a necesitar en más de dos o tres sitios y si representa un patrón del proyecto.

Buenos candidatos para convertirse en mixins:

  • Centrado con Flexbox.
  • Media queries.
  • Estilos base de botones.
  • Estados hover y focus.
  • Estilos visuales reutilizables.
  • Helpers de accesibilidad.
  • Patrones de truncado de texto.
  • Animaciones repetidas.
  • Contenedores con ancho máximo.

En cambio, no suele ser buena idea crear un mixin para un estilo que solo se usa una vez o para un bloque demasiado específico de un componente.

Un mixin debe resolver un problema concreto. Si el nombre del mixin tiene que explicar demasiadas cosas, probablemente está haciendo demasiado.

Paso 2: usa nombres claros

Los nombres importan. Un buen nombre permite entender qué hace el mixin sin tener que abrir su definición.

Mejor esto:

@mixin visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

Que esto:

@mixin hidden-thing {
  position: absolute;
  width: 1px;
  height: 1px;
}

El primer nombre comunica intención. El segundo no.

También conviene evitar nombres demasiado genéricos como box, style, effect o custom. En un proyecto grande, esos nombres se vuelven difíciles de mantener.

Paso 3: organiza los mixins en archivos separados

En proyectos pequeños puedes escribir los mixins en el mismo archivo, pero en un proyecto real conviene separarlos.

Una estructura sencilla podría ser:

scss/
  abstracts/
    _variables.scss
    _mixins.scss
  base/
    _reset.scss
    _typography.scss
  components/
    _buttons.scss
    _cards.scss
  main.scss

En Sass moderno es recomendable trabajar con @use y @forward en lugar de depender de @import.

Por ejemplo:

// abstracts/_mixins.scss

@mixin flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

Luego, en otro archivo:

@use "../abstracts/mixins" as mixins;

.card {
  @include mixins.flex-center;
}

Este enfoque evita contaminar el espacio global y hace que el origen de cada mixin sea más claro.

Ejemplos útiles de mixins en Sass

A continuación tienes varios ejemplos prácticos que puedes adaptar a tus propios proyectos.

Mixin para centrar elementos con Flexbox

@mixin flex-center($direction: row, $gap: 0) {
  display: flex;
  flex-direction: $direction;
  align-items: center;
  justify-content: center;
  gap: $gap;
}

.empty-state {
  @include flex-center(column, 1rem);
  min-height: 20rem;
  text-align: center;
}

Este mixin es útil para componentes como modales, tarjetas vacías, secciones hero o layouts centrados.

Mixin para media queries

@mixin media-up($size) {
  @if $size == sm {
    @media (min-width: 640px) {
      @content;
    }
  }

  @if $size == md {
    @media (min-width: 768px) {
      @content;
    }
  }

  @if $size == lg {
    @media (min-width: 1024px) {
      @content;
    }
  }

  @if $size == xl {
    @media (min-width: 1280px) {
      @content;
    }
  }
}

Uso:

.blog-grid {
  display: grid;
  gap: 1.5rem;

  @include media-up(md) {
    grid-template-columns: repeat(2, 1fr);
  }

  @include media-up(lg) {
    grid-template-columns: repeat(3, 1fr);
  }
}

Este patrón ayuda a mantener las media queries consistentes y evita escribir valores sueltos por todo el proyecto.

Mixin para botones reutilizables

@mixin button-base {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border: 0;
  border-radius: 999px;
  padding: 0.85rem 1.4rem;
  font: inherit;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  transition:
    transform 0.2s ease,
    background-color 0.2s ease,
    color 0.2s ease;
}

@mixin button-theme($bg, $color, $hover-bg) {
  background-color: $bg;
  color: $color;

  &:hover {
    background-color: $hover-bg;
    transform: translateY(-2px);
  }

  &:focus-visible {
    outline: 3px solid rgba($bg, 0.35);
    outline-offset: 3px;
  }
}

.button-primary {
  @include button-base;
  @include button-theme(#cc2b5e, #ffffff, #753a88);
}

.button-soft {
  @include button-base;
  @include button-theme(#f8e0ea, #753a88, #f1c4d7);
}

Aquí separamos la estructura del botón de su tema visual. Esto hace que el código sea más fácil de escalar.

Mixin para texto oculto visualmente

Este tipo de mixin es útil cuando queremos ocultar texto de forma visual pero mantenerlo disponible para tecnologías de asistencia.

@mixin visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.icon-button span {
  @include visually-hidden;
}

Este patrón puede ser útil en botones que solo muestran un icono, pero que necesitan conservar un nombre accesible para lectores de pantalla.

Mixin para truncar texto

@mixin truncate($lines: 1) {
  overflow: hidden;

  @if $lines == 1 {
    white-space: nowrap;
    text-overflow: ellipsis;
  } @else {
    display: -webkit-box;
    -webkit-line-clamp: $lines;
    -webkit-box-orient: vertical;
  }
}

.card-title {
  @include truncate(2);
}

Este mixin permite reutilizar un patrón muy habitual en tarjetas de blog, listados de productos o interfaces con contenido dinámico.

Mixin para mantener proporciones de imagen

@mixin aspect-ratio($width, $height) {
  aspect-ratio: #{$width} / #{$height};
  overflow: hidden;

  > img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
}

.post-card__media {
  @include aspect-ratio(3, 2);
  border-radius: 1rem;
}

Este mixin es práctico cuando quieres mantener una línea visual consistente en imágenes destacadas, galerías o tarjetas.

Mixins en Sass vs variables CSS: cuándo usar cada uno

Una duda habitual es si tiene sentido seguir usando Sass cuando CSS moderno ya incluye custom properties, también conocidas como variables CSS.

La respuesta corta es: sí, pero no para lo mismo.

Las variables CSS se declaran con la sintaxis --nombre-variable y se consumen mediante var(). Además, participan en la cascada y pueden cambiar según el contexto del elemento. Esto las hace muy útiles para temas, modos claro/oscuro o valores dinámicos.

Por ejemplo:

:root {
  --color-primary: #cc2b5e;
}

.button {
  background-color: var(--color-primary);
}

Un mixin, en cambio, no existe en tiempo de ejecución. Se compila antes de llegar al navegador.

Por eso, un mixin es ideal para generar bloques completos de CSS, mientras que una variable CSS es ideal para valores que pueden cambiar según el contexto.

Usa mixins cuando necesites generar patrones de CSS

Por ejemplo:

@mixin focus-ring($color) {
  &:focus-visible {
    outline: 3px solid $color;
    outline-offset: 4px;
  }
}

.link {
  @include focus-ring(#cc2b5e);
}

Usa variables CSS cuando necesites valores dinámicos

:root {
  --focus-color: #cc2b5e;
}

[data-theme="dark"] {
  --focus-color: #f8e0ea;
}

.link:focus-visible {
  outline: 3px solid var(--focus-color);
}

En muchos proyectos, la mejor solución es combinar ambas herramientas: Sass para organizar y generar CSS, y variables CSS para gestionar valores que deben adaptarse al contexto.

Errores comunes al utilizar mixins en Sass

Los mixins son útiles, pero también pueden utilizarse mal. Estos son algunos errores frecuentes que conviene evitar.

Crear mixins para todo

No todo necesita ser un mixin. Si un bloque de estilos solo se utiliza una vez, probablemente no merece convertirse en una abstracción.

Un exceso de mixins puede hacer que el CSS sea más difícil de leer, porque obliga a saltar constantemente entre archivos para entender qué estilos se están aplicando.

Crear mixins demasiado grandes

Un mixin debería tener una responsabilidad clara. Este ejemplo es problemático:

@mixin complete-card-system {
  display: grid;
  padding: 2rem;
  border-radius: 1rem;
  background: white;
  color: black;
  box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.12);

  h2 {
    font-size: 2rem;
  }

  p {
    color: gray;
  }

  a {
    color: red;
  }
}

Este mixin mezcla layout, estilos visuales, tipografía y estilos de elementos internos. Puede parecer cómodo al principio, pero a la larga será difícil de mantener.

Es mejor dividirlo en piezas pequeñas:

@mixin card-surface {
  border-radius: 1rem;
  background: white;
  box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.12);
}

@mixin content-flow($gap: 1rem) {
  display: grid;
  gap: $gap;
}

Así puedes combinar solo lo que necesites.

Usar mixins para valores simples

Si solo quieres reutilizar un color, un tamaño o un espaciado, probablemente sea mejor usar una variable Sass o una variable CSS.

No tiene mucho sentido hacer esto:

@mixin primary-color {
  color: #cc2b5e;
}

En este caso, sería más claro usar una variable:

$color-primary: #cc2b5e;

.title {
  color: $color-primary;
}

O una custom property si quieres que el valor sea dinámico:

.title {
  color: var(--color-primary);
}

Buenas prácticas para escribir mixins mantenibles

Para que los mixins sigan siendo útiles con el paso del tiempo, conviene aplicar algunas buenas prácticas.

Mantén una responsabilidad por mixin

Un mixin debería resolver una cosa concreta: centrar elementos, aplicar una media query, generar una variante de botón, crear un estado de foco o definir una superficie visual.

Si un mixin empieza a crecer demasiado, divídelo.

Usa argumentos con nombres claros

Los argumentos deben ser fáciles de entender:

@mixin container($max-width: 72rem, $padding-inline: 1.5rem) {
  width: min(100% - (#{$padding-inline} * 2), #{$max-width});
  margin-inline: auto;
}

Uso:

.page-wrapper {
  @include container(80rem, 2rem);
}

También puedes usar argumentos nombrados para mejorar la legibilidad:

.page-wrapper {
  @include container($max-width: 80rem, $padding-inline: 2rem);
}

Documenta los mixins importantes

No hace falta comentar todo, pero sí conviene documentar los mixins que forman parte de la arquitectura del proyecto.

/// Crea un contenedor centrado con ancho máximo y padding lateral.
/// @param {Length} $max-width - Ancho máximo del contenedor.
/// @param {Length} $padding-inline - Espaciado lateral mínimo.
@mixin container($max-width: 72rem, $padding-inline: 1.5rem) {
  width: min(100% - (#{$padding-inline} * 2), #{$max-width});
  margin-inline: auto;
}

Esta pequeña documentación puede ahorrar mucho tiempo cuando el proyecto crece o cuando otra persona se incorpora al código.

Evita esconder demasiada lógica

Los mixins deben ayudarte, no convertirse en una caja negra. Si un @include genera demasiadas reglas inesperadas, puede dificultar la depuración en el navegador.

Un buen mixin debe ser predecible.

Cuándo conviene utilizar mixins en Sass

Los mixins son especialmente útiles cuando existe un patrón repetible con cierta lógica.

Por ejemplo:

@mixin hover-lift($distance: -3px) {
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease;

  &:hover {
    transform: translateY($distance);
    box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.12);
  }
}

Uso:

.article-card {
  @include hover-lift;
}

.project-card {
  @include hover-lift(-5px);
}

También son muy útiles cuando quieres crear una API interna para tus estilos. Por ejemplo, un equipo puede acordar que todos los componentes usen el mismo mixin para los estados de foco:

@mixin accessible-focus($color: #cc2b5e) {
  &:focus-visible {
    outline: 3px solid $color;
    outline-offset: 4px;
  }
}

De esta manera, la accesibilidad visual se vuelve más consistente en todo el proyecto.

Y si estás trabajando con movimiento en interfaces, conviene recordar que no todo tiene que resolverse con CSS puro. Para ciertos casos más avanzados, puedes combinar Sass con librerías específicas. En ese contexto, puede interesarte este artículo sobre cómo crear animaciones para la web con la librería GSAP.

Preguntas frecuentes sobre mixins en Sass

¿Cuál es la diferencia entre un mixin y una función en Sass?

Una función en Sass devuelve un valor, mientras que un mixin genera un bloque de declaraciones CSS.

Por ejemplo, una función puede calcular un tamaño o devolver un color transformado. Un mixin, en cambio, puede generar varias propiedades como display, align-items, justify-content, padding, border-radius o incluso media queries completas.

En resumen: usa funciones para valores y mixins para bloques de estilos reutilizables.

¿Es buena idea utilizar mixins para responsive design?

Sí, siempre que se usen con criterio. Los mixins para media queries ayudan a centralizar los breakpoints y evitar inconsistencias.

En lugar de escribir @media (min-width: 768px) en veinte archivos diferentes, puedes crear un mixin como media-up(md) y usarlo en todos los componentes.

Esto mejora la mantenibilidad y hace que el sistema responsive del proyecto sea más fácil de modificar.

¿Los mixins aumentan el tamaño del CSS final?

Pueden hacerlo si se abusa de ellos. Cada vez que incluyes un mixin, Sass copia su contenido en el selector correspondiente.

Si un mixin genera muchas propiedades y lo usas en demasiados lugares, el CSS compilado puede crecer.

Por eso es importante utilizar mixins para patrones realmente reutilizables, no como sustituto automático de cualquier declaración CSS.

Escribir menos no siempre es escribir mejor

Los mixins en Sass son una herramienta muy poderosa para escribir CSS más organizado, reutilizable y coherente. Permiten reducir repetición, centralizar patrones, crear variantes mediante argumentos y trabajar mejor con media queries, estados visuales o estructuras comunes de componentes.

Sin embargo, como ocurre con cualquier abstracción, su valor depende de cómo se utilicen. Un buen mixin hace que el código sea más claro. Un mal mixin puede convertir una hoja de estilos en un sistema difícil de seguir.

La clave está en usarlos con intención. Antes de crear un mixin, pregúntate si realmente estás resolviendo un patrón repetido, si el nombre comunica bien su propósito y si el resultado será más fácil de mantener dentro de unos meses.

Sass sigue teniendo sentido en muchos flujos de trabajo modernos, especialmente cuando se combina con CSS actual, variables personalizadas, arquitectura modular y una buena organización de componentes.

En definitiva, aprender cómo utilizar mixins en Sass no consiste solo en memorizar @mixin y @include. Consiste en desarrollar criterio para detectar patrones, reducir ruido y construir una base de estilos más sólida para tus proyectos frontend.

Hooks en React

Los Hooks en React cambiaron por completo la forma de construir componentes modernos. Si antes era habitual asociar el estado, los ciclos de vida y buena parte de la lógica interna a los componentes de clase, hoy lo más común es trabajar con componentes funcionales y Hooks como useState, useEffect, useRef, useMemo, useCallback o useContext.

Pero aquí aparece una duda muy habitual: ¿qué son exactamente los Hooks en React y cómo se usan sin complicar demasiado el código?

Dicho de forma sencilla, los Hooks son funciones especiales que permiten “conectar” un componente con diferentes características de React, como el estado, los efectos secundarios, el contexto o la optimización de cálculos. Gracias a ellos, puedes escribir componentes más claros, reutilizables y fáciles de mantener.

Si estás empezando a trabajar con React, también puede ser útil complementar esta lectura con contenidos relacionados como TypeScript: primeros pasos o con artículos más concretos sobre navegación en React, como cómo utilizar React Router Hash Link para crear enlaces ancla en ReactJS.

En este artículo vamos a ver qué son los React Hooks, para qué sirven, cuáles son los más utilizados y cómo aplicarlos en tus componentes con ejemplos prácticos. La idea no es memorizar todos los Hooks disponibles, sino entender cuándo tiene sentido usar cada uno y qué errores conviene evitar.

Qué son los Hooks en React

Los Hooks son funciones especiales que permiten usar características de React dentro de componentes funcionales. Normalmente, sus nombres empiezan por use, como useState, useEffect, useRef, useContext, useMemo o useCallback.

Antes de los Hooks, muchas funcionalidades avanzadas de React estaban ligadas a los componentes de clase. Por ejemplo, si querías manejar estado interno o ejecutar lógica cuando un componente se montaba, actualizaba o desmontaba, era habitual recurrir a métodos como componentDidMount, componentDidUpdate o componentWillUnmount.

Con los Hooks, esa lógica puede escribirse dentro de componentes funcionales de una forma más directa.

import { useState } from "react";

function Contador() {
  const [contador, setContador] = useState(0);

  return (
    <div>
      <p>Has hecho clic {contador} veces.</p>

      <button onClick={() => setContador(contador + 1)}>
        Incrementar
      </button>
    </div>
  );
}

En este caso, contador es el valor actual del estado y setContador es la función que permite actualizarlo. Cada vez que se pulsa el botón, React actualiza el estado y vuelve a renderizar el componente con el nuevo valor.

La clave está en entender que un Hook no es magia. Es una forma ordenada de decirle a React: “este componente necesita recordar algo”, “este componente necesita sincronizarse con algo externo” o “este componente necesita reutilizar una lógica determinada”.

Por qué son importantes los React Hooks

Los React Hooks son importantes porque ayudan a escribir componentes más claros, reutilizables y fáciles de mantener. En lugar de depender de clases para gestionar estado o lógica de ciclo de vida, puedes trabajar con funciones y añadirles comportamiento mediante Hooks.

Esto tiene varias ventajas. La primera es que el código suele ser más compacto. La segunda es que resulta más sencillo separar responsabilidades. Y la tercera es que se pueden crear Hooks personalizados para reutilizar lógica entre componentes sin duplicar código.

Imagina, por ejemplo, que varios componentes necesitan saber si el usuario está conectado a internet. En lugar de repetir la misma lógica en cada componente, podrías crear un Hook personalizado llamado useOnlineStatus.

Esto permite organizar mejor la lógica de una aplicación. En lugar de tener componentes enormes, llenos de condiciones, efectos y cálculos, puedes extraer partes de esa lógica a Hooks propios.

En proyectos frontend reales, esta capacidad de separar responsabilidades es especialmente útil. Si además combinas React con buenas prácticas de tipado, puedes mejorar mucho la mantenibilidad del código. Por eso, si estás profundizando en este ecosistema, puede interesarte revisar también el artículo sobre TypeScript: primeros pasos.

Reglas básicas para usar Hooks en React

Aunque los Hooks son muy útiles, tienen unas reglas importantes. No se pueden llamar en cualquier lugar del código.

La regla principal es que los Hooks deben llamarse en el nivel superior del componente o dentro de otros Hooks personalizados. No deberían llamarse dentro de bucles, condicionales o funciones anidadas, porque React necesita que el orden de ejecución de los Hooks sea estable entre renderizados.

No llames Hooks dentro de condicionales

Este ejemplo sería incorrecto:

function Perfil({ usuario }) {
  if (usuario) {
    const [activo, setActivo] = useState(true);
  }

  return <p>Perfil de usuario</p>;
}

El problema es que el Hook solo se ejecutaría si usuario existe. Si en un renderizado existe y en otro no, React perdería el orden esperado de los Hooks.

La forma correcta sería esta:

import { useState } from "react";

function Perfil({ usuario }) {
  const [activo, setActivo] = useState(true);

  if (!usuario) {
    return <p>No hay usuario disponible.</p>;
  }

  return <p>Perfil activo: {activo ? "Sí" : "No"}</p>;
}

Aquí el Hook se llama siempre en el mismo lugar, antes de cualquier retorno condicional importante.

Usa Hooks solo en componentes o en otros Hooks

Tampoco deberías llamar Hooks desde funciones normales de JavaScript que no sean componentes ni Hooks personalizados.

Este ejemplo no sería correcto:

function calcularEstadoInicial() {
  const [valor, setValor] = useState(0);

  return valor;
}

En cambio, si quieres extraer esa lógica, puedes crear un Hook personalizado:

import { useState } from "react";

function useValorInicial() {
  const [valor, setValor] = useState(0);

  return [valor, setValor];
}

La diferencia es importante: un Hook personalizado también empieza por use y está pensado para encapsular lógica compatible con React.

Principales Hooks en React y cómo usarlos

React incluye varios Hooks integrados. No necesitas dominarlos todos desde el primer día, pero sí conviene conocer los más comunes.

  • useState
  • useEffect
  • useRef
  • useContext
  • useMemo
  • useCallback

Cada uno resuelve un tipo de problema diferente. La clave está en no usarlos por inercia, sino entender qué necesidad concreta cubre cada uno.

useState: manejar estado local en un componente

useState es probablemente el primer Hook que se aprende. Sirve para guardar valores que pueden cambiar con el tiempo y que afectan a lo que se muestra en pantalla.

import { useState } from "react";

function FormularioNombre() {
  const [nombre, setNombre] = useState("");

  return (
    <form>
      <label htmlFor="nombre">Nombre</label>

      <input
        id="nombre"
        value={nombre}
        onChange={(event) => setNombre(event.target.value)}
      />

      <p>Hola, {nombre || "visitante"}.</p>
    </form>
  );
}

Aquí el estado nombre se actualiza cada vez que el usuario escribe en el campo. Este patrón es habitual en formularios controlados.

Cuándo usar useState

Usa useState cuando el componente necesite recordar información que cambia y que afecta a la interfaz.

  • Un contador.
  • El valor de un campo de formulario.
  • Un estado de carga.
  • Una pestaña activa.
  • Un modal abierto o cerrado.
  • Un mensaje de error.
  • Una selección hecha por el usuario.

Sin embargo, no todo debe ir en estado. Si un valor se puede calcular a partir de props o de otro estado existente, muchas veces es mejor calcularlo directamente durante el renderizado.

const nombreCompleto = `${nombre} ${apellido}`;

Cuanto menos estado innecesario tenga un componente, más fácil será mantenerlo.

useEffect: sincronizar un componente con algo externo

useEffect es uno de los Hooks más importantes, pero también uno de los que más confusión genera.

Este Hook permite ejecutar lógica después del renderizado del componente. Es especialmente útil cuando necesitas sincronizar el componente con algo externo al propio flujo de React.

  • Llamadas a una API.
  • Suscripciones.
  • Eventos del navegador.
  • Temporizadores.
  • Lectura o escritura en localStorage.
  • Integración con librerías externas.
import { useEffect, useState } from "react";

function Usuarios() {
  const [usuarios, setUsuarios] = useState([]);
  const [cargando, setCargando] = useState(true);

  useEffect(() => {
    async function obtenerUsuarios() {
      try {
        const respuesta = await fetch("/api/usuarios");
        const datos = await respuesta.json();

        setUsuarios(datos);
      } finally {
        setCargando(false);
      }
    }

    obtenerUsuarios();
  }, []);

  if (cargando) {
    return <p>Cargando usuarios...</p>;
  }

  return (
    <ul>
      {usuarios.map((usuario) => (
        <li key={usuario.id}>{usuario.nombre}</li>
      ))}
    </ul>
  );
}

El array de dependencias [] indica que el efecto se ejecuta después del primer renderizado. Si incluyes dependencias dentro de ese array, el efecto volverá a ejecutarse cuando cambien.

Cuidado: no siempre necesitas un useEffect

Uno de los errores más frecuentes es usar useEffect para todo.

Por ejemplo, este caso puede ser innecesario:

const [nombreCompleto, setNombreCompleto] = useState("");

useEffect(() => {
  setNombreCompleto(`${nombre} ${apellido}`);
}, [nombre, apellido]);

Sería más simple escribir:

const nombreCompleto = `${nombre} ${apellido}`;

Este detalle parece pequeño, pero es importante. Usar menos efectos ayuda a que tus componentes sean más previsibles. Un useEffect debería responder a una sincronización real, no convertirse en el lugar donde se coloca cualquier lógica.

Si estás trabajando con datos persistentes del navegador, también puede interesarte leer el artículo sobre almacenamiento web con localStorage y sessionStorage, porque combina muy bien con algunos casos prácticos de useEffect.

useRef: guardar referencias sin provocar renderizados

useRef permite guardar un valor mutable que se mantiene entre renderizados, pero que no provoca un nuevo renderizado cuando cambia.

Uno de sus usos más habituales es acceder a un elemento del DOM:

import { useRef } from "react";

function Buscador() {
  const inputRef = useRef(null);

  function enfocarInput() {
    inputRef.current.focus();
  }

  return (
    <div>
      <input ref={inputRef} type="search" placeholder="Buscar..." />

      <button onClick={enfocarInput}>
        Enfocar campo
      </button>
    </div>
  );
}

En este ejemplo, inputRef permite acceder directamente al input para hacer foco cuando el usuario pulsa el botón.

También puedes usar useRef para guardar valores que necesitas conservar, pero que no deben actualizar la interfaz por sí mismos.

import { useRef } from "react";

function Temporizador() {
  const timerRef = useRef(null);

  function iniciar() {
    timerRef.current = setInterval(() => {
      console.log("Intervalo activo");
    }, 1000);
  }

  function detener() {
    clearInterval(timerRef.current);
  }

  return (
    <div>
      <button onClick={iniciar}>Iniciar</button>
      <button onClick={detener}>Detener</button>
    </div>
  );
}

La diferencia con useState es importante: si el valor debe mostrarse en pantalla, probablemente necesitas estado. Si solo necesitas guardar una referencia interna, useRef puede ser mejor opción.

useContext: compartir datos sin pasar props manualmente

useContext permite leer datos de un contexto de React desde un componente.

Es útil para datos globales o semiglobales, como:

  • El tema visual.
  • El idioma.
  • La sesión de usuario.
  • Ciertas preferencias de la aplicación.
  • Configuraciones compartidas.
import { createContext, useContext } from "react";

const ThemeContext = createContext("light");

function Boton() {
  const theme = useContext(ThemeContext);

  return (
    <button className={theme === "dark" ? "btn-dark" : "btn-light"}>
      Cambiar tema
    </button>
  );
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Boton />
    </ThemeContext.Provider>
  );
}

useContext evita el conocido prop drilling, es decir, pasar props por muchos niveles intermedios solo para que lleguen a un componente profundo.

Ahora bien, no conviene usar contexto para absolutamente todo. Si un dato solo lo necesitan uno o dos componentes cercanos, probablemente sea suficiente pasarlo por props.

Cuándo tiene sentido usar useContext

Tiene sentido usar useContext cuando muchos componentes necesitan acceder al mismo dato y pasarlo por props haría el código más incómodo.

Por ejemplo, en una aplicación con modo claro y oscuro, el contexto puede ser una buena opción. En cambio, si solo necesitas pasar un texto desde un componente padre a un hijo directo, usar contexto sería excesivo.

Hooks de rendimiento: useMemo y useCallback

Cuando una aplicación crece, puede aparecer la necesidad de optimizar ciertos cálculos o evitar renderizados innecesarios. Aquí entran Hooks como useMemo y useCallback.

No son Hooks que deban usarse en cada componente. De hecho, usarlos sin necesidad puede hacer que el código sea más difícil de leer. Pero cuando existe un problema real de rendimiento o una dependencia que conviene estabilizar, pueden ser muy útiles.

useMemo: memorizar cálculos costosos

useMemo permite almacenar el resultado de un cálculo entre renderizados. Si sus dependencias no cambian, React puede reutilizar el resultado anterior.

import { useMemo, useState } from "react";

function ListaFiltrada({ productos }) {
  const [busqueda, setBusqueda] = useState("");

  const productosFiltrados = useMemo(() => {
    return productos.filter((producto) =>
      producto.nombre.toLowerCase().includes(busqueda.toLowerCase())
    );
  }, [productos, busqueda]);

  return (
    <div>
      <input
        value={busqueda}
        onChange={(event) => setBusqueda(event.target.value)}
        placeholder="Buscar producto"
      />

      <ul>
        {productosFiltrados.map((producto) => (
          <li key={producto.id}>{producto.nombre}</li>
        ))}
      </ul>
    </div>
  );
}

Este Hook puede ser útil si el filtrado es pesado o si la lista es muy grande. Pero no deberías usar useMemo por costumbre. Si el cálculo es simple, añadirlo puede complicar el código sin aportar una mejora real.

Cuándo usar useMemo

Puedes valorar useMemo cuando:

  • El cálculo es costoso.
  • La lista de datos es grande.
  • El componente se renderiza con frecuencia.
  • El resultado calculado se pasa a componentes memorizados.
  • Has detectado un problema real de rendimiento.

Si ninguna de estas situaciones se cumple, probablemente no lo necesitas.

useCallback: memorizar funciones

useCallback permite mantener la misma referencia de una función entre renderizados, siempre que sus dependencias no cambien.

import { useCallback, useState } from "react";

function Panel() {
  const [abierto, setAbierto] = useState(false);

  const alternarPanel = useCallback(() => {
    setAbierto((valorActual) => !valorActual);
  }, []);

  return (
    <section>
      <button onClick={alternarPanel}>
        {abierto ? "Cerrar" : "Abrir"} panel
      </button>

      {abierto && <p>Contenido del panel.</p>}
    </section>
  );
}

Este Hook suele ser útil cuando pasas funciones a componentes memorizados o cuando una función aparece como dependencia de otro Hook.

Aun así, conviene repetir la misma idea: no hace falta envolver cada función en useCallback. Primero escribe código claro. Después optimiza donde tenga sentido.

Crear Hooks personalizados

Una de las partes más interesantes de los Hooks en React es que puedes crear tus propios Hooks.

Esto permite extraer lógica repetida y reutilizarla en distintos componentes. También ayuda a separar responsabilidades y a reducir el tamaño de los componentes.

Por ejemplo, puedes crear un Hook para leer y actualizar un valor en localStorage:

import { useEffect, useState } from "react";

function useLocalStorage(clave, valorInicial) {
  const [valor, setValor] = useState(() => {
    const valorGuardado = window.localStorage.getItem(clave);

    return valorGuardado ? JSON.parse(valorGuardado) : valorInicial;
  });

  useEffect(() => {
    window.localStorage.setItem(clave, JSON.stringify(valor));
  }, [clave, valor]);

  return [valor, setValor];
}

Y usarlo así:

function Preferencias() {
  const [tema, setTema] = useLocalStorage("tema", "light");

  return (
    <button onClick={() => setTema(tema === "light" ? "dark" : "light")}>
      Tema actual: {tema}
    </button>
  );
}

La ventaja es evidente: el componente Preferencias no necesita saber todos los detalles de localStorage. Solo consume una API sencilla.

Si quieres profundizar en este tema desde el lado del navegador, puedes complementar este ejemplo con el artículo sobre cómo usar localStorage y sessionStorage en proyectos JavaScript.

Buenas prácticas al crear Hooks propios

Un Hook personalizado debería tener una responsabilidad clara. Si hace demasiadas cosas, puede volverse tan difícil de mantener como el componente original.

También conviene cuidar el nombre. Si usa otros Hooks internamente, debe empezar por use. Esto ayuda a React, a las herramientas de linting y a cualquier persona que lea el código.

Por ejemplo:

function useUsuarioActual() {
  // Lógica relacionada con el usuario actual
}

Mucho mejor que:

function obtenerUsuarioActual() {
  // Si aquí se usan Hooks, el nombre no comunica bien su intención
}

El nombre useUsuarioActual deja claro que no es una función cualquiera, sino un Hook personalizado.

Ejemplo práctico: componente con varios Hooks

Veamos un ejemplo sencillo que combina varios Hooks en un mismo componente.

import { useEffect, useMemo, useRef, useState } from "react";

function BuscadorDeArticulos({ articulos }) {
  const [consulta, setConsulta] = useState("");
  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current.focus();
  }, []);

  const articulosFiltrados = useMemo(() => {
    return articulos.filter((articulo) =>
      articulo.titulo.toLowerCase().includes(consulta.toLowerCase())
    );
  }, [articulos, consulta]);

  return (
    <section>
      <h2>Buscar artículos</h2>

      <input
        ref={inputRef}
        value={consulta}
        onChange={(event) => setConsulta(event.target.value)}
        placeholder="Escribe una palabra clave"
      />

      <p>
        Se encontraron {articulosFiltrados.length} resultados.
      </p>

      <ul>
        {articulosFiltrados.map((articulo) => (
          <li key={articulo.id}>{articulo.titulo}</li>
        ))}
      </ul>
    </section>
  );
}

Aquí useState guarda la consulta de búsqueda, useRef permite enfocar el input al cargar el componente, useEffect ejecuta esa acción después del primer renderizado y useMemo evita recalcular la lista filtrada si no cambian los artículos ni la consulta.

Este ejemplo muestra una idea importante: los Hooks no compiten entre sí. Cada uno cumple una función concreta. El objetivo es elegir el Hook que mejor encaja con el problema.

Errores comunes al usar Hooks en React

Los Hooks son muy expresivos, pero también pueden generar problemas si se usan sin criterio.

Usar useEffect para lógica que pertenece a eventos

Si algo ocurre como respuesta directa a una acción del usuario, muchas veces debería estar en el manejador del evento, no en un useEffect.

Por ejemplo, si quieres enviar un formulario al hacer clic en un botón, lo normal es hacerlo en onSubmit, no detectar con un efecto que un estado ha cambiado y entonces enviar los datos.

Ignorar las dependencias de useEffect

El array de dependencias no es un adorno. Si un efecto usa valores externos, como props o estado, esas dependencias deberían estar reflejadas.

Un error habitual es eliminar dependencias para “evitar que el efecto se dispare”. Eso puede ocultar bugs y provocar que el componente trabaje con valores antiguos.

Guardar demasiado estado

No todo necesita useState. Si puedes calcular un valor a partir de otro, calcúlalo. Si puedes pasarlo por props, pásalo. Si puedes resolverlo en el renderizado, evita añadir un estado extra.

Cuanto más estado tenga un componente, más posibilidades hay de que distintas piezas de información se desincronicen.

Optimizar antes de tiempo

useMemo y useCallback son útiles, pero no deberían convertirse en una decoración automática.

Antes de añadirlos, conviene preguntarse:

  • ¿Hay realmente un problema de rendimiento?
  • ¿El cálculo es costoso?
  • ¿Estoy pasando esta función a un componente memorizado?
  • ¿El código se entiende mejor o peor después de añadir este Hook?

En muchas aplicaciones, la claridad del código aporta más valor que una microoptimización prematura.

Cómo decidir qué Hook necesitas

Cuando estés trabajando con componentes de React, puedes hacerte algunas preguntas para elegir mejor.

¿Necesito recordar un valor que afecta a la interfaz?

Probablemente necesitas useState.

Ejemplos: un modal abierto, una pestaña activa, el valor de un formulario o un mensaje de error.

¿Necesito sincronizar el componente con algo externo?

Probablemente necesitas useEffect.

Ejemplos: escuchar eventos del navegador, conectar con una API, actualizar el título del documento o trabajar con una librería externa.

¿Necesito acceder a un elemento del DOM o guardar un valor mutable?

Probablemente necesitas useRef.

Ejemplos: enfocar un input, guardar un temporizador o conservar una referencia que no debe provocar renderizados.

¿Necesito compartir datos entre muchos componentes?

Probablemente necesitas useContext, aunque conviene valorar si unas props serían suficientes.

¿Tengo un cálculo pesado o una función que provoca renderizados innecesarios?

Puede que necesites useMemo o useCallback, pero solo si hay un motivo claro.

Hooks en React y arquitectura de componentes

Los Hooks no solo sirven para resolver detalles técnicos. También influyen en cómo piensas la arquitectura de tus componentes.

Un componente debería tener una responsabilidad clara. Si empieza a tener demasiados estados, demasiados efectos y demasiadas funciones internas, quizá sea una señal de que necesita dividirse.

Puedes extraer:

  • Componentes más pequeños.
  • Hooks personalizados.
  • Funciones auxiliares.
  • Lógica de datos.
  • Lógica de presentación.

Esta separación ayuda a que el código sea más legible. También facilita el testing, la reutilización y la evolución del proyecto.

Por ejemplo, si estás construyendo una navegación compleja en React, puedes separar la lógica de rutas, anclas o scroll en componentes específicos. En ese caso, puede interesarte revisar también cómo utilizar React Router Hash Link para crear enlaces ancla en ReactJS.

La idea de fondo es sencilla: un buen componente no debería intentar hacerlo todo. Los Hooks te ayudan a encapsular comportamiento, pero también debes usarlos con intención.

FAQs sobre Hooks en React

¿Qué son los Hooks en React?

Los Hooks en React son funciones especiales que permiten usar características de React dentro de componentes funcionales. Por ejemplo, useState permite gestionar estado, useEffect permite sincronizar el componente con sistemas externos y useContext permite consumir datos de un contexto.

¿Cuál es la diferencia entre useState y useRef?

useState guarda valores que, al cambiar, provocan un nuevo renderizado del componente. useRef, en cambio, guarda una referencia mutable que se mantiene entre renderizados, pero su actualización no vuelve a renderizar la interfaz. Por eso useState es mejor para datos visibles y useRef para referencias internas.

¿Cuándo debería crear un Hook personalizado?

Deberías crear un Hook personalizado cuando detectes lógica repetida entre varios componentes o cuando quieras separar una responsabilidad concreta para mejorar la legibilidad. Por ejemplo, puedes crear Hooks para gestionar formularios, leer datos de localStorage, detectar el estado de conexión o encapsular llamadas a una API.

Elegir bien tus Hooks también es diseñar mejor tus componentes

Los Hooks en React no son simplemente una sintaxis moderna. Son una forma de organizar la lógica de los componentes de manera más clara, declarativa y reutilizable.

Aprender qué son los Hooks en React y cómo usarlos implica algo más que memorizar useState o useEffect. Significa entender cuándo un componente necesita estado, cuándo debe sincronizarse con algo externo, cuándo una referencia mutable es suficiente y cuándo merece la pena extraer lógica a un Hook personalizado.

La mejor recomendación es empezar por lo simple. Usa useState cuando necesites estado. Usa useEffect solo cuando exista una sincronización real con algo externo. Usa useRef cuando necesites conservar una referencia sin afectar al renderizado. Y deja useMemo y useCallback para casos donde realmente aporten claridad o rendimiento.

En React, escribir buenos componentes no consiste en usar todos los Hooks posibles, sino en elegir bien. Porque un componente bien diseñado no solo funciona: también se entiende, se mantiene y se puede hacer crecer sin que cada cambio se convierta en un pequeño incendio.

AutoLayout en Figma

El diseño de interfaces de usuario es una tarea fundamental en cualquier proyecto de software, y en la actualidad, la mayoría de las aplicaciones se ejecutan en diferentes dispositivos con diferentes tamaños de pantalla. Para abordar este desafío, Figma, una popular herramienta de diseño de interfaces de usuario, ofrece una solución llamada AutoLayout, que facilita la creación de diseños adaptables y responsivos.

¿Qué es AutoLayout?

AutoLayout es una función avanzada de Figma que permite crear diseños de UI dinámicos y adaptables en minutos. En lugar de tener que redimensionar manualmente cada elemento de la interfaz de usuario para que se ajuste a diferentes tamaños de pantalla, AutoLayout automatiza todo el proceso.

Cómo utilizar AutoLayout en Figma

Para empezar a utilizar AutoLayout, simplemente hay que seleccionar un grupo de elementos en el lienzo de Figma y, a continuación, activar la función de AutoLayout. A partir de ahí, Figma genera automáticamente los diferentes diseños para diferentes tamaños de pantalla, lo que permite visualizar cómo se verá la interfaz en diferentes dispositivos.

Personalización de AutoLayout

AutoLayout ofrece múltiples opciones para configurar cómo se comportan los elementos de la interfaz en diferentes tamaños de pantalla, lo que permite personalizar el diseño para que se adapte a las necesidades específicas del proyecto. Por ejemplo, se puede ajustar el espaciado entre elementos, la alineación de los objetos, la distribución de los elementos y mucho más.

Ventajas de AutoLayout

Una de las grandes ventajas de AutoLayout es que ahorra tiempo y esfuerzo. En lugar de tener que diseñar manualmente diferentes versiones de la interfaz de usuario para diferentes tamaños de pantalla, Figma lo hace por ti. Esto significa que puedes centrarte en la creatividad y el diseño de la interfaz de usuario, en lugar de preocuparte por la adaptabilidad y responsividad de la misma.

Además, AutoLayout también ayuda a garantizar la coherencia visual en la interfaz de usuario. Siempre que se realicen cambios en el diseño, Figma actualizará automáticamente todas las versiones de la interfaz de usuario creadas con AutoLayout, lo que evita errores y ahorra tiempo.

En resumen, AutoLayout es una herramienta muy poderosa e importante para cualquier diseñador de interfaces de usuario que quiera crear diseños adaptables y responsivos. Si eres un diseñador que trabaja con Figma, te recomendamos que empieces a utilizar AutoLayout para acelerar tu flujo de trabajo y mejorar la eficiencia de tus diseños. Con AutoLayout, podrás crear diseños que se adapten perfectamente a cualquier tamaño de pantalla sin sacrificar la calidad y la coherencia visual.

Entradas relacionadas