@amsterdam/design-system-tokens

中文文档
4.4.0发布于 2026/10/22SEE LICENSE IN LICENSE.mdES Module零依赖构建来源已验证近 30 天下载 1.2万

All design tokens from the Amsterdam Design System. Use it to apply its visual design to your website or application.

原始使用文档
文档目录22 节
  1. Introduction
  2. Installation
  3. Usage in CSS
  4. Main stylesheet
  5. Compact overrides
  6. Lo-fi overrides
  7. Where to apply a mode
  8. Three layers
  9. Overriding tokens
  10. Deprecating tokens
  11. Renaming a token
  12. Removing a token
  13. Token types
  14. DTCG standard types
  15. Custom extensions
  16. Tokens that hold a single value
  17. Descriptions
  18. Usage in Sass
  19. Usage in JavaScript
  20. Usage in Figma
  21. Updating
  22. Support

Amsterdam Design System: Tokens

This package provides all design tokens from the Amsterdam Design System. Use it to apply its visual design to your websites. The tokens are exported in multiple formats, including CSS custom properties and JSON, making them compatible with most, if not all, technology stacks.

Note that the values of the tokens in this package implement the branding of the City of Amsterdam. If your project is not affiliated with the City of Amsterdam, you should not use this package. You are allowed to copy the token files if you change the values to your own branding.

Introduction

Every design token is a variable representing a single visual design choice. Tokens exist for colours, various aspects of text, spacing lengths, border widths, the configuration of animations, and more. The value of every token is valid in CSS. All tokens together form a theme that encodes the entire branding of the City of Amsterdam.

Installation

Install this package by itself if you want or need to reference tokens directly in your stylesheets.

Note that our CSS components and React components provide more functionality and apply the tokens automatically. You should use those packages if your application uses React or if it allows you to apply our HTML classes.

npm install @amsterdam/design-system-tokens

Usage in CSS

Tokens are typically used as custom properties in CSS. Their names start with a prefix of --ams-.

Main stylesheet

This package offers a main stylesheet containing all tokens. They are declared as global CSS variables through the :root selector.

import "@amsterdam/design-system-tokens/dist/index.css"

If that doesn’t work for your project, use index.theme.css instead, which uses an .ams-theme selector. Add that class to a root element of your application.

import "@amsterdam/design-system-tokens/dist/index.theme.css"
<body class="ams-theme">
  …
</body>

Compact overrides

Our visual style is quite spacious. This works well for public websites. The main stylesheet implements this ‘Spacious Mode’ as the default. A compact stylesheet is available for internal websites that require a high-density layout with reduced white space and smaller text.

Note that the compact stylesheet is not independent – it only contains overrides. Import it after the main stylesheet for the correct result.

import "@amsterdam/design-system-tokens/dist/index.css"
import "@amsterdam/design-system-tokens/dist/compact.css"

Pair compact.theme.css with index.theme.css if you apply the tokens through a class rather than through :root. Import it after the main stylesheet here as well, and add the ams-theme--compact class to the very element that carries the ams-theme class.

import "@amsterdam/design-system-tokens/dist/index.theme.css"
import "@amsterdam/design-system-tokens/dist/compact.theme.css"
<body class="ams-theme ams-theme--compact">
  …
</body>

Lo-fi overrides

A Lo-fi stylesheet is available to present work in progress as a sketch rather than a finished page. It renders all components in greyscale, replaces text with handwritten squiggles, gives borders a hand-drawn rounding, and shows crossed placeholder boxes instead of images. Layout, sizing, and spacing remain unchanged, so pages keep their realistic structure.

This stylesheet only contains overrides as well. Import it after the main stylesheet, together with the Redacted Script font from our assets package.

import "@amsterdam/design-system-tokens/dist/index.css"
import "@amsterdam/design-system-tokens/dist/lo-fi.css"
import "@amsterdam/design-system-assets/font/lo-fi/index.css"

Pair lo-fi.theme.css with index.theme.css if you apply the tokens through a class rather than through :root. Add the ams-theme--lo-fi class to the very element that carries the ams-theme class.

import "@amsterdam/design-system-tokens/dist/index.theme.css"
import "@amsterdam/design-system-tokens/dist/lo-fi.theme.css"
import "@amsterdam/design-system-assets/font/lo-fi/index.css"
<body class="ams-theme ams-theme--lo-fi">
  …
