DEV Community

Cover image for Let’s Explore the New CSS “@function” Rule
Almaz Bisenbaev
Almaz Bisenbaev

Posted on

Let’s Explore the New CSS “@function” Rule

If you've been keeping an eye on the evolution of CSS, you might have heard about this new feature that kinda turns CSS into a programming language (I’m exaggerating, but still).

The @function rule is a proposed addition to CSS that lets us define custom functions. It’s kinda similar what we call Mixins in Sass.

In this post I’ll try to show you how it works and what we can do with it. I’ll show you a few practical examples and use cases that highlight its potential to streamline your workflow and create more maintainable designs.

What is @function?

At its core, the @function rule is part of the CSS Functions and Mixins Module Level 1, a working draft from the W3C that introduces logic into CSS. Think of it as creating your own mini-functions that can accept arguments, perform computations, and return values. These functions are invoked similarly to custom properties (using a dashed name like --example-function()), but they go beyond simple variable substitution by supporting parameters, defaults and even conditional rules like @media.

Unlike built-in CSS functions such as calc() or clamp(), which are predefined, @function lets you define custom ones. This means you can encapsulate complex calculations or styles that would otherwise clutter your code or require external tools. It's especially useful for design systems where consistency and scalability are the key.

The rule is still emerging, but as of the end of 2025, it's starting to land in Chromium-based browsers. Firefox and Safari support is pending, so for now, it should be used with @supports or as a progressive enhancement.

How Does @function Work? A Quick Syntax Overview

Creating a function is simple and straightforward. You use the @function at-rule followed by a dashed name, optional parameters with types and defaults and a body that ends with a result descriptor specifying the output.

Here's the basic syntax:

@function --set-font-size(--size-small type(length), --size-large type(length)) {

  /* Let's say this is our condition */
  @media (width > 640px) {
    result: var(--size-small); /* We will return the first parameter for small screens */
  }

  result: var(--size-large); /* ... and the second one the above condition is not met */
}
Enter fullscreen mode Exit fullscreen mode

To use the function:

.heading {
  width: --set-font-size(24px, 36px);
}

.quote {
    width: --set-font-size(16px, 18px);
}
Enter fullscreen mode Exit fullscreen mode

This example may not look practical, but the point is that you can reuse the same function in different places many times.

Parameters can be of different types (e.g. length, color or more complex syntax via type()) and the function evaluates at computed-value time, inheriting context from where it's called. If arguments don't match, it falls back gracefully to an invalid value.

What We Can Do With @function

The real magic of @function lies in what it enables. Let’s see some examples.

1. Unit Conversions (e.g. pixels to rems)

Tired of manually converting units? Create a function to handle it automatically. This is great for accessibility-focused designs where rem units ensure better scaling.

@function --px-to-rem(--px type(length)) {
  result: calc(var(--px) / 16 * 1rem); /* Assuming 16px root font size */
}

h1 {
  font-size: --px-to-rem(32px);
}
Enter fullscreen mode Exit fullscreen mode

2. Color Manipulations (e.g. opacity or tints)

Functions shine in color processing. Need a semi-transparent version of a base color? Define an opacity helper:

@function --opacity(--color type(color), --level type(number): 0.5) {
  result: rgb(from var(--color) r g b / var(--level));
}

.button {
  background-color: --opacity(#F00, 0.8);
}
Enter fullscreen mode Exit fullscreen mode

This can extend to tinting, shading, or even contrast checks for better accessibility.

3. Fluid Typography and Scaling

One of the most popular use cases is fluid typography that scales smoothly with viewport size, clamped between min and max values.

@function --fluid-type(--min, --max, --scale) {
  result: clamp(
    var(--min),
    calc(var(--min) + var(--scale)),
    var(--max)
  );
}

h1 {
  font-size: --fluid-type(20px, 40px, 5vw);
}

p {
  font-size: --fluid-type(14px, 18px, 2vw);
}
Enter fullscreen mode Exit fullscreen mode

This makes responsive text effortless, adapting to different screen sizes without media queries everywhere.

These examples barely scratch the surface. Imagine functions for random values, advanced math, or even integrating with custom properties for theme switching. The key benefit? Reduced repetition, easier maintenance, and more expressive CSS.

Browser Support and Considerations

As mentioned, support is limited but growing. It's available in Chrome 139+ and Edge 139+, with Android variants following suit. For broader compatibility, wrap usages in @supports selector(--my-function()) { ... } to provide fallbacks. Keep an eye on updates, this could become a staple in CSS soon.

The @function rule is poised to transform how we write CSS, bridging the gap between static styles and dynamic logic. By enabling custom computations and conditionals, it empowers developers to build more robust, scalable designs without external dependencies. Whether you're tweaking colors, scaling elements or handling responsiveness, it's a tool that encourages creativity and efficiency.

Top comments (0)