¿Por qué el CSS necesita funciones personalizadas?
Durante años, los desarrolladores de CSS han dependido de preprocesadores como Sass para traer lógica y reutilización a las hojas de estilo. Pero ahora la plataforma está evolucionando. La regla @function de CSS, parte del Módulo de Funciones y Mixins Personalizados Nivel 1, te permite definir tus propias funciones directamente en CSS, sin necesidad de build.
Imagina poder escribir una función que calcule un porcentaje de progreso, ajuste el espaciado según una escala, o incluso devuelva un color con transparencia. Con @function, puedes encapsular lógica compleja y reutilizarla a lo largo de tus estilos.
Esto no es solo azúcar sintáctico. Es un cambio fundamental hacia un CSS más mantenible y con seguridad de tipos. Vamos a ver cómo funciona.
Nota:
@functiones experimental. Verifica el soporte del navegador antes de usarlo en producción.

Sintaxis Básica y Ejemplos Prácticos
Definir una función básica
Una función personalizada comienza con @function, seguido de un nombre --ident, parámetros opcionales y un descriptor returns. Dentro, usamos el descriptor result para devolver un valor.
/* Define una función que divide cualquier longitud a la mitad */
@function --half(--size) returns {
result: calc(var(--size) / 2);
}
/* Uso */
.container {
margin-inline: --half(20px); /* 10px */
}
Verificación de tipos para seguridad
Puedes forzar los tipos de entrada usando corchetes angulares, similar a @property. Esto ayuda a evitar errores en proyectos grandes.
/* Solo acepta números y devuelve porcentaje */
@function --progression(--current, --total) returns {
result: calc(var(--current) / var(--total) * 100%);
}
.progress-bar {
width: --progression(3, 5); /* 60% */
}
Trabajar con listas y valores por defecto
Para pasar listas, usa el sufijo # y envuelve los valores en llaves. También se admiten valores por defecto.
/* Calcula el rango de una lista más un valor extra */
@function --get-range(--list#, --n) {
result: calc(max(var(--list)) - min(var(--list)) + var(--n));
}
div {
padding-block: --get-range({10px, 100px, 50px, 25px}, 200px); /* 290px */
}
Funciones anidadas y variables locales
Puedes anidar funciones y usar propiedades personalizadas locales, manteniendo el código modular y limpio.
@function --square(--n) {
result: calc(var(--n) * var(--n));
}
@function --circle-area(--radius) {
--pi: 3.14159;
result: calc(var(--pi) * --square(var(--radius)));
}
.blob {
width: calc(--circle-area(10) * 1px); /* 314.159px */
}
Usar la cascada para lógica responsive
Como result sigue la cascada de CSS, puedes usar media queries o container queries para devolver valores diferentes.
@function --suitable-font-size() returns {
result: 16px;
@media (width > 1000px) {
result: 20px;
}
}
body {
font-size: --suitable-font-size();
}
Recuerda: La última declaración válida gana. Si colocas el fallback después de la media query, sobrescribirá.

Limitaciones y Precauciones
Aunque @function es potente, tiene reglas estrictas:
- Sin efectos secundarios: No puedes cambiar propiedades ni generar múltiples declaraciones. Eso está reservado para la propuesta
@mixin. - Dependencias circulares: Si una función se llama a sí misma (directa o indirectamente), el navegador la marca como inválida. Lo mismo ocurre con propiedades personalizadas que dependen de la función.
- Mismatch de tipos: Si un argumento no coincide con el tipo declarado, toda la llamada a la función se vuelve inválida.
Soporte del navegador y progressive enhancement
Actualmente, @function solo se admite con flags en algunos navegadores. Los navegadores sin soporte ignoran la regla, así que usa fallbacks y @supports para progressive enhancement.
@supports (at-rule(@function)) {
/* Usa funciones personalizadas */
}
Sin embargo, ten en cuenta que la condición at-rule() en sí tiene soporte limitado (solo Chrome 148+). Para estado actualizado, consulta Can I use.

Conclusión y Próximos Pasos
La @function de CSS es un cambio de juego para crear estilos sostenibles y con lógica. Empieza a experimentar en tus proyectos locales para familiarizarte con la sintaxis y las capacidades. Cuando el soporte de los navegadores mejore, estarás listo para adoptarla en producción.
Para una inmersión más profunda en características modernas de CSS, echa un vistazo a nuestra guía sobre container queries y ejemplos prácticos de custom properties.
Si te interesa cómo decidir entre modales y páginas separadas en UX, tenemos un árbol de decisión definitivo que puede ayudarte. Y para quienes trabajan con sistemas distribuidos, nuestro tutorial de comunicación PyTorch es un gran recurso.
Fuente: CSS-Tricks Almanac: @function