mcpField
M
modern-css

modern-css

github.com/moderncss设计与 UI5176 次安装3 周前更新
代码仓库

关于 modern-css

modern-css 是面向 Agent 和开发者的 CSS 编写技能,为现代 CSS 制定一致规则。它补充 Modern Web Guidance,明确具体样式选择,并涵盖 stylelint-config-modern 无法强制执行的规则。

主要功能

  1. 01CSS 层与作用域样式规则
  2. 02嵌套与范围查询约定
  3. 03流向相对布局与流式尺寸
  4. 04排版与颜色系统指导
  5. 05动态效果偏好约定
  6. 06CSS 审查与重构流程

适用场景

  1. 01为新组件编写 CSS
  2. 02按统一规则重构现有样式
  3. 03检查 CSS 是否采用现代模式

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/moderncss/skills --skill modern-css

安装后在 Claude Code 中输入/modern-css确认已加载。

详细介绍

现代 CSS

现代 CSS 的约定规则,让 Agent 和开发者以一致的方式编写样式。

这些规则基于 Modern Web Guidance 技能,该技能必须先安装。它会说明每项特性的作用、适用场景以及回退方式,但不会限定具体选择:使用哪种颜色空间、是否进行作用域限定、何时嵌套、如何设置字号。这些规则会明确这些选择;其他内容请查阅该技能的指南。两者意见不一致时,以本规则为准。

stylelint-config-modern 包会强制执行所有可由代码检查器强制执行的规则。此技能让 Agent 从一开始就遵循这些规则编写代码,并涵盖其余规则。

浏览器支持策略:对于属于 Baseline「新近可用」范围内的特性,直接使用,不添加 @supports 回退,作为渐进增强。

规则

架构
组织样式(@layer)
  • 规则:将每条样式规则都放在 @layer 中。
  • 限制:避免未分层的元素默认样式和重置样式。
  • 理由:未分层的规则优先级高于所有层;将所有规则分层后,仅由层顺序决定冲突的处理方式。
  • 参考:MDN 上的 @layer。
  • 示例:
@layer elements, components;

@layer elements {
  a {
    text-decoration-skip-ink: auto;
  }
}
封装样式(@scope)
  • 规则:每个组件的样式都使用 @scope;如果组件承载了不归它所有的内容,则使用作用域上限(@scope (outer) to (inner)),例如嵌入式组件、插槽内容或用户内容。
  • 限制:避免在作用域之外编写组件样式,也避免对组件不拥有的内容使用无限范围的作用域。
  • 理由:作用域选择器不会渗入其他组件;上限可阻止外层作用域的样式影响投影内容。这种方式有时称为甜甜圈式作用域限定。
  • 参考:MDN 上的 @scope。
  • 示例:
@scope (.card) to (.content) {
  h2 {
    font-size: var(--large);
  }
}
嵌套规则和 at 规则(&)
  • 规则:将规则和 at 规则嵌套在父规则中;当嵌套选择器附加到父选择器时,写出 &(&:hover);对于组合符则省略它(写 b,而不是 & b)。
  • 限制:避免未嵌套的选择器(例如 a {} a:hover {})。
  • 理由:让规则的状态和查询与规则本身放在同一个代码块中;stylelint-config-modern 会强制使用隐式 & 形式。
  • 参考:MDN 上的 & 嵌套选择器。
  • 示例:
a {
  color: var(--blue);

  &:hover {
    text-decoration: underline;
  }

  code {
    font-variant-numeric: tabular-nums;
  }
}
范围查询(20em < width <= 40em)
  • 规则:尺寸查询使用范围语法(例如 @container (20em < width <= 40em)),并确保范围不重叠。
  • 限制:避免使用 min-width/max-width 和重叠范围(例如同时使用 width <= 20em 和 width >= 20em,两者都会在 20em 时匹配)。
  • 理由:每种尺寸只会落入一个条件,因此无需让任何条件覆盖其他条件。
  • 参考:MDN 上的媒体查询范围语法。
  • 示例:
