Carbon Design System 排版基石:@carbon/type 的 Sass 使用指南与源码级原理解析
2026/9/16 18:04:15 网站建设 项目流程

Carbon Design System 排版基石:@carbon/type 的 Sass 使用指南与源码级原理解析

【免费下载链接】carbonA design system built by IBM项目地址: https://gitcode.com/GitHub_Trending/carbo/carbon

本文基于 IBM Carbon Design System(当前仓库 carbo/carbon)中@carbon/type包的 Sass 官方文档 编写。@carbon/type是 Carbon Design System 的排版基础包,封装了 IBM Design Language 的字阶(Type Scale)、字体(IBM Plex 系列)与整套排版设计令牌(Type Tokens),并内置了h1h2p等常见元素的有主见默认样式。读完本文,你将掌握@carbon/type的全部 Sass 用法:快速接入、四个核心 Mixin、类型令牌与工具类的选用、$prefix配置,以及其字阶公式、流式排版(Fluid Type)与 CSS 自定义属性等底层实现原理,可直接上手把它接入自己的项目。

一、@carbon/type 是什么

@carbon/type是 Carbon Design System 的排版包(当前仓库版本为11.67.0,见 packages/type/package.json),它提供三样核心能力:

  1. 字阶(Type Scale):一套从 12px 到 92px、共 23 个步进的字号系统;
  2. 字体(Fonts):IBM Plex 系列字体族及其回退栈(fallback stack);
  3. 排版设计令牌(Type Tokens):如productive-heading-01body-02等,每个令牌包含font-sizefont-weightline-heightletter-spacing的完整声明组合。

除此之外,它还带来"开箱即用"的默认样式:通过default-typeMixin 可以直接为h1~h6paem等 HTML 元素应用设计系统认可的排版,无需逐个手动书写。

从构建层面看,该包同时提供 JavaScript API(src/index.ts,构建产物为lib/index.jses/index.js)与 Sass 入口(index.scss,并在package.json中通过"sass": "index.scss"声明),本文聚焦其 Sass 侧能力。

二、快速开始:接入 @carbon/type

2.1 安装

@carbon/type是独立发布的 npm 包,与@carbon/layout(提供间距、字号 rem 换算)和@carbon/grid(提供断点系统)配合工作,这两者也是它的直接依赖(见 packages/type/package.json 的dependencies字段)。安装命令:

npm install @carbon/type # 或 yarn add @carbon/type

2.2 最小使用示例

在 Sass 中使用现代模块系统@use引入,并调用四个常用 Mixin:

@use '@carbon/type'; // 包含排版 reset:html 字号、body 字体与抗锯齿、code 等基线样式 @include type.reset(); // 包含默认排版样式,作用于 h1, h2, h3 等元素 @include type.default-type(); // 包含排版相关的工具类(utility classes) @include type.type-classes(); .selector { // 在任意选择器中套用某个类型令牌 @include type.type-style('productive-heading-01'); }

其中@use '@carbon/type'会加载包的 Sass 入口 packages/type/index.scss,该入口通过@forward依次暴露了 7 个子模块:scss/prefixscss/font-familyscss/scalescss/resetscss/stylesscss/classesscss/default-type。因此上述四个 Mixin 均可用type.前缀直接调用。

2.3 仓库内真实使用参考

仓库自带的示例工程 packages/type/examples/preview/src/styles.scss 展示了完整实践:先通过@use '@carbon/styles/scss/config' with (...)配置字体路径与需要加载的字体(含阿拉伯、梵文、希伯来、泰文等多语言 IBM Plex 字体),再@use '@carbon/type' as *;,随后直接@include reset();@include type-classes();,并基于$type-scale循环生成.type-scale-1~.type-scale-23演示类。

三、核心 API 详解

3.1 四个核心 Mixin

Export(导出)说明
@mixin type-classes生成排版工具类的 CSS(字体族、字重、斜体、各令牌)
@mixin reset生成 Carbon Design System 的基础排版基线样式
@mixin default-typeh1~h6pa等元素生成默认排版样式
@mixin type-style在任意选择器内输出某个类型令牌的全部声明

reset的源码细节:见 packages/type/scss/_reset.scss。它接收两个可选参数:

@mixin reset( $body-font-family: font-family('sans'), $mono-font-family: font-family('mono') )

输出内容为:

  • html { font-size: 100%; }—— 保证 rem 换算基准;
  • body使用sans字体族、regular(400)字重,并开启-moz-osx-font-smoothing: grayscale-webkit-font-smoothing: antialiasedtext-rendering: optimizeLegibility以优化渲染;
  • code使用等宽字体mono
  • strong提升为semibold(600)字重。

default-type的映射关系:见 packages/type/scss/_default-type.scss。它把语义元素映射到设计令牌,无需记忆字号即可获得规范排版:

