网站导航

快速开始

Master CSS 入门

使用类构建界面,追踪对应的 CSS,并定义项目共用的值。

本页内容

Master CSS 是一个 CSS 框架,用于在标记中设置界面样式,并在 CSS 中定义共用样式。创建元素时,就在相应位置编写类;整个项目共用的值和模式,则放在样式表中。Master 会生成这些类所需的 CSS。

可以从内置的颜色、间距和排版设置开始。创建第一个组件之前,不必先设计完整的主题。

#使用 CSS 和工具类构建界面

这张卡片结合了原生组件类与工具类。.action 在 CSS 中定义按钮的基础样式;w-full、mt-md 和 bg-blue-60 则为这张卡片设置按钮的宽度、外边距和颜色。其余标记使用预设工具类处理布局、间距和排版。

完成安装后,将示例的 CSS 添加到应用样式表中预设导入语句之后,再把 HTML 放入集成工具会扫描的源文件:

app.css
@import '@master/css';

使用 CSS 与工具类制作的卡片

@layer components {  .action {    display: flex;    align-items: center;    justify-content: center;    min-height: 2.75rem;    padding: var(--spacing-xs) var(--spacing-md);    border-radius: var(--radius-md);    font-size: var(--text-sm);    font-weight: var(--font-weight-regular);    line-height: var(--text-sm--line-height, normal);    letter-spacing: var(--text-sm--letter-spacing, normal);    text-decoration-line: none;    outline-offset: 3px;    &:focus-visible {      outline: 2px solid;    }  }}
生成的 CSS
@layer components {  .action {    min-height: 2.75rem;    padding: var(--spacing-xs) var(--spacing-md);    border-radius: var(--radius-md);    font-size: var(--text-sm);    font-weight: var(--font-weight-regular);    line-height: var(--text-sm--line-height, normal);    letter-spacing: var(--text-sm--letter-spacing, normal);    outline-offset: 3px;    justify-content: center;    align-items: center;    text-decoration-line: none;    display: flex;    &:focus-visible {      outline: 2px solid;    }  }}@layer theme {  :root,  :host {    --color-zinc-40: oklch(68.6% .0028 265);    --color-zinc-60: oklch(48.6% .003 265);    --color-zinc-90: oklch(24.6% .0022 265);    --color-zinc-100: oklch(15% .0016 265);    --color-blue-30: oklch(72.87% .1468 249.3);    --color-blue-60: oklch(51.83% .2687 266.1);    --color-blue-70: oklch(46.26% .3057 266.7);    --color-blue-80: oklch(42.89% .2907 266.3)  }  :root,  :host {    --color-surface-raised: light-dark(var(--color-white), var(--color-zinc-90));    --color-text-strong: light-dark(var(--color-zinc-100), var(--color-white));    --color-text-muted: light-dark(var(--color-zinc-60), var(--color-zinc-40));    --color-text-blue: light-dark(var(--color-blue-60), var(--color-blue-30))  }  :root,  :host {    --color-white: oklch(100% 0 none)  }  :root,  :host {    --tracking-widest: .12em;    --leading-lg: 1.8;    --font-weight-regular: 400;    --font-size-2xs: .625rem;    --font-size-sm: .875rem;    --font-size-md: 1rem;    --text-2xs: var(--font-size-2xs);    --text-2xs--line-height: 1.5;    --text-2xs--letter-spacing: 0;    --text-sm: var(--font-size-sm);    --text-sm--line-height: 1.5;    --text-sm--letter-spacing: 0;    --text-md: var(--font-size-md);    --text-md--line-height: 1.6;    --text-md--letter-spacing: 0;    --radius-md: .375rem;    --radius-lg: .5rem;    --spacing-xs: .5rem;    --spacing-md: 1rem;    --spacing-lg: 1.5rem  }  :root,  :host {    --shadow-sm: 0 0 0 1px light-dark(oklch(0% 0 none / .04), oklch(100% 0 none / .05)), 0 1px 1px -.5px light-dark(oklch(0% 0 none / .045), oklch(0% 0 none / .3)), 0 2px 2px -1px light-dark(oklch(0% 0 none / .04), oklch(0% 0 none / .26)), 0 4px 4px -2px light-dark(oklch(0% 0 none / .04), oklch(0% 0 none / .24))  }}@layer utilities {  .text-2xs {    font-size: var(--text-2xs);    line-height: var(--text-2xs--line-height, normal);    letter-spacing: var(--text-2xs--letter-spacing, normal)  }  .text-md {    font-size: var(--text-md);    line-height: var(--text-md--line-height, normal);    letter-spacing: var(--text-md--letter-spacing, normal)  }  .text-sm {    font-size: var(--text-sm);    line-height: var(--text-sm--line-height, normal);    letter-spacing: var(--text-sm--letter-spacing, normal)  }  .bg-blue-60 {    background-color: var(--color-blue-60)  }  .bg-surface-raised {    background-color: var(--color-surface-raised)  }  .r-lg {    border-radius: var(--radius-lg)  }  .shadow-sm {    box-shadow: var(--shadow-sm)  }  .fg-text-blue {    color: var(--color-text-blue)  }  .fg-text-muted {    color: var(--color-text-muted)  }  .fg-text-strong {    color: var(--color-text-strong)  }  .fg-white {    color: var(--color-white)  }  .block {    display: block  }  .font-regular {    font-weight: var(--font-weight-regular)  }  .h-auto {    height: auto  }  .tracking-widest {    letter-spacing: var(--tracking-widest)  }  .leading-lg {    line-height: var(--leading-lg)  }  .m\(0\) {    margin: calc(0 * 1px)  }  .mx-auto {    margin-inline: auto  }  .mt-md {    margin-top: var(--spacing-md)  }  .mt-xs {    margin-top: var(--spacing-xs)  }  .mb\(0\) {    margin-bottom: calc(0 * 1px)  }  .object-cover {    object-fit: cover  }  .overflow-hidden {    overflow: hidden  }  .p-lg {    padding: var(--spacing-lg)  }  .uppercase {    text-transform: uppercase  }  .w-full {    width: 100%  }  .\(aspect-ratio\:16\/9\) {    aspect-ratio: 16/9  }  .\(max-width\:22\.5rem\) {    max-width: 22.5rem  }  .bg-blue-70\:hover:hover {    background-color: var(--color-blue-70)  }  .outline-blue-60\:focus-visible:focus-visible {    outline-color: var(--color-blue-60)  }  .bg-blue-80\:active:active {    background-color: var(--color-blue-80)  }}
action 类定义按钮的基础样式。这个实例的宽度、外边距和蓝色由工具类指定。将指针悬停在链接上,或让链接获得焦点,查看交互状态。