</body>

Lo-fi Mode combines freely with Compact Mode.

Where to apply a mode

A stylesheet that overrides token values must be declared on the same element as the tokens it overrides. That element is html when you use index.css, and the element carrying the ams-theme class when you use index.theme.css.

Applying a mode class like ams-theme--compact anywhere else – even on a child of the element with the ams-theme class – takes effect only in part. The tokens that the mode stylesheet declares itself, such as --ams-space-xl, do take their new value there. Any other token that refers to them keeps the value it resolved on the element where it was declared. Our components mostly read such tokens, so they silently keep their spacious values.

The cause is that CSS resolves a var() reference inside a custom property on the element where that property is declared. For example, --ams-paragraph-font-size refers to --ams-typography-body-text-font-size and is declared on the root element, where it resolves to the spacious font size. A paragraph deeper in the document inherits that resolved value, so overriding the typography token further down arrives too late.

Applying a mode to a part of a page is therefore not supported: our components would not follow it.

Three layers

The tokens are organised in three layers: brand, common and component.

Brand tokens

These express the corporate identity of the City of Amsterdam. They are our fundamental selection from all possible colours, text characteristics, spacing lengths, border widths, etc. Their names begin with our prefix, followed by a design category such as ‘color’, ‘typography’, or ‘space’.

Examples:

:root {
  --ams-color-feedback-error: #ec0000;
  --ams-space-m: 1rem;
  --ams-aspect-ratio-4-3: 4 / 3;
  --ams-border-width-l: 0.1875rem;
}

Find the list of brand tokens on GitHub.

Removing ‘default’ keys

Some brand tokens include a ‘default’ key in JSON to allow for additional variants, such as ams.color.interactive.default and ams.color.interactive.disabled However, this key is not needed for collections of variables that are flat, like our CSS custom properties. Therefore, we remove this key in non-nested variables. For instance, --ams-color-interactive and --ams-color-interactive-disabled.

Common tokens

Related components share visual design characteristics. For example, all links have the same colour, and the borders of various form inputs are equally thick. Common tokens express these relations and streamline future changes. Their names begin with our prefix, followed by the name of the group that uses them. This group name is plural to indicate that several components apply these tokens.

Design system components use common tokens where possible. The same goes for custom components that you may create in your application.

<a class="my-link" href="#">…</a>
.my-input {
  color: var(--ams-links-color);
  text-underline-offset: var(--ams-links-text-underline-offset);
}

Find the list of common tokens on GitHub.

Component tokens

Every design system component defines a token for every property that expresses branding and uses it in its stylesheet.

Use these tokens when recreating an existing component to receive the correct values for them – now and in the future. Do not apply these tokens to other components – components must be independent.

The name of a component token ends with the CSS property that uses it, e.g. -font-size. We follow the NL Design System token naming guidelines here.

<button class="my-button" type="button">Button label</button>
.my-button {
  font-family: var(--ams-button-font-family);
  background-color: var(--ams-button-primary-background-color);
}

Find the list of component tokens on GitHub.

Logical viewport inline size tokens

Some component tokens vary by viewport breakpoint and follow CSS logical properties naming:

  • vi means viewport inline size.
  • Breakpoint-specific variants use vi-medium and vi-wide, for example:
    • ams.menu.vi-wide.padding-inline
    • ams.dialog.vi-medium.inline-size
    • ams.grid.vi-medium.column-count

Components can also use narrow, medium or wide keys without the vi prefix when the dimension is intrinsic to the component and not tied to the active viewport breakpoint.

Overriding tokens

This package allows the creation of a theme to reuse our components for a different brand. This is a key feature of NL Design System of which we are part.

However, websites for the City of Amsterdam must follow the design system as closely as possible. We repeat: websites for the City of Amsterdam must follow the design system as closely as possible.

At the same time, we are aware that adopting a design system can pose challenges in practice. If there is a good reason to (temporarily) adapt a component, do so by overriding the values of its appropriate tokens in a separate stylesheet. Note that redefining the value of a token is a much better approach than redeclaring styles, adding class names or even inline styles.

Deprecating tokens