元素令牌
h1heading-06
h2heading-05
h3heading-04
h4heading-03
h5heading-02
h6heading-01
pbody-02

同时它还为a设置链接色var(--cds-link-primary, #0062fe)(优先读取 CSS 自定义属性,缺失时回退到 IBM 蓝#0062fe),为em设置斜体。注意:aem使用--#{$prefix}-link-primary动态拼接,因此会跟随$prefix配置变化。

type-classes的生成逻辑:见 packages/type/scss/_classes.scss。它通过三个@each循环遍历$font-families$font-weights$tokens三张映射表,分别生成字体族、字重、以及每个令牌对应的工具类(见下节)。

3.2 类型工具类(Type classes)

type-classesMixin 会输出一批工具类,可直接用于 HTML 元素:

类名说明
.cds--type-{font-family}设置font-family。可选值:monosanssans-condensedsans-arabicsans-devanagarisans-hebrewsans-jpsans-krsans-thai-loopedsans-thaiserif
.cds--type-{font-weight}设置font-weight。可选值:light(300)、regular(400)、semibold(600)
.cds--type-italic设置font-style: italic
.cds--type-{token}将元素样式设置为对应类型令牌,如.cds--type-productive-heading-01

这些字体族与字重的完整定义位于 packages/type/scss/_font-family.scss:$font-families映射中每个字体族都带完整的回退栈,例如sans展开为'IBM Plex Sans', system-ui, -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', sans-serif$font-weights则定义了light: 300regular: 400semibold: 600三档推荐字重。

3.3 完整令牌清单(Token API)

下表列出了@carbon/type导出的全部类型令牌变量,均以!default声明(即允许你在@use ... with (...)之外通过 Sass Modules 覆写,或在使用前重新赋值覆盖)。它们以 Map 形式存在,每个值包含font-sizefont-weightline-heightletter-spacing(含breakpoints的为流式令牌,见 4.3 节)。

令牌变量!default
$label-01$legal-02$helper-text-01$helper-text-02
$body-short-01$body-compact-01$body-long-01$body-01
$body-short-02$body-compact-02$body-long-02$body-02
$code-01$code-02
$heading-01$productive-heading-01$heading-compact-01
$heading-02$productive-heading-02$heading-compact-02
$productive-heading-03$heading-03
$productive-heading-04$heading-04
$productive-heading-05$heading-05
$productive-heading-06$heading-06
$productive-heading-07$heading-07
$expressive-heading-01$expressive-heading-02$expressive-heading-03$fluid-heading-03
$expressive-heading-04$fluid-heading-04$expressive-heading-05$fluid-heading-05$expressive-heading-06$fluid-heading-06
$expressive-paragraph-01$fluid-paragraph-01
$quotation-01$fluid-quotation-01$quotation-02$fluid-quotation-02
$display-01$fluid-display-01$display-02$fluid-display-02$display-03$fluid-display-03$display-04$fluid-display-04

所有令牌被统一聚合进$tokens映射表(见 packages/type/scss/_styles.scss),该表同时是type-styleMixin 与type-classes工具类生成器的数据来源。命名上有两条规律值得注意:

  • productive / expressive / fluid 三大家族productive-*面向紧凑型产品界面,行高更小;expressive-*面向营销与叙事场景,行高更大且带响应式断点;fluid-*expressive-*的别名,强调随视口连续缩放;
  • 新旧令牌并存:如body-short-01/body-long-01(V10 遗留)与body-compact-01/body-01(V11 令牌)在$tokens中同时存在,部分旧令牌(如$caption-01$caption-02$helper-text-01)在源码中被标记为@deprecated,新项目应优先选用 V11 令牌。

四、配置项:$prefix 与 CSS 自定义属性前缀

@carbon/type支持通过 Sass Modules 的with语法进行配置:

@use '@carbon/type' with ( $prefix: 'custom-prefix' );

配置项完整列表如下:

选项说明默认值
$prefix用于选择器、CSS 自定义属性等的前缀'cds'

$prefix会影响三处输出(见 packages/type/scss/_prefix.scss):

  1. 工具类名.cds--type-sans变为.custom-prefix--type-sans
  2. CSS 自定义属性名type-style输出形如font-size: var(--cds-productive-heading-01-font-size, ...)的声明,前缀同样随之变化;
  3. default-type中的链接色var(--cds-link-primary, #0062fe)

此外_prefix.scss还声明了第二个配置变量$custom-property-prefix: 'cds' !default,它专门控制 CSS 自定义属性前缀,可由内部的configure($values)Mixin 单独设置,便于在工具类前缀与自定义属性前缀需要分离的场景(如与@carbon/themes协同)下使用。

五、源码级原理剖析

5.1 字阶公式:从 12px 到 92px

@carbon/type的字阶不是拍脑袋定死的数值,而是由一条递推公式生成(见 packages/type/scss/_scale.scss):

Yn = Yn-1 + {INT[(n-2)/4] + 1} * 2

其中Y1 = 12px。该公式的含义是:每跨过一个步进,字号在前一步基础上增加 2px、4px、6px…… 的阶梯增量(增量每 4 步提升 2px),使得字号在大尺寸段拉开间距、小尺寸段保持细腻,从 12px 一路递增到 92px,共 23 个步进。每个步进再通过@carbon/layoutto-rem转换为 rem 单位存入$type-scale列表。相关函数与 Mixin:

// 取第 $step 步的字号(rem) $fs: type-scale(8); // 或直接在选择器中设置 .selector { @include type-scale(8); // 等价于 @include font-size(8); }

5.2 type-style:令牌是如何输出的

type-styleMixin 的核心逻辑位于 packages/type/scss/_styles.scss:

@mixin type-style($name, $fluid: false, $breakpoints: gridconfig.$grid-breakpoints) { @if not map.has-key($tokens, $name) { @error 'Unable to find a token with the name: `#{$name}`'; } $token: map.get($tokens, $name); // 开启流体且令牌定义了 breakpoints 时,走流体排版 @if $fluid == true and map.has-key($token, 'breakpoints') { @include fluid-type($token, $breakpoints); } @else { // 否则输出 CSS 自定义属性 + 回退值 @include custom-properties($name, $token); } }

要点一:令牌名错误会直接编译报错@error),避免静默失败。要点二:默认输出的是CSS 自定义属性而非裸属性值,例如:

.selector { font-size: var(--cds-productive-heading-01-font-size, 0.875rem); font-weight: var(--cds-productive-heading-01-font-weight, 600); line-height: var(--cds-productive-heading-01-line-height, 1.28572); letter-spacing: var(--cds-productive-heading-01-letter-spacing, 0.16px); }

这一设计让主题系统可以在运行时通过覆盖自定义属性实现换肤,而编译期回退值保证了不依赖运行时变量时的可用性。仓库测试 packages/type/tests/scss-test.js 专门验证了这一行为:断言每个属性值都包含var(--且回退值与 JS 侧令牌productiveHeading01对应键一致。

5.3 流式排版(Fluid Type)

对于定义有breakpoints键的令牌(如$expressive-heading-03$display-04等),type-style($name, true)会启用流体排版:font-size不再由断点阶梯切换,而是通过calc()依据视口宽度连续计算:

.selector { @include type-style('expressive-heading-03', true); }

其原理(实现见_styles.scssfluid-typefluid-type-size,参考了 CSS-Tricks 的 fluid typography 方案):以当前断点宽度为min-vw、下一个含流体定义的断点宽度为max-vw,以两个断点的字号为min-font-size/max-font-size,输出形如font-size: calc(min + (max - min) * ((100vw - min-vw) / (max-vw - min-vw)))的插值公式。行高则使用百分比相对值,以适配动态字号。源码注释特别提醒:流体排版应谨慎用于固定宽度容器,因为字号完全取决于视口。同时,无breakpoints的令牌即使传true也会回退为普通静态输出。

5.4 与其它包的协作

@carbon/type处于 Carbon 设计令牌生态的中层:

  • 依赖@carbon/layout:负责to-rem换算等基础工具;
  • 依赖@carbon/grid:提供断点系统($grid-breakpointsbreakpoint()breakpoint-next()),供流体排版与令牌断点使用;
  • @carbon/themes约定共享 CSS 自定义属性前缀机制(源码中留有 TODO,计划将custom-propertiesMixin 抽取为两包共用模块)。

六、最佳实践小结

  1. 三段式引入reset()+default-type()建立全局排版基线,type-classes()按需输出工具类(体积敏感时可改为只引入自己用到的type-style);
  2. 优先用令牌而非手写数值:所有字号、行高、字重都通过令牌表达,保证与设计系统一致且可被主题覆盖;
  3. 区分静态与流体:正文、表格等密集内容用productive-*/body-*静态令牌;营销头图、大标题用expressive-*并开启$fluid: true
  4. 注意前缀一致性:自定义$prefix时,需同步确保 HTML 中使用的工具类名(如.cds--type-sans)与新前缀匹配;
  5. 多语言场景:阿拉伯、梵文、希伯来、泰文、日文、韩文等字体族已内置回退栈,仅需按示例工程方式在@carbon/styles$fonts配置中开启对应字体加载。

相关文档与源码入口:Sass 文档、包入口、令牌与流体实现、字阶实现、字体族与字重、Sass 测试。

【免费下载链接】carbonA design system built by IBM项目地址: https://gitcode.com/GitHub_Trending/carbo/carbon

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询