预览会同时使用展示的 CSS 和 HTML。这个示例在 @layer components 中定义 .action;Master 根据标记中的类生成工具类规则。将按钮共用的形态和焦点样式保留在 .action 中,而这个实例的蓝色和全宽设置仍由标记指定。

试着将 p-lg 改为 p-md:卡片内容的内边距会缩小,但按钮的基础样式不会改变。

图片 URL 假定应用会提供 /building.jpg。请替换为自己的图片和替代文本,并将链接指向应用中的页面。

#从类追踪到 CSS

以卡片中的 p-lg 为例。预设将 p- 关联到内边距,将 lg 关联到间距令牌 --spacing-lg。Master 会生成一个类选择器,其声明引用这个 CSS 变量。

类选择样式,令牌提供值

对应的名称将各个部分连接起来:p-lg 选中规则,var(--spacing-lg) 读取共用值。图中仅展示相关声明;下方的完整输出还包含所属的层。

文字说明
  1. 类匹配. HTML 中的 p-lg 类匹配生成的 .p-lg 选择器。蓝色括号与连线将这两处对应起来。
  2. 共用值. 预设将 --spacing-lg 定义为 1.5rem。紫色括号与连线将这一定义连接到 padding: var(--spacing-lg) 中的引用。
  3. 浏览器结果. 浏览器解析 CSS 变量后,在四边应用 1.5rem 内边距。生成的规则保留变量引用,而不会将值复制进声明。
生成的 CSS
@layer theme {  :root,  :host {    --spacing-lg: 1.5rem  }}@layer utilities {  .p-lg {    padding: var(--spacing-lg)  }}

浏览器会对匹配的元素应用 padding: var(--spacing-lg)。按照预设值,四边的内边距都是 1.5rem。即使在主题中修改共用值,也无需改变类名。

其他类表达的是不同类型的设置:w-full 是对应 width: 100% 的固定工具类,bg-blue-70:hover 则添加悬停状态。语法教程会通过可运行的示例,介绍值、选择器和条件。

#定义哪些部分应该一起改变

当多个元素需要共享某项项目设置时,就添加一个主题令牌。以主要操作的颜色为例,在应用样式表的导入语句之后定义 --color-brand,再在标记中使用 bg-brand:

@theme {  --color-brand: #2563eb;}
<a class="inline-flex px-md py-xs r-md bg-brand fg-white" href="/guide/installation">Start building</a>
生成的 CSS
@layer theme {  :root,  :host {    --color-white: oklch(100% 0 none)  }  :root,  :host {    --radius-md: .375rem;    --spacing-xs: .5rem;    --spacing-md: 1rem  }  :root,  :host {    --color-brand: #2563eb  }}@layer utilities {  .bg-brand {    background-color: var(--color-brand)  }  .r-md {    border-radius: var(--radius-md)  }  .fg-white {    color: var(--color-white)  }  .inline-flex {    display: inline-flex  }  .py-xs {    padding-block: var(--spacing-xs)  }  .px-md {    padding-inline: var(--spacing-md)  }}

修改 --color-brand,使用它的元素就会一起更新。共享令牌的理由,应该是这些元素需要一起改变;两个互不相关的颜色,即使当前值相同,也不必共用一个名称。主题令牌会说明如何定义和覆盖共用值。

多个元素需要共享样式规则时,可以使用 .action 这样的组件类;需要共享标记时,则使用 UI 组件。类列表很长,本身并不意味着需要再创建一个 CSS 名称。复用样式会帮助你判断何时适合使用共用令牌、组件类或自定义工具类。

交付方式改变,类词汇保持不变

语法表达请求的样式;渲染模式则决定何时、在哪里生成对应的 CSS。

文字说明

同一个类及其声明在图中分为两条交付路径:构建时生成的样式表,以及浏览器生成的样式表。

#从静态 CSS 开始

使用框架推荐的静态集成方式。它会在构建时从源文件中查找完整类名,交付普通 CSS,无需在浏览器中加载 Master 运行时或引擎。

交互界面仍可正常工作:切换已知的类,使用 :hover 等选择器,或通过 CSS 自定义属性更新进度、坐标等值。当演练场、可视化编辑器或已部署的内容引入先前未知的类名时,运行时就能发挥作用。渲染模式会说明各种交付方式。

按照安装指南将 Master CSS 接入应用,再跟随语法教程,构建具有交互状态和响应式条件的卡片。如需编写时的补全与诊断,请配置语言服务。