.card {
  @container (width <= 20em) {
    grid-template-columns: 1fr;
  }

  @container (20em < width <= 40em) {
    grid-template-columns: 1fr 1fr;
  }

  @container (width > 40em) {
    grid-template-columns: repeat(3, 1fr);
  }
}
布局
相对流向的布局(*-inline-*、*-block-*、cqi/vi、start/end)
  • 规则:布局使用相对流向的属性(例如 padding-block-start、inset-inline、inline-size)、单位(例如 cqi、cqb、vi)和关键字(例如 text-align: start)。
  • 限制:避免使用对应的物理属性(例如 padding-top、width、cqw、vw、text-align: left),即使布局永远不会翻转也不例外。
  • 理由:让盒模型与 flexbox 和 grid 已使用的轴保持一致;stylelint-config-modern 会强制执行此规则。
  • 参考:MDN 上的逻辑属性和值。
  • 示例:
.card {
  max-inline-size: 60ch;
  padding-block-start: 2cqi;
  text-align: start;
}
双值显示(display: block flex)
  • 规则:使用双值 display 语法(例如 display: block flex、display: inline grid)。
  • 限制:避免使用单值关键字(例如 display: block、display: flex、display: inline-block)。
  • 理由:将盒子在父级中的排列方式与其子元素的布局方式区分开来,因此 inline flex 和 inline flow-root 可替代特殊关键字 inline-flex 和 inline-block。
  • 参考资料:MDN 上的多关键字 display 语法。
  • 示例:
nav {
  display: block flex;
}

.card {
  display: block grid;
}
流式间距(cqi)
  • 规则:使用容器单位设置间距大小(例如 padding: 2cqi),并在需要设置下限或上限时使用钳制。
  • 限制:避免固定间距(例如 padding-block: 16px、margin-inline: 1rem)。
  • 理由:间距会随容器缩放,因此组件无论放置在哪里都能灵活适配,不会留下断点造成的接缝。
  • 参考资料:MDN 上的容器查询长度单位、响应式设计:接缝与边缘。。
  • 示例:
.card {
  container: card / inline-size;
  gap: 2cqi;
  padding: clamp(1rem, 0.5rem + 2cqi, 2rem);
}
自动增长的文本区域(field-sizing: content)
  • 规则:在文本区域上使用 field-sizing: content,并用 lh 明确指定 inline-size 和 min-block-size/max-block-size。
  • 限制:避免固定块大小(例如 block-size: 8rem),也不要在输入框上使用 field-sizing: content,因为输入框会缩至内容值的宽度。
  • 理由:输入的文本会持续显示,而不是在固定大小的框内滚动;lh 限制会随字号缩放时的行高变化。
  • 参考资料:MDN 上的 field-sizing。
  • 示例:
textarea {
  field-sizing: content;
  inline-size: 100%;
  max-block-size: 12lh;
  min-block-size: 3lh;
}
排版
流式字号(clamp())
  • 规则:使用带容器单位的 clamp() 设置字号,并采用字号比例随容器增大的字号阶梯,例如窄容器使用 Major Second(1.125),宽容器使用 Major Third(1.25)。
  • 限制:避免固定字号(例如 px、rem),以及不含 rem 项的中间值(例如 clamp(1.75rem, 5cqi, 2.25rem))。
  • 理由:字号会根据容器而非断点调整,且 rem 项可确保缩放功能正常。
  • 参考资料:MDN 上的 clamp()、使用流式字号阶梯进行设计。
  • 示例:
:root {
  --medium: clamp(1.3125rem, 1.1821rem + 0.6522cqi, 1.6875rem);
  --large: clamp(1.75rem, 1.5761rem + 0.8696cqi, 2.25rem);
}
孤行与寡行(text-wrap)
  • 规则:在标题上使用 text-wrap: balance,在所有其他文本上使用 text-wrap: pretty。
  • 限制:避免在输入框和文本区域之外使用默认换行。
  • 理由:默认消除孤行与寡行,而不是只在有人记得选择启用时才处理。
  • 参考资料:MDN 上的 text-wrap。
  • 示例:
h1,
h2,
h3 {
  text-wrap: balance;
}

body {
  text-wrap: pretty;
}
颜色
感知均匀的亮度(oklch())
  • 规则:所有颜色都使用 oklch()。
  • 限制:避免使用 hex、rgb()、hsl() 和其他颜色格式。
  • 理由:亮度在感知上均匀,因此文本对比度在不同色相下都能保持一致。
  • 参考资料:MDN 上的 oklch()。
  • 示例:
