mcpField
M
material-design-3-layout

material-design-3-layout

github.com/shelbeely设计与 UI537 次安装36 周前更新
代码仓库

关于 material-design-3-layout

material-design-3-layout 是面向界面开发者的技能,指导实现 Material Design 3 的布局与尺寸层级。它涵盖间距、响应式网格、层次、容器和交互状态等设计规则。

主要功能

  1. 014dp 间距刻度与语义令牌
  2. 02响应式断点和网格列数
  3. 03组件尺寸与视觉层级
  4. 04海拔、模糊和表面分层
  5. 05触控目标与焦点指示规范

适用场景

  1. 01规划适配不同屏幕的页面网格
  2. 02统一组件间距和尺寸层级
  3. 03为弹窗与浮层设置深度关系
  4. 04检查交互控件的触控和焦点状态

安装

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

$npx skills add https://github.com/shelbeely/shelbeely-agent-skills --skill material-design-3-layout

安装后在 Claude Code 中输入/material-design-3-layout确认已加载。

详细介绍

Material Design 3 布局与尺寸层级

概述

本技能介绍如何运用 Material Design 3(M3)Expressive 的布局与间距原则,打造清晰、有序且响应迅速的界面。

关键词:Material Design 3、M3、布局、间距、网格、响应式设计、断点、尺寸层级、高程、内边距、外边距

核心原则

布局理念

从 Material You 基础到 M3 Expressive,M3 布局注重:

  1. 清晰的层级:通过尺寸和间距体现视觉重要性
  2. 响应式适配:布局适用于各种屏幕尺寸
  3. 策略性间距:一致的间距营造节奏感与流畅感
  4. 基于尺寸的强调:较大的元素自然会吸引注意力
  5. 高程深度:分层表面展现元素间的关系
  6. 显式与隐式包含:通过边框和相邻关系实现视觉分组
  7. 背景模糊与分层:引导视觉焦点的深度效果(M3 Expressive)

间距比例系统

M3 对所有布局间距使用一致的 4dp 间距比例:

基础比例(以 4dp 为增量)
:root {
  /* Spacing scale */
  --md-sys-spacing-0: 0px;
  --md-sys-spacing-1: 4px;
  --md-sys-spacing-2: 8px;
  --md-sys-spacing-3: 12px;
  --md-sys-spacing-4: 16px;
  --md-sys-spacing-5: 20px;
  --md-sys-spacing-6: 24px;
  --md-sys-spacing-7: 28px;
  --md-sys-spacing-8: 32px;
  --md-sys-spacing-9: 36px;
  --md-sys-spacing-10: 40px;
  --md-sys-spacing-12: 48px;
  --md-sys-spacing-14: 56px;
  --md-sys-spacing-16: 64px;
  --md-sys-spacing-20: 80px;
  --md-sys-spacing-24: 96px;
}
语义化间距

为常见模式定义语义化间距:

:root {
  /* Component spacing */
  --md-sys-spacing-component-gap: var(--md-sys-spacing-2); /* 8px */
  --md-sys-spacing-component-padding: var(--md-sys-spacing-4); /* 16px */
  
  /* Layout spacing */
  --md-sys-spacing-section-gap: var(--md-sys-spacing-6); /* 24px */
  --md-sys-spacing-page-margin: var(--md-sys-spacing-4); /* 16px */
  
  /* List spacing */
  --md-sys-spacing-list-item-gap: var(--md-sys-spacing-2); /* 8px */
  --md-sys-spacing-list-padding: var(--md-sys-spacing-4); /* 16px */
}

响应式网格系统

断点

M3 为响应式设计定义了标准断点:

:root {
  /* Breakpoints */
  --md-sys-breakpoint-xs: 0px;      /* Extra small (phones) */
  --md-sys-breakpoint-sm: 600px;    /* Small (tablets portrait) */
  --md-sys-breakpoint-md: 905px;    /* Medium (tablets landscape) */
  --md-sys-breakpoint-lg: 1240px;   /* Large (laptops) */
  --md-sys-breakpoint-xl: 1440px;   /* Extra large (desktops) */
}
网格列

