Design Systems

Design Token Typography: Từ Figma đến CSS

Updated Tháng 2 24, 2026
Design token kết nối thiết kế và phát triển — font family, kích thước, độ đậm, line-height và khoảng cách như những giá trị có cấu trúc, không phụ thuộc nền tảng.

Typography Design Tokens: From Figma to CSS

Design tokens are the connective tissue between design and engineering. Without them, a designer updates a font size in Figma and a developer independently updates a CSS value, and the two drift apart the moment anyone makes a second change. With tokens, both sides reference the same named values — and when a token changes, every design component and every code component changes with it automatically.

Typography tokens deserve particular attention because text is the most ubiquitous element in any interface. A system with robust typography tokens can change its body font, adjust its scale, or update line-height globally — all from a single source of truth.


What Are Typography Design Tokens?

A design token is a named, platform-agnostic value that represents a single design decision. Instead of hard-coding font-size: 16px in a component, you reference a token: font-size: var(--font-size-body). The value is stored once and consumed everywhere.

The W3C Design Tokens Community Group has been formalizing a standard format for tokens, and while full adoption is still in progress, the key concepts — names, types, values, and metadata — are already common across major tools like Figma Variables, Style Dictionary, and Theo.

Typography tokens cover several CSS properties, each of which benefits from tokenization:

  • font-family — which typeface or type stack
  • font-size — size at each scale step
  • font-weight — available weights (400, 500, 600, 700, etc.)
  • line-height — leading, expressed as a multiplier or fixed value
  • letter-spacing — tracking, often expressed in em units
  • font-style — italic, oblique
  • text-transform — uppercase, lowercase, capitalize
  • text-decoration — underline, strike-through

Not every property needs to be tokenized for every use case, but font-family, font-size, font-weight, and line-height are the minimum set for a functional typography token system.


Token Structure: Primitive, Semantic, Component

The most important architectural decision in a token system is the layering strategy. Well-designed token systems use three layers: primitive, semantic, and component.

Primitive tokens are the raw values — the complete palette of available options. They have no inherent meaning beyond their literal value.

/* Primitive tokens — the raw palette */
--font-size-100: 0.64rem;
--font-size-200: 0.8rem;
--font-size-300: 1rem;
--font-size-400: 1.25rem;
--font-size-500: 1.5625rem;
--font-size-600: 1.953rem;

--font-weight-regular: 400;
--font-weight-medium:  500;
--font-weight-semibold: 600;
--font-weight-bold:    700;

--line-height-tight:   1.15;
--line-height-snug:    1.3;
--line-height-normal:  1.5;
--line-height-relaxed: 1.65;

Semantic tokens give meaning to primitive values. They describe what the value represents in the design language, not just what its raw number is. Semantic tokens reference primitive tokens.

/* Semantic tokens — describe intent */
--font-size-body:        var(--font-size-300);
--font-size-body-sm:     var(--font-size-200);
--font-size-heading-sm:  var(--font-size-500);
--font-size-heading-md:  var(--font-size-600);
--font-size-caption:     var(--font-size-200);
--font-size-label:       var(--font-size-200);
--font-size-display:     var(--font-size-700);

--font-weight-body:      var(--font-weight-regular);
--font-weight-heading:   var(--font-weight-semibold);
--font-weight-label:     var(--font-weight-medium);

--line-height-body:      var(--line-height-normal);
--line-height-heading:   var(--line-height-snug);
--line-height-caption:   var(--line-height-normal);

Component tokens are optional but useful in large systems. They scope a semantic token to a specific component context, allowing a component to be customized without changing global semantics.

/* Component tokens — scoped to a specific context */
--button-font-size:      var(--font-size-label);
--button-font-weight:    var(--font-weight-medium);
--button-line-height:    var(--line-height-tight);

--card-title-font-size:  var(--font-size-heading-sm);
--card-title-font-weight: var(--font-weight-semibold);

--badge-font-size:       var(--font-size-caption);
--badge-font-weight:     var(--font-weight-medium);
--badge-letter-spacing:  0.04em;

This three-layer approach means a decision at the primitive level (change --font-size-300 from 1rem to 0.9375rem) propagates through semantic tokens to every component using --font-size-body. No component CSS needs to change.


Defining Tokens in Figma

Since Figma introduced Variables in 2023, the workflow for maintaining a single source of truth has improved substantially. Prior to Variables, design tokens lived in code and were reflected in Figma styles by convention. Variables allow the design tool itself to store the canonical values.

Setting up primitive collections:

In Figma, create a variable collection named "Primitives" or "Foundation." Add variables for each font size, weight, and line-height using the raw numeric values. Set the type to Number for sizes and weights. At this layer, names should be purely descriptive: font/size/100, font/size/200, font/weight/400, font/weight/700.

The slash syntax in Figma variable names creates a nested grouping in the panel, making it easier to navigate large collections. font/size/300 appears in a font → size group.

Setting up semantic collections:

Create a second collection named "Semantic" or "Tokens." Variables in this collection reference primitive variables rather than raw values. font/size/body references font/size/300 from the Primitives collection.

Figma's variable aliasing makes this straightforward: when editing a semantic variable, choose "Variables" mode in the value selector and pick the appropriate primitive.

Text styles:

Figma text styles compose multiple token values into a single reusable style. A "Body" text style might bundle the semantic variables for font family, font size (body), font weight (regular), and line-height (normal). Text styles are what designers actually apply to text layers — variables are the values underneath.

