你是否也有同感?一遍遍写重复的规则,为了一个小逻辑去绕 JavaScript,担心设计系统越用越乱。今天我们来看看一个简单却强力的 CSS 特性:它不仅能让样式表更清爽,还能高度复用。

这些年我一直在和 CSS 打交道,反复打磨样式表,只为追求“干净又灵动”的设计平衡。

你是否也有同感?一遍遍写重复的规则,为了一个小逻辑去绕 JavaScript,担心设计系统越用越乱。

今天我们来看看一个简单却强力的 CSS 特性:它不仅能让样式表更清爽,还能高度复用。

一起上手。

写出干净、可复用的 CSS

最近留意到 Chrome 139 带来的新能力——@function 规则。真心讲,既“酷”又“好用”。

这不只是又一个 CSS 语法点,而是一种更“聪明”的写法:让复用与逻辑封装成为日常,风格贴近 2025 年的现代前端。

接下来我们用它来简化设计系统:从流式排版到主题切换,你可以把示例代码直接落地到项目里。

@function 是什么?

@function 允许你定义自定义 CSS 函数,把可复用的样式逻辑封装起来。你可以把它想成 CSS 里的“迷你 JavaScript 函数”:纯粹、声明式、由浏览器原生支持。

为什么这对你很重要?

因为它能减少重复代码,让样式在不依赖预处理器或脚本的情况下更具动态性。

先看个直观示例:

@function --dashed-border(--color: red) {
  result: 2px dashed var(--color);
}

这段代码创建了一个可复用的“虚线边框”函数。更妙的是:你还能给参数设置默认值——上面默认色就是 red

用法如下:

div {
   border: --dashed-border(blue); /* 2px dashed blue */
}

简洁、直接、可复用。干净吧?

实用场景 1:优雅求“负”的工具

有时我们需要负值(比如外边距或定位),但 calc() 连用起来很凌乱。

自定义 @function 就能把它封成一行、处处可用:

/* 返回某个值的相反数 */
@function --negate(--value) {
  result: calc(-1 * var(--value));
}
.navigation {
  margin: --negate(30px);
}

任何值一键“取负”,布局更灵活。告别满屏 calc()。是不是顺手多了?

实用场景 2:不费力的透明度处理

给颜色做透明变化(比如 hover 或 disabled 态),过去常常意味着重复规则或拉上 JS。

现在,@function 把这套逻辑集中到一个地方:

/* 返回半透明的颜色值 */
@function --opacity(--opacity, --color: #007bff) {
  result: rgb(from var(--color) r g b / var(--opacity));
}
button {
  background: --opacity(0.8);
}

button:hover {
  background: --opacity(1);
}

button:disabled {
  background: --opacity(0.3, gray);
}

再配合主题或状态相关的自定义属性,你就能写出无需额外类名的动态按钮样式。并且这里也给颜色参数留了默认值。

实用场景 3:顺滑可控的流式排版

响应式设计里,流式排版很关键;但反复写 clamp(),真心费劲。

用 @function 把它变成一句话:

@function --fluid-type(--font-min, --font-max, --type: 'header') {
  --scalar: if(style(--type: 'header'): 4vw; 
               style(--type: 'copy'): 0.5vw);
  result: clamp(var(--font-min), var(--scalar) + var(--font-min), var(--font-max));
}
h1 {
  font-size: --fluid-type(24px, 36px);
}