手机(0-599px):

  • 列数:4
  • 边距:16px
  • 槽距:16px

平板(600-904px):

  • 列数:8
  • 边距:24px
  • 槽距:24px

桌面(905px+):

  • 列数:12
  • 边距:24px
  • 槽距:24px
CSS 网格实现
.layout-grid {
  display: grid;
  gap: var(--md-sys-spacing-4);
  padding: var(--md-sys-spacing-4);
  
  /* Mobile: 4 columns */
  grid-template-columns: repeat(4, 1fr);
}

@media (min-width: 600px) {
  .layout-grid {
    gap: var(--md-sys-spacing-6);
    padding: var(--md-sys-spacing-6);
    /* Tablet: 8 columns */
    grid-template-columns: repeat(8, 1fr);
  }
}

@media (min-width: 905px) {
  .layout-grid {
    /* Desktop: 12 columns */
    grid-template-columns: repeat(12, 1fr);
  }
}

组件间距

按钮

内边距:

  • 水平:24px
  • 垂直:10px
  • 最小高度:40px
  • 图标与文本间距:8px
.button {
  padding: var(--md-sys-spacing-2) var(--md-sys-spacing-6);
  min-height: 40px;
  gap: var(--md-sys-spacing-2);
}
卡片

内边距:

  • 标准:四边均为 16px
  • 大卡片:四边均为 24px
  • 紧凑:四边均为 12px

元素间距:

  • 标题到内容:8px
  • 内容到操作项:16px
  • 操作项之间:8px
.card {
  padding: var(--md-sys-spacing-4);
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-spacing-2);
}

.card-actions {
  margin-top: var(--md-sys-spacing-4);
  display: flex;
  gap: var(--md-sys-spacing-2);
}
对话框

内边距:

  • 四边:24px
  • 内容内边距:16px
  • 标题到内容:16px
  • 内容到操作项:24px

尺寸:

  • 最小宽度:280px
  • 最大宽度:560px
  • 手机:全宽并保留边距
.dialog {
  padding: var(--md-sys-spacing-6);
  min-width: 280px;
  max-width: 560px;
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-spacing-4);
}

@media (max-width: 599px) {
  .dialog {
    width: calc(100% - 32px);
    margin: var(--md-sys-spacing-4);
  }
}
列表

间距:

  • 列表项之间:0px(各项相接)
  • 列表项内边距:水平 16px,垂直 8px
  • 图标到文本:16px
  • 文本到次要操作项:16px
.list-item {
  padding: var(--md-sys-spacing-2) var(--md-sys-spacing-4);
  display: flex;
  align-items: center;
  gap: var(--md-sys-spacing-4);
  min-height: 56px;
}
导航

应用栏:

  • 高度:64px(桌面)、56px(手机)
  • 内边距:水平 16px
  • 项目间距:24px

导航栏:

  • 宽度:80px
  • 项目高度:56px
  • 项目间距:4px

底部导航:

  • 高度:80px
  • 项目宽度:平均分配
  • 图标到标签:4px
.app-bar {
  height: 56px;
  padding: 0 var(--md-sys-spacing-4);
  display: flex;
  align-items: center;
  gap: var(--md-sys-spacing-6);
}

@media (min-width: 600px) {
  .app-bar {
    height: 64px;
  }
}

尺寸层级

使用尺寸进行强调

M3 Expressive 会策略性地使用尺寸来建立视觉层级:

主视觉元素(最大):

  • 比标准尺寸大 2-3 倍
  • 用于主要行动号召或精选内容
  • 每个视图限 1-2 个

主要元素(较大):

  • 比标准尺寸大 1.5 倍
  • 主要内容、精选项目
  • 每个视图 3-5 个