:root {
  --success: oklch(40% 0.15 150deg);
  --danger: oklch(40% 0.2 25deg);
}
遵循颜色偏好(light-dark())
  • 规则:对于所有在浅色和深色方案之间不同的颜色,都使用 light-dark()。
  • 限制:避免使用会重新声明颜色的 prefers-color-scheme 块,以及不会自适应的颜色。
  • 理由:每个令牌都在同一处包含两种颜色值,因此颜色变化时不会遗漏任何配色方案。
  • 参考资料:MDN 上的 light-dark()。
  • 示例:
:root {
  --surface: light-dark(oklch(98% 0 0deg), oklch(16% 0 0deg));
  --text: light-dark(oklch(35% 0 0deg), oklch(75% 0 0deg));
}
相对颜色函数(oklch(from /* .. */) 与 color-mix())
  • 规则:使用相对颜色语法(例如 oklch(from var(--primary) l c calc(h - 10deg)))或在 oklab 中使用 color-mix(),派生相关颜色。
  • 限制:避免硬编码与其他颜色相关的颜色,以及仅调整高饱和颜色的亮度(例如 oklch(from var(--primary) 90% c h))。
  • 原因:源颜色变化时,相关颜色会随之变化。
  • 参考资料:MDN 上的相对颜色、MDN 上的 color-mix()。
  • 示例:
:root {
  --primary: oklch(55% 0.25 350deg);
  --primary-hover: oklch(from var(--primary) l c calc(h - 10deg));
  --primary-tint: color-mix(in oklab, var(--primary), oklch(100% 0 0deg) 80%);
}
动效
尊重动效偏好(prefers-reduced-motion)
  • 规则:应用大型动画和过渡效果时,使用 prefers-reduced-motion: no-preference。
  • 限制:避免使用 prefers-reduced-motion: reduce。
  • 原因:动效会变为主动选择启用,因此无需为动画设置减少动效的覆盖规则。使用 reduce 时,每个动画都需要设置覆盖规则,很容易遗漏。
  • 参考资料:MDN 上的 prefers-reduced-motion。
  • 示例:
@media (prefers-reduced-motion: no-preference) {
  .hero {
    animation: bounce-in 0.5s ease;
  }
}

应用这些规则

在编写、重构或审查 CSS 时:

  1. 确定哪些规则适用于当前任务;如果有多条适用规则,就全部应用。
  2. 阅读周边文件,了解已经在使用哪些规则;遵循现有模式。
  3. 在整个更改集中一致地应用规则,而不只是应用于改动点。
  4. 获取适用于当前任务的 Modern Web Guidance 指南,并在这些规则范围内应用;根据上文的浏览器支持策略,跳过其中的回退方案。
  5. 如果项目使用 Stylelint 和 stylelint-config-modern,在完成前对已更改的文件运行 Stylelint,并修复其报告的问题。

注意事项

以下问题既未在上述规则中提及,也未在 Modern Web Guidance 中说明:

  • **clamp() 的中心值需要包含 rem 项:**使用 clamp(1.75rem, 1.5761rem + 0.8696cqi, 2.25rem),不要使用 Modern Web Guidance 的 fluid-scaling 指南所示的 clamp(1rem, 5cqi, 2.5rem) 形式。
  • **grid-template-rows: subgrid 只会继承子元素声明使用的网格轨道。**应配合 grid-row: span N 使用;没有跨度时,子元素只会占一行,无法与任何内容对齐。Modern Web Guidance 的 css-layout 指南展示了跨度写法,但没有说明原因。
  • **container-type 已经会应用包含约束:**使用 container-type: inline-size 的组件具有布局、样式和行内尺寸包含约束,因此不需要 contain。Modern Web Guidance 的 performance 指南为小组件设置的 contain: layout style paint 会额外应用绘制包含约束,导致溢出的后代元素被裁剪,效果类似 overflow: clip。

示例

本站遵循这些规则:

仅当项目没有可供匹配的自有 CSS 时,才获取其中一个文件。

评论

支持 Markdown