The important constraint: text styles in Figma do not currently accept variable references for all properties. Font size and font weight can be linked to number variables. Font family and line-height support is more limited depending on the Figma version. This is an evolving area, and the Figma plugin ecosystem (particularly Tokens Studio) fills gaps where native Variables fall short.


Exporting to CSS Custom Properties

The goal is to generate CSS from the Figma token definitions without manual transcription. Several approaches exist:

Style Dictionary is the most mature and widely used transformation tool. It reads tokens defined in JSON or YAML and outputs them in any target format — CSS custom properties, JavaScript ES modules, Swift, Kotlin XML, or any custom format you define.

A Style Dictionary source file for typography tokens:

{
  "font": {
    "size": {
      "100": { "value": "0.64rem",    "type": "fontSizes" },
      "200": { "value": "0.8rem",     "type": "fontSizes" },
      "300": { "value": "1rem",       "type": "fontSizes" },
      "400": { "value": "1.25rem",    "type": "fontSizes" },
      "500": { "value": "1.5625rem",  "type": "fontSizes" },
      "600": { "value": "1.953rem",   "type": "fontSizes" },
      "700": { "value": "2.441rem",   "type": "fontSizes" }
    },
    "weight": {
      "regular":  { "value": "400", "type": "fontWeights" },
      "medium":   { "value": "500", "type": "fontWeights" },
      "semibold": { "value": "600", "type": "fontWeights" },
      "bold":     { "value": "700", "type": "fontWeights" }
    }
  }
}

Style Dictionary transforms this into:

:root {
  --font-size-100: 0.64rem;
  --font-size-200: 0.8rem;
  --font-size-300: 1rem;
  --font-size-400: 1.25rem;
  --font-size-500: 1.5625rem;
  --font-size-600: 1.953rem;
  --font-size-700: 2.441rem;

  --font-weight-regular: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
}

Tokens Studio (Figma plugin) connects directly to Figma and can export tokens in Style Dictionary-compatible JSON, commit them to a GitHub repository, and trigger CI pipelines to regenerate CSS. This is the closest thing to a fully automated Figma-to-CSS pipeline available today.

Direct Figma API: For teams building custom tooling, the Figma REST API returns all styles and variables for a file. A small Node script can extract typography values, apply naming transformations, and write CSS files to a repository.


Token Naming Conventions

Naming conventions determine whether your token system scales gracefully or becomes a maintenance burden. The key principles:

Use a consistent hierarchy separator. CSS custom properties use hyphens: --font-size-body. JSON files commonly use dots or slashes: font.size.body or font/size/body. Pick one and enforce it across all tools.

Order from general to specific. The hierarchy should read from category to subcategory to variant: font-size-heading-sm, not sm-heading-font-size. This groups related tokens together when sorted alphabetically.

Use semantic vocabulary at the semantic layer. Avoid positional names like font-size-large at the semantic layer because "large" is relative and changes meaning when you add a new step. Prefer role-based names: font-size-heading-md, font-size-caption, font-size-label.

Version your token names cautiously. Renaming a token breaks every component that uses it. When a token's meaning genuinely changes (a semantic token is repurposed), create a new token and deprecate the old one. Add a deprecation comment in the source and a migration note in the changelog.

Document units explicitly. Whether a line-height value is 1.5 (multiplier) or 24 (pixels) or 24px matters enormously. Make the unit convention explicit in your documentation and consistent across all tokens.

A reference naming pattern used by teams building on Google Fonts and Material Design tokens:

/* Pattern: --{category}-{property}-{variant}-{state} */
--font-size-body-md:       1rem;
--font-size-body-sm:       0.875rem;
--font-size-label-lg:      1rem;
--font-size-label-md:      0.875rem;
--font-size-label-sm:      0.75rem;
--font-size-headline-sm:   1.5rem;
--font-size-headline-md:   1.75rem;
--font-size-headline-lg:   2rem;
--font-size-display-sm:    2.25rem;
--font-size-display-md:    2.8125rem;
--font-size-display-lg:    3.5625rem;

Keeping Tokens in Sync

Defining tokens once is straightforward. Keeping them synchronized between Figma, code, and documentation over months and years is the real challenge. Several practices help:

Single source of truth, one direction of change. Decide whether Figma or code is canonical. Most teams treating design systems as engineering products make code the source of truth: tokens are defined in JSON, generated into CSS, and imported into Figma via plugin. Changes flow from JSON to code to Figma, not from Figma to code. This prevents the situation where a designer changes a Figma style and the code never catches up.

Token versioning and changelogs. Treat token files like code — version them with git, write meaningful commit messages when values change, and maintain a changelog. When a semantic token changes, the changelog entry should list what changed, why, and which component tokens or components are affected.

CI validation. Add a CI check that validates your token schema. Tools like Token Validator or custom scripts can verify that every semantic token resolves to a primitive, that all referenced primitives exist, and that no circular references exist. This catches token definition errors before they reach production.

Storybook visual testing. If your component library uses Storybook, run visual regression tests against a story that renders every type scale step. A token change that accidentally breaks a heading size will show up as a visual diff before it ships.

Figma library synchronization. When tokens change in code, publish an updated Figma library file and notify design teams through your standard design system communication channels. Figma's library update notification system will surface the "Libraries have updates" banner to every file consuming the library, but designers still need to understand what changed and why.

Typography tokens are never truly "done." As products evolve, new type roles emerge, new languages require additional consideration, and new platforms demand new output formats. Build the infrastructure to manage this evolution — version control, transformation pipelines, and validation tooling — from the beginning, and the token system will be an asset rather than a liability as your design system matures.

Type Scale Systems

Typography Terms

Try These Tools

Fonts Mentioned

Related Articles