标准元素(基础):

  • 大多数内容的默认尺寸
  • 保持可读性与易用性

次要元素(较小):

  • 标准尺寸的 0.75 倍
  • 辅助信息、元数据
  • 数量可以较多

三级元素(最小):

  • 标准尺寸的 0.5 倍
  • 时间戳、说明文字、细则
  • 谨慎使用
尺寸示例
/* Hero button */
.button-hero {
  padding: var(--md-sys-spacing-4) var(--md-sys-spacing-10);
  min-height: 56px;
  font-size: 18px;
}

/* Standard button */
.button-standard {
  padding: var(--md-sys-spacing-2) var(--md-sys-spacing-6);
  min-height: 40px;
  font-size: 14px;
}

/* Small button */
.button-small {
  padding: var(--md-sys-spacing-1) var(--md-sys-spacing-4);
  min-height: 32px;
  font-size: 12px;
}

高程系统

M3 使用高程来体现深度和层级:

海拔层级

Level 0(位于表面):

  • 无阴影
  • 背景元素

Level 1(轻微抬升):

  • 阴影:0 1px 2px rgba(0,0,0,0.3), 0 1px 3px rgba(0,0,0,0.15)
  • 卡片、列表项
  • 使用:1dp

Level 2(抬升):

  • 阴影:0 2px 4px rgba(0,0,0,0.3), 0 3px 4px rgba(0,0,0,0.15)
  • 突起按钮、静止状态的 FAB
  • 使用:3dp

Level 3(悬浮):

  • 阴影:0 4px 8px rgba(0,0,0,0.3), 0 6px 8px rgba(0,0,0,0.15)
  • 悬停状态的 FAB、应用栏
  • 使用:6dp

Level 4(模态):

  • 阴影:0 8px 12px rgba(0,0,0,0.3), 0 12px 16px rgba(0,0,0,0.15)
  • 对话框、导航抽屉
  • 使用:8dp

Level 5(高模态):

  • 阴影:0 12px 16px rgba(0,0,0,0.3), 0 16px 24px rgba(0,0,0,0.15)
  • 模态底部表单
  • 使用:12dp
海拔令牌
:root {
  --md-sys-elevation-0: none;
  --md-sys-elevation-1: 0 1px 2px rgba(0,0,0,0.3), 0 1px 3px rgba(0,0,0,0.15);
  --md-sys-elevation-2: 0 2px 4px rgba(0,0,0,0.3), 0 3px 4px rgba(0,0,0,0.15);
  --md-sys-elevation-3: 0 4px 8px rgba(0,0,0,0.3), 0 6px 8px rgba(0,0,0,0.15);
  --md-sys-elevation-4: 0 8px 12px rgba(0,0,0,0.3), 0 12px 16px rgba(0,0,0,0.15);
  --md-sys-elevation-5: 0 12px 16px rgba(0,0,0,0.3), 0 16px 24px rgba(0,0,0,0.15);
}
带色调的海拔效果

M3 会为抬升的表面添加细微的颜色色调:

.elevated-surface {
  background-color: var(--md-sys-color-surface);
  box-shadow: var(--md-sys-elevation-1);
  /* Add subtle tint using primary color */
  background-image: linear-gradient(
    rgba(var(--md-sys-color-primary-rgb), 0.05),
    rgba(var(--md-sys-color-primary-rgb), 0.05)
  );
}

响应式布局模式

移动优先方法

从移动端布局开始,然后针对更大的屏幕进行增强:

/* Mobile: Stack vertically */
.content-layout {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-spacing-4);
  padding: var(--md-sys-spacing-4);
}

/* Tablet: Two columns */
@media (min-width: 600px) {
  .content-layout {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--md-sys-spacing-6);
    padding: var(--md-sys-spacing-6);
  }
}

/* Desktop: Three columns with sidebar */
@media (min-width: 905px) {
  .content-layout {
    grid-template-columns: 250px 1fr 1fr;
  }
}
容器查询