A deprecated token keeps working until it is removed, so it must always hold a real value.

We provide a reason and a migration path through the DTCG $deprecated field. When there is a direct replacement, start the message with Use `<replacement-token>` instead. End every message with a removal date: Will be removed on or after YYYY-MM-DD.

Renaming a token

Keep the old name intact during the deprecation window, while adding the new name for the same value. Wire the rename through a var() fallback, so downstream overrides of the old name keep working.

  1. Point the deprecated token’s $value at the replacement, so it resolves to the same value:
"medium": {
  "padding-inline": {
    "$deprecated": "Use `ams.grid.vi-medium.padding-inline` instead. Will be removed on or after 2026-10-20.",
    "$value": "{ams.grid.vi-medium.padding-inline}"
  }
}
  1. In the component CSS, reference the deprecated token first, with the replacement as the fallback: Mark the deprecation in the component stylesheet as well; no need to copy the details from the tokens file.
padding-inline: var(--ams-grid-medium-padding-inline /* @deprecated */, var(--ams-grid-vi-medium-padding-inline));
  1. If a theme overrides the replacement (for example Compact Mode), overriding the replacement token is enough because the deprecated token references it. Only repeat the deprecated token in a theme tokens file if you need to override the deprecated token itself for legacy consumers.

Removing a token

A removal will always be a breaking change, so it must be part of a major release. Plan the deprecation early, as it must stay in place for at least six months. The value of the token cannot change during the deprecation window, as we consider visual consequences for downstream users a breaking change.

"row-gap": {
  "$deprecated": "Whitespace is now applied through the `ams.description-list.*.margin-block-end` tokens. Will be removed on or after 2026-10-20.",
  "$value": "(unchanged value)"
}

Surface the deprecation in the stylesheet as well.

row-gap: var(--ams-description-list-row-gap); /* @deprecated Will be removed on or after 2026-10-20. */

Token types

Tokens may define their type using a DTCG $type, or, when no standard DTCG type applies, using our Amsterdam-specific $extensions.nl.amsterdam.type. References inherit the type of the token they refer to.

We also use group-level inheritance where all tokens in a group share the same DTCG type. A $type set on a group applies to all its descendants, so individual tokens do not need to repeat it.

DTCG standard types

The following types come from the Design Tokens Community Group (DTCG) specification:

TypeDescription
colorAny colour value
dimensionAny dimension with a unit
durationA length of time
fontFamilyFont family definitions (string array)
fontWeightFont weight values
numberUnitless numeric values
shadowBox shadow definitions

Custom extensions

Type

We add a custom type under $extensions.nl.amsterdam.type for:

  1. tokens that refer to another token
  2. properties that the DTCG specification does not cover
  3. values that do not conform to a standard type

We use these types to help decide which preview to render in the Design Tokens Table on each component’s documentation page.

TypeDescription
aspectRatioAspect ratio values
backgroundImageBackground image values (e.g. SVGs)
backgroundPositionBackground position values
borderBorder shorthand values
borderRadiusBorder radius values
borderStyleBorder style values
borderWidthBorder thickness values
cursorCursor values
dimensionResponsive dimensions
fontSizeFont size values
gridTemplateColumnsGrid track definitions
hyphenateLimitCharsHyphenation limit values
listStyleTypeList marker styles
opacityOpacity values
textDecorationLineText decoration line values
textWrapText wrapping values
transitionTimingFunctionTransition timing function values

Note that dimension appears both as a standard $type and as a custom extension type. The standard type is for values that conform to the DTCG dimension format (an object with a value and unit). The extension type is for responsive dimensions that use clamp() expressions, which are not valid DTCG dimensions.

Subtype

We add a subtype for certain types to further specify their purpose and preview.

SubtypeFor typeDescription
lineHeightnumberLine height multipliers
spacedimensionMargins, paddings and gaps

Hint

An $extensions.nl.amsterdam.hint indicates special handling for internal use.

Tokens that hold a single value

A token typed as a dimension must resolve to exactly one value, whichever of the two spellings gives it that type.

A dimension is read through calc(), clamp(), max() or min(), or assigned to a longhand such as padding-inline-start, and none of those take two values. Given two, the declaration is invalid at computed-value time and the property falls back to its initial value rather than to the token, so the padding disappears rather than degrading.

