material-design-3-layout について
material-design-3-layoutは、Material Design 3のレイアウトとサイズ階層を適用する開発者向けスキルです。スペーシング、レスポンシブグリッド、奥行き、グルーピング、インタラクション状態を扱います。
主な機能
- 014dpスペーシング尺度と意味的トークン
- 02レスポンシブなブレークポイントとグリッド列
- 03コンポーネントのサイズと視覚的階層
- 04エレベーション、ぼかし、サーフェスの重なり
- 05タッチ領域とフォーカスの指針
活用シーン
- 01画面サイズに応じたページグリッドの設計
- 02コンポーネントの余白とサイズ階層の統一
- 03ダイアログやフローティングレイヤーの奥行き設計
- 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 のレイアウトでは次の点を重視します。
- 明確な階層:サイズと間隔によって視覚的な重要度を表します
- レスポンシブな適応性:あらゆる画面サイズで機能するレイアウトにします
- 意図的な間隔:一貫した間隔によってリズムと流れを作ります
- サイズによる強調:大きな要素ほど自然に目を引きます
- エレベーションによる奥行き:レイヤー化されたサーフェスで関係性を示します
- 明示的および暗黙的な包含:境界線と近接性の両方で視覚的にグループ化します
- 背景のぼかしとレイヤー化:焦点を導く奥行き効果(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 つのビューにつき 1~2 個に限定します
主要要素(大):
- 標準の 1.5 倍の大きさ
- メインコンテンツや注目アイテムに使用します
- 1 つのビューにつき 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 では、奥行きと階層を示すためにエレベーションを使用します。
エレベーションレベル
レベル 0(表面上):
- シャドウなし
- 背景要素
レベル 1(わずかなエレベーション):
- シャドウ:
0 1px 2px rgba(0,0,0,0.3), 0 1px 3px rgba(0,0,0,0.15) - カード、リスト項目
- 使用:1dp
レベル 2(エレベーション):
- シャドウ:
0 2px 4px rgba(0,0,0,0.3), 0 3px 4px rgba(0,0,0,0.15) - 浮き上がったボタン、静止時の FAB
- 使用:3dp
レベル 3(フローティング):
- シャドウ:
0 4px 8px rgba(0,0,0,0.3), 0 6px 8px rgba(0,0,0,0.15) - ホバー時の FAB、アプリバー
- 使用:6dp
レベル 4(モーダル):
- シャドウ:
0 8px 12px rgba(0,0,0,0.3), 0 12px 16px rgba(0,0,0,0.15) - ダイアログ、ナビゲーションドロワー
- 使用:8dp
レベル 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;
}
ぼかしを使用する場面
- モーダルやダイアログの背後:前景のコンテンツにフォーカスを集めます
- フローティングツールバーの背後:強いエレベーションを使わずに、ツールバーをコンテンツから分離します
- ナビゲーションドロワーの背後:ドロワーとコンテンツの間の切り替わりを和らげます
- ボトムシートの背後:コンテンツを完全に隠さずに奥行きを生み出します
- コンテンツ自体には使わない:ぼかしはスクラムや背景に適用するもので、読み取り可能なコンテンツには適用しません
奥行きのレイヤー化
エレベーション、ぼかし、サーフェスのティントを組み合わせて、明確なレイヤーを作ります。
/* 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つだけです。優先順位は次のとおりです。
- ドラッグ(最優先)
- 押下
- フォーカス
- ホバー
- 有効(最下位)
タッチターゲットとアクセシビリティ
タッチターゲットの最小サイズ
すべてのインタラクティブ要素は、少なくとも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;
}
ベストプラクティス
推奨事項
- ✅ 4dpのスペーシングスケールを一貫して使用します
- ✅ 一般的なパターン向けに、セマンティックなスペーシングトークンを定義します
- ✅ モバイルファーストで始めて、大きな画面向けに拡張します
- ✅ サイズの階層を使って、視覚的な強調を作ります
- ✅ 48×48dp以上のタッチターゲットを維持します
- ✅ エレベーションを使って、コンポーネント間の関係を示します
- ✅ すべてのブレークポイントでレイアウトをテストします
- ✅ モダンなレイアウトにはCSS GridとFlexboxを使用します
避けること
- ❌ 任意の間隔値を使用しないでください(スケールに従ってください)
- ❌ デスクトップでしか機能しないレイアウトを作成しないでください
- ❌ モバイルで小さすぎるタッチターゲットを使用しないでください
- ❌ エレベーションを過剰に使用しないでください(視覚的なノイズが生じます)
- ❌ コンポーネントでコンテナクエリを無視しないでください
- ❌ 最大幅を設定せずに固定幅のレイアウトを作成しないでください
- ❌ モバイルでの横スクロールを忘れないでください
パフォーマンスに関する考慮事項
- CSS Grid/Flexboxを使用する:floatベースのレイアウトは避けてください
- レイアウトシフトを最小限に抑える:CLSを防ぐため、寸法を定義してください
- 画像を最適化する:srcsetを使用してレスポンシブ画像を指定してください
- 遅延読み込みを行う:画面外のコンテンツの読み込みを遅らせてください
- コンテナクエリ:コンポーネントではメディアクエリよりも適しています
レイアウト実装のチェックリスト
M3レイアウトを実装する際は、次の点を確認してください:
- 間隔のスケールが定義されている(4dp刻み)
- 意味的な間隔トークンが作成されている
- ブレークポイントが定義されている(600px、905px、1240px)
- モバイルファーストのレスポンシブなアプローチが使用されている
- グリッドシステムが4/8/12列に対応している
- タッチターゲットが最低48×48dpである
- エレベーションシステムが定義されている(5段階)
- 強調にはサイズ階層が使用されている
- すべての間隔にトークンが使用されている(ハードコードされた値がない)
- すべての画面サイズでレイアウトが機能する
- フォーカスインジケーターに適切な間隔がある
- コンポーネントにコンテナクエリが使用されている
- 読みやすさを確保するため、コンテンツの最大幅が設定されている
- 浮き上がった面にエレベーションの色付けが適用されている
- 内包の原則が適用されている(明示的および暗黙的なグループ化)
- モーダル、ドロワー、フローティング要素に背景のぼかしが使用されている
- 適切な不透明度の値でインタラクション状態が実装されている
- 無効状態では、コンテンツの不透明度に38%、背景の不透明度に12%が使用されている
- 適切な不透明度で、表面上の色を使った状態レイヤーが使用されている
- パフォーマンスが最適化されている(Grid/Flexbox、遅延読み込み)
リソース
- M3レイアウトの概要:https://m3.material.io/foundations/layout/understanding-layout/overview
- Material Designトークン:https://github.com/material-foundation/material-tokens