p {
  font-size: --fluid-type(16px, 24px, 'copy');
}

    字体会随视口平滑缩放,并可根据标题/正文字体分别设置缩放强度。

    没函数之前手写?那体验,别提了 😅。

    实用场景 4:自适应边界的条件圆角

    当元素贴近视口边缘时,让圆角“收起来”,能避免难看的贴边效果;但为此写媒体查询就有点小题大做。

    @function 的写法更干净:

    /* 当元素距离屏幕边缘在一定阈值内(默认 4px,可传第二参)时,按条件收缩圆角 */
    @function --conditional-radius(--radius, --edge-dist: 4px) {
      result: clamp(0px, ((100vw - var(--edge-dist)) - 100%) * 1e5, var(--radius));
    }
    /* 用法 */
    .box {
      /* 1rem 圆角,默认 4px 边缘距离 */
      border-radius: --conditional-radius(1rem);
    }
    
    .box-2 {
      /* 1rem 圆角,紧贴边缘(0px 距离) */
      border-radius: --conditional-radius(1rem, 0px);
    }

    当元素触到视口边缘时,圆角自动收敛,版面更干净。

    无需媒体查询。这就是我偏爱的 CSS 风格。

    实用场景 5:把明暗主题拓展到“任何属性”

    light-dark() 对颜色很好用,但边框、字重、尺寸这些怎么办?

    自定义 @function 可以把主题逻辑扩展到任意属性

    /* 若用户的颜色偏好为浅色,取第一个值;若为深色,取第二个值 */
    @function --light-dark(--light, --dark) {
      result: if(
        style(--scheme: dark): var(--dark);
        else: var(--light)
      );
    }
    :root {
      --root-scheme: light;
      --scheme: light;
    
      @media (prefers-color-scheme: dark) {
        --root-scheme: dark;
        --scheme: dark;
      }
    } 
    
    @scope ([data-scheme]) {
      :scope {
        --scheme-from-attr: attr(data-scheme type());
          --scheme: if(
            style(--scheme-from-attr: system): var(--root-scheme);
            else: var(--scheme-from-attr)
          );
        color-scheme: var(--scheme); /* 让原生 light-dark() 生效 */
      }
    }

    用法示例:

    [data-scheme] {
      color: light-dark(#333, #e4e4e4);
      background-color: light-dark(aliceblue, #333);
    
      border: 4px --light-dark(dashed, dotted) currentcolor;
      font-weight: --light-dark(500, 300);
      font-size: --light-dark(16px, 18px);
    }
    <div class="stylable-thing" data-scheme="light">
     …
    </div>

    实用场景 6:侧栏网格的响应式函数

    我们再写一个侧栏布局的小工具:

    /* 小屏下侧栏占 1fr;>=640px 时侧栏固定宽度,其余空间给主内容 */
    @function --layout-sidebar(--sidebar-width: 20ch) {
      result: 1fr;
      
      @media (width > 640px) {
        result: var(--sidebar-width) auto;
      }
    }
    
    .layout {
      display: grid;
      /* 使用默认 20ch 的侧栏宽度 */
      grid-template-columns: --layout-sidebar();
    }

    这个函数能把侧栏/主内容的响应式切换一步到位:小屏单列,大屏固定侧栏 + 自适应主区域。

    加餐:给函数也做“类型检查”

    就像 @property 可以为自定义属性约束类型一样,CSS @function 也能限制参数与返回值的类型。结合内联条件表达式,还能做更安全的动态计算。

    示例如下:

    @function --custom-spacing(--a <length>) { /* ... */ } /* 例:10px */
    @function --custom-background(--b <color>) { /* ... */ } /* 例:hsl(50%, 30% 50%) */
    @function --custom-margin(--c <length>+) { /* ... */ } /* 例:10px 2rem 20px */
    @function --wideness(--d type(<number> | <percentage>)) { /* ... */ }

    我们甚至可以为返回值声明类型:

    @function --progression(--current, --total) returns <percentage> {
      result: calc(var(--current) / var(--total) * 100%);
    }

    为什么说它“像未来”?

    以往这类逻辑常靠 Sass 或 JavaScript 处理;而现在,@function 把它原生落在 CSS 层。

    意义不止是“写得更少”,更是让样式具备智能适配能力

    同时,这也顺应了 React 19 对渲染优化的趋势:样式更精简,应用更迅速。

    但要注意什么?

    Chrome 139 毕竟是前沿版本,浏览器支持度暂时有限。这里没有可用的 polyfill,但你可以用特性检测回退策略来兼容旧环境。

    .browser-support {
      margin: 2rem auto;
      width: max-content;
      @supports (color: --function(value)) {
        display: none;
      }
    }

    这样就能在尝试新特性的同时,保证线上安全。

    AI大模型学习福利

    作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

    一、全套AGI大模型学习路线

    AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

    因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取

    二、640套AI大模型报告合集

    这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

    因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获

    三、AI大模型经典PDF籍

    随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。


    因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获

    四、AI大模型商业化落地方案

    因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获

    作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量

    Logo

    Agent 垂直技术社区,欢迎活跃、内容共建。

    更多推荐