The build enforces this: pnpm build fails and names every token that resolves to more than one value. A deprecated token is left alone, since its value cannot change while it waits to be removed.

Where a value per side is wanted, split the token in two and set the longhands:

"padding-block-start": {
  "$value": "{ams.space.l}",
  "$extensions": { "nl.amsterdam.subtype": "space", "nl.amsterdam.type": "dimension" }
},
"padding-block-end": {
  "$value": "0",
  "$type": "dimension",
  "$extensions": { "nl.amsterdam.subtype": "space" }
}

The ams/require-single-value-token Stylelint rule enforces the same constraint in the stylesheets that read the tokens.

Descriptions

Brand and common tokens use the DTCG $description property to explain the purpose of a token or group when the name alone is not sufficient. Add a $description when a token has a non-obvious value (e.g. currentColor), when similar tokens need to be distinguished (e.g. background.body vs background.default), or when the value encodes design rationale worth preserving (e.g. pixel equivalents for responsive clamp() values).

Usage in Sass

The tokens can be imported as Sass variables as well. As they are already prefixed, the namespace that Sass would assign isn’t necessary.

@use "@amsterdam/design-system-tokens/dist/index.scss" as *;

Import the compact tokens if needed. Note that Sass doesn’t allow importing them alongside the default set due to naming conflicts. Address these tokens through the compact namespace and do not use the spacious tokens they replace.

@use "@amsterdam/design-system-tokens/dist/compact.scss";

.class {
  padding-block: compact.$ams-space-m;
}

Usage in JavaScript

Import the JSON file to use the tokens in TypeScript or JavaScript. Here, tokens start their name with a prefix of ams.. Use ‘dot notation’ or square brackets to access the tokens.

import tokens from "@amsterdam/design-system-tokens/dist/index.json"

const buttonBackgroundColor = tokens.ams.color.interactive.default
const rowGap = tokens.ams.space.m

Import and merge the compact tokens if you need them. Then you can use the tokens in scripting or css-in-js libraries.

import compactTokens from "@amsterdam/design-system-tokens/dist/compact.json"
import spaciousTokens from "@amsterdam/design-system-tokens/dist/index.json"

const tokens = { ...spaciousTokens, ...compactTokens }

Usage in Figma

The tokens are used in our Figma Library as well.

Updating

We follow semantic versioning and publish a change log to guide you through updates. The tokens are a public API of the design system. Note that detecting changed or deleted tokens is still a manual process.

Support

Contact us if you have a question, find an issue, or want to contribute. Find ways to reach us on designsystem.amsterdam.

版本与发布记录

@amsterdam/design-system-tokens 共发布 43 个版本,首次发布于 2023/02/10;过去 12 个月发布了 12 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
4.4.0latest2026/10/2216 天前
4.3.02026/08/092 个月前
4.2.02026/07/133 个月前
4.1.02026/06/244 个月前
4.0.12026/04/256 个月前
4.0.02026/04/206 个月前

关于 @amsterdam/design-system-tokens 的常见问题

@amsterdam/design-system-tokens 是什么?

All design tokens from the Amsterdam Design System. Use it to apply its visual design to your website or application.

如何安装 @amsterdam/design-system-tokens?

在项目目录运行 npm install @amsterdam/design-system-tokens,或使用 pnpm add / yarn add / bun add。

@amsterdam/design-system-tokens 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/amsterdam__design-system-tokens 是否存在。

@amsterdam/design-system-tokens 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@amsterdam/design-system-tokens 可以商用吗?

@amsterdam/design-system-tokens 使用 SEE LICENSE IN LICENSE.md 许可。许可条款写在包内的独立文件中,请阅读该文件确认可否商用。以上为概括,不构成法律意见,请以许可原文为准。

@amsterdam/design-system-tokens 的下载量有多少?

根据 npm 官方下载统计,@amsterdam/design-system-tokens 在 2026/10/06 – 2026/11/04 这 30 天内被下载 12,335 次,日均约 411 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@amsterdam/design-system-tokens 还在维护吗?

最新版本 4.4.0 发布于 2026/10/22(16 天前);至今共发布 43 个版本,其中过去 12 个月发布了 12 个;首次发布于 2023/02/10。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。