用于组件级响应式设计:

.card-container {
  container-type: inline-size;
}

.card {
  display: flex;
  flex-direction: column;
}

@container (min-width: 400px) {
  .card {
    flex-direction: row;
    gap: var(--md-sys-spacing-4);
  }
}
常见布局模式

内容居中:

.centered-layout {
  max-width: 1200px;
  margin: 0 auto;
  padding: var(--md-sys-spacing-6);
}

侧边栏布局:

.sidebar-layout {
  display: grid;
  grid-template-columns: 250px 1fr;
  gap: var(--md-sys-spacing-6);
}

@media (max-width: 904px) {
  .sidebar-layout {
    grid-template-columns: 1fr;
  }
}

仪表盘网格:

.dashboard-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--md-sys-spacing-4);
}

包含原则

显式包含

使用可见边界将相关内容分组:

/* Card containment with outline */
.contained-group {
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-medium);
  padding: var(--md-sys-spacing-4);
  background: var(--md-sys-color-surface-container);
}

/* Elevated containment */
.elevated-group {
  box-shadow: var(--md-sys-elevation-1);
  border-radius: var(--md-sys-shape-corner-medium);
  padding: var(--md-sys-spacing-4);
  background: var(--md-sys-color-surface-container-low);
}
隐式包含

使用邻近关系、留白和对齐来对项目分组,无需可见边框:

/* Implicit grouping through proximity */
.implicit-group {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-spacing-1); /* Tight spacing implies grouping */
}

/* Separated groups use larger spacing */
.section-gap {
  margin-bottom: var(--md-sys-spacing-8); /* Larger gap separates groups */
}
何时使用各类型
包含类型使用场景
显式(边框/卡片)交互内容、不同的区块、可操作的分组
显式(海拔)需要呈现“抬升”或模态效果的内容
隐式(邻近关系)相关文本块、标签-值对、顺序内容
隐式(对齐)网格布局、导航项、一致的结构

背景模糊和深度效果

M3 Expressive 引入背景模糊和分层效果,以提升深度感和聚焦效果:

背景模糊

在覆盖层、模态窗口和导航元素后方策略性地使用模糊效果:

/* Blur behind modal dialogs */
.dialog-backdrop {
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  background-color: rgba(0, 0, 0, 0.32);
}

/* Blur behind floating toolbars */
.floating-toolbar {
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  background-color: rgba(var(--md-sys-color-surface-rgb), 0.85);
}

/* Blur behind navigation drawers */
.nav-drawer-scrim {
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  background-color: var(--md-sys-color-scrim);
  opacity: 0.32;
}
何时使用模糊效果
  1. 模态窗口和对话框后方:将注意力集中在前景内容上
  2. 悬浮工具栏后方:将工具栏与内容分隔开,而不使用强烈的海拔效果
  3. 导航抽屉后方:柔化抽屉与内容之间的过渡
  4. 底部表单后方:营造深度感,同时不完全遮挡内容
  5. 不要用于内容本身:模糊效果用于遮罩层和背景,而非可读内容
深度分层

结合海拔、模糊和表面色调,形成清晰的分层效果:

/* Layer 1: Base content */
.base-layer {
  background: var(--md-sys-color-surface);
}

/* Layer 2: Elevated content */
.elevated-layer {
  background: var(--md-sys-color-surface-container);
  box-shadow: var(--md-sys-elevation-1);
}

/* Layer 3: Overlay with blur */
.overlay-layer {
  backdrop-filter: blur(16px);
  background: rgba(var(--md-sys-color-surface-container-high-rgb), 0.9);
  box-shadow: var(--md-sys-elevation-3);
}

交互状态

M3 为所有交互元素定义了一致的交互状态:

状态层系统

状态层是使用特定不透明度的内容颜色创建的覆盖层:

