@cssints/mise-en-mode

中文文档
0.35.1发布于 2026/11/07MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 7707

Mise en Mode for cssints: looks are themes in the layers app < author < viewer, set on data-mode scopes

原始使用文档

@cssints/mise-en-mode

The look layer of Mise en Mode for cssints: a look is a theme set on a data-mode scope, and looks from three sources are resolved by the Mode Contract. It is one call member of cssints/plugin scope() (positional arguments $tokens and $overrides, returning themes), so a look is checked against your token set, and check.contrast sees it. No runtime.

import { createTokens } from "cssints" with { type: "cssints" };
import { look } from "@cssints/mise-en-mode" with { type: "cssints" };

const t = createTokens({
  color: { $type: "color", bg: { $value: "#ffffff" }, fg: { $value: "#111111" } },
});

// look(tokens, expression, source, overrides, { scope? })
look(t, "dark", "app", { color: { bg: "#0b0b0f", fg: "#f3f4f6" } });
look(t, "dark", "viewer", { color: { bg: "#101018" } });
look(t, "hero", "author", { color: { bg: "#123456" } }, { scope: "article.post" });
@layer app, author, viewer;
@layer app {
  :where([data-mode="dark"], [data-mode~="dark/color"]) {
    --color-bg: #0b0b0f;
    --color-fg: #f3f4f6;
  }
}
@layer viewer {
  :where([data-mode="dark"], [data-mode~="dark/color"]) {
    --color-bg: #101018;
  }
}
@layer author {
  @scope (article.post) {
    :where([data-mode="hero"], [data-mode~="hero/color"]) {
      --color-bg: #123456;
    }
  }
}

The contract, as the package does it

  • Sources (Rule 5). source is "app", "author" or "viewer": the layers app < author < viewer, declared once after the engine's own (layers() of cssints), so a look beats the engine's :root fallbacks and a viewer's look beats an author's over the app's. Each variable fills from the most preferred source that sets it: the viewer look above sets only --color-bg, and --color-fg still comes from the app look.
  • Aspects and fragments (Rule 4). An aspect is a top-level group of the token set (color, typography). A look's overrides are split by it, one rule per aspect, and each rule matches the bare marker or its fragment: data-mode="dark" applies every aspect, data-mode="dark/color" only the color group.
  • Expressions. expression is a <custom-ident> or a string; a dotted reverse-DNS key is quoted at the call, look(t, '"com.alice.midnight"', "author", …), and matched exactly.
  • Containment (Rule 7). { scope: "article.post" } wraps the rule in @scope (article.post) { … }, so a foreign look cannot repaint the host's chrome. It is a selector, checked by the build.
  • Overrides are createGlobalTheme's: values by token path, each of the token's type, {color.bg} references allowed, checked in the types as you type and again at build time (color.bg value "blu" is not a <color>, located at the call). The aliases that depend on an overridden token are declared again on the scope.
  • Contrast. The looks of one expression and aspect are one cascade to check.contrast: they are laid over each other in layer order, so a viewer look that sets only the text colour is checked on the app look's background, and a poor combination fails the build.

A look prints no class: call it at a module's top level, like createGlobalTheme. Its types are inferred from the scope() definition in src/index.ts: there is no types file.

Changed from cssints/mise-en-mode, which this package replaces: look(expression, source, declarations, { scope }) took raw custom-property declarations ("--color-bg": "#000") that nothing checked; it is now look(tokens, expression, source, overrides, { scope }) with the token set first and the overrides by token path, so the declarations are checked, the aliases are re-derived and contrast sees them. Aspects are the groups of the tokens, no longer a table of --color- and --typography- prefixes, and a look emits themes, no longer globals.

cd packages/mise-en-mode && bun run test   # fixtures through the engine (output, errors, contrast), and the type test via bun run typecheck

Credits

Mise en Mode is an open style standard on AT Protocol (https://standard.mode.place), and the Mode Contract is its rules: data-mode scopes, the layers app < author < viewer, aspects. This package is an implementation of the contract on scope(); no code of the standard's site is copied.

版本与发布记录

@cssints/mise-en-mode 共发布 43 个版本,首次发布于 2026/10/11;过去 12 个月发布了 43 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.35.1latest2026/11/073 天前
0.35.02026/11/073 天前
0.34.02026/11/073 天前
0.33.02026/11/046 天前
0.32.02026/11/046 天前
0.31.02026/11/047 天前

关于 @cssints/mise-en-mode 的常见问题

@cssints/mise-en-mode 是什么?

Mise en Mode for cssints: looks are themes in the layers app < author < viewer, set on data-mode scopes

如何安装 @cssints/mise-en-mode?

在项目目录运行 npm install @cssints/mise-en-mode,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:cssints(^0.35.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@cssints/mise-en-mode 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cssints/mise-en-mode 支持 ESM 还是 CommonJS?

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

@cssints/mise-en-mode 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@cssints/mise-en-mode 可以商用吗?

@cssints/mise-en-mode 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cssints/mise-en-mode 的下载量有多少?

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

@cssints/mise-en-mode 还在维护吗?

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