状态不透明度描述
启用0%默认状态,无覆盖层
悬停8%指针设备悬停
聚焦12%键盘/无障碍焦点
按下12%触摸/点击按下
拖动16%正在进行拖动操作
禁用0%不可交互(内容不透明度为 38%,背景不透明度为 12%)
/* State layer implementation */
.interactive-element {
  position: relative;
}

.interactive-element::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--md-sys-color-on-surface);
  opacity: 0;
  transition: opacity 200ms var(--md-sys-motion-easing-standard);
  pointer-events: none;
}

.interactive-element:hover::before { opacity: 0.08; }
.interactive-element:focus-visible::before { opacity: 0.12; }
.interactive-element:active::before { opacity: 0.12; }

/* Disabled state */
.interactive-element:disabled {
  opacity: 0.38;
  pointer-events: none;
}

.interactive-element:disabled::before {
  opacity: 0;
}
状态优先级

一次只应用一个可见状态层。优先级顺序:

  1. 拖动(最高)
  2. 按下
  3. 聚焦
  4. 悬停
  5. 启用(最低)

触控目标和无障碍

最小触控目标尺寸

所有交互元素的尺寸必须至少为 48×48dp:

.touch-target {
  min-width: 48px;
  min-height: 48px;
  /* Visual size can be smaller with padding */
  padding: var(--md-sys-spacing-3);
}
焦点指示器

确保焦点环周围有足够的间距:

.focusable {
  position: relative;
}

.focusable:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

最佳实践

建议做法
  1. ✅ 始终使用 4dp 间距比例
  2. ✅ 为常见模式定义语义化间距令牌
  3. ✅ 从移动优先开始,然后针对更大的屏幕进行增强
  4. ✅ 使用尺寸层级营造视觉强调
  5. ✅ 保持触控目标至少为 48×48dp
  6. ✅ 使用海拔效果展示组件之间的关系
  7. ✅ 在所有断点下测试布局
  8. ✅ 使用 CSS Grid 和 Flexbox 构建现代布局
不要做
  1. ❌ 不要使用随意的间距值(请遵循比例)
  2. ❌ 不要设计仅适用于桌面端的布局
  3. ❌ 不要在移动设备上使用过小的触控目标
  4. ❌ 不要过度使用立体效果(会造成视觉干扰)
  5. ❌ 不要忽略组件的容器查询
  6. ❌ 不要创建没有最大宽度限制的固定宽度布局
  7. ❌ 不要忘记移动设备上的水平滚动

性能注意事项

  1. 使用 CSS Grid/Flexbox:避免基于 float 的布局
  2. 尽量减少布局偏移:定义尺寸以防止 CLS
  3. 优化图片:使用带有 srcset 的响应式图片
  4. 延迟加载:延后加载屏幕外的内容
  5. 容器查询:对组件而言比媒体查询更好

布局实现检查清单

实现 M3 布局时,请确保:

  • 已定义间距比例(以 4dp 为增量)
  • 已创建语义化间距令牌
  • 已定义断点(600px、905px、1240px)
  • 采用移动优先的响应式设计方法
  • 网格系统支持 4/8/12 列
  • 触控目标至少为 48×48dp
  • 已定义立体效果系统(5 个级别)
  • 使用尺寸层级突出重点
  • 所有间距均使用令牌(不使用硬编码值)
  • 布局适用于所有屏幕尺寸
  • 焦点指示器周围留有足够间距
  • 对组件使用容器查询
  • 设置最大内容宽度以提高可读性
  • 对凸起表面应用立体色调
  • 应用内聚原则(显式和隐式分组)
  • 对模态框、抽屉和浮动元素使用背景模糊
  • 使用正确的不透明度值实现交互状态
  • 禁用状态使用 38% 的内容不透明度和 12% 的背景不透明度
  • 状态层以适当的不透明度使用表面上方颜色
  • 优化性能(Grid/Flexbox、延迟加载)

资源

评论

支持 Markdown