mcpField
U
ux-css-layout

ux-css-layout

github.com/microsoftデザイン・UI194.4k87 回インストール今日更新
リポジトリ

ux-css-layout について

VS Code の UI を実装・保守する開発者向けの CSS スキルです。スタイル規約、レイアウト部品、レスポンシブなサイズ調整、テキストのはみ出し処理を扱います。

主な機能

  1. 01CSS の配置と命名規則
  2. 02SplitView と Grid のレイアウト
  3. 03スクロール可能なコンテンツ
  4. 04制約ベースのレスポンシブ設計
  5. 05テキスト省略とホバー表示
  6. 06デザインシステムのサイズトークン

活用シーン

  1. 01コンポーネントのスタイルシート整理
  2. 02サイズ変更可能なペインとグリッドの構築
  3. 03リストやタブの狭いラベルへの対応

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/microsoft/vscode --skill ux-css-layout

インストール後、Claude Code で/ux-css-layoutを入力して読み込まれたか確認します。

詳細

このスキルでは、CSS ファイルの整理、命名、標準サイズ、プログラムによるレイアウト(SplitView、Grid、スクロール可能な要素)、レスポンシブパターン、テキストのオーバーフロー処理について説明します。


1. ファイルの整理

CSS ファイルは TypeScript コンポーネントと同じ場所に配置します。

src/vs/base/browser/ui/button/
    button.ts
    button.css
src/vs/workbench/contrib/myFeature/browser/
    myFeature.ts
    media/
        myFeature.css

TS ファイルで CSS を直接インポートします。

import './media/myFeature.css';
// or for base widgets:
import './button.css';

ワークベンチレベルのグローバルスタイルは src/vs/workbench/browser/media/ にあります。

2. クラスの命名

  • すべての主要コンポーネントには monaco- プレフィックスを付けます。.monaco-workbench、.monaco-split-view2、.monaco-scrollable-element
  • 修飾クラス:.monaco-split-view2.vertical、.monaco-split-view2.horizontal
  • 状態クラス:.visible、.focused、.active、.highlight
  • 機能固有のクラスには、プレフィックスを付けずにケバブケースを使用します。.my-feature、.outline-pane、.welcome-view-content

3. 標準サイズ

要素サイズ
パーツタイトルの高さ35px
タイトルのパディング(水平)8px
タイトルラベルの内側のパディング12px
アクション領域のパディング5px
アクションアイコンのサイズ16px
本文のフォントサイズ13px(ワークベンチ)、11px(HTML 本文)
行の高さ1.4em
検証メッセージのフォントサイズ12px(line-height: 17px)

padding/margin/gap、border-radius、font-size/font-weight、codicon のサイズ、ボーダー幅には、生の px 値よりもデザインシステムのサイズトークンを優先してください。§10 デザインシステムのサイズトークンを参照してください。標準の参照先:.github/instructions/design-tokens.instructions.md(src/vs/**/*.css に自動挿入されます)。

4. CSS セレクターの品質

アンチパターン(検出対象)正しいパターン
スタイル指定に ID セレクターを使う(#my-widget)クラスセレクターを使う(.my-widget)
過度に詳細なセレクター必要最小限の詳細度
不適切なファイルにスタイルを記述するコンポーネントと同じ場所に配置する
flex の子要素に min-width: 0 がない切り詰めの問題を防ぎます
非表示のオーバーレイに pointer-events: none を設定し忘れるクリックが透過する不具合を防ぎます
新たな !important の追加は禁止

新規または変更する CSS に !important を追加しないでください。宣言がカスケードで負ける場合は、競合するセレクターを調べ、コンポーネント、ワークベンチ、または状態クラスのプレフィックスを適切に最小限追加して、詳細度を上げてください。既存の !important 宣言はそのまま残してもかまいません。また、無関係な編集の際に機械的に削除してはいけません。コピーしたり、新たに追加したり、セレクターの所有関係を理解することを避けるために使ったりしないでください。

限定的な例外として、共有のフォーカス/アクティブアウトラインの抑制では、ネイティブまたはグローバルなフォーカスインジケーターを上書きし、ポインター操作中にアウトラインが点滅するのを防ぐため、意図的に outline: 0 !important を使用します。この例外はフォーカスインジケーターの動作に限定してください。機能のスタイルでは、引き続きセレクターの詳細度によってカスケードの競合を解決してください。

5. SplitView レイアウト

ファイル:src/vs/base/browser/ui/splitview/splitview.ts

ドラッグ可能なサッシでビューを分割する場合(水平または垂直):

const splitView = new SplitView(container, {
    orientation: Orientation.VERTICAL,
    proportionalLayout: true,
    styles: { separatorBorder: asCssVariable(sashBorder) }
});

// Each view implements IView:
const myView: IView = {
    element: myDomNode,
    minimumSize: 100,
    maximumSize: Number.POSITIVE_INFINITY,
    onDidChange: Event.None,
    layout(size, offset) { /* resize content */ }
};

splitView.addView(myView, Sizing.Distribute);

スペースが制約されたときにどのビューから先にサイズ変更するかを制御するには、LayoutPriority.High/.Low を使用します。ビューをスナップして閉じられるようにするには、snap: true を使用します。

6. Grid レイアウト

ファイル:src/vs/base/browser/ui/grid/grid.ts

2D レイアウト(エディターグループで使用)の場合:

const grid = new Grid(initialView);
grid.addView(newView, Sizing.Distribute, referenceView, Direction.Right);

7. スクロール可能なコンテンツ

用途に応じて、次の 3 つのクラスを使い分けます。

クラス使用する場面
SmoothScrollableElementアニメーション付きスクロール(SplitView、ListView)
DomScrollableElement既存の DOM コンテンツをラップする(ホバー、メニュー、パンくずリスト)
ScrollableElement基本的な単方向スクロールバー
const scrollable = new DomScrollableElement(contentNode, {
    horizontal: ScrollbarVisibility.Auto,
    vertical: ScrollbarVisibility.Auto
});
this._register(scrollable);
container.appendChild(scrollable.getDomNode());
scrollable.scanDomNode(); // call after content changes

8. レスポンシブレイアウト

VS Code では CSS メディアクエリを使用しません。代わりに、プログラムによる制約ベースのレイアウトシステムを使用します。

  • IView.minimumSize / maximumSize — ビューでサイズ制約を宣言します。
  • SplitView と Grid は、制約と LayoutPriority に応じて領域を分配します。
  • コンテナーに応じたサイズ調整(例:エディターの自動レイアウト)には、ResizeObserver を使用します。
  • ウィンドウは固定ビューポートとして扱い、領域はサッシュによるサイズ変更で分配されます。

レスポンシブコンポーネントを構築する場合:

  1. minimumSize / maximumSize を適切に設定します。
  2. 最初に折りたたむパネルには LayoutPriority.Low を使用します。
  3. 小さくなりすぎたときにパネルをスナップして閉じるには、snap: true を使用します。
  4. 制約が動的に変化したときは、onDidChange を発火させます。

9. テキストのオーバーフローと省略記号

サイズ変更可能なコンテナーによって切り詰められる可能性のあるテキストラベルには、必ず省略記号のパターンを使用する必要があります。省略記号なしでテキストがクリップされるのは、視覚的な不具合です。

標準的な省略記号のパターン(CSS)

次の3つのプロパティの組み合わせが必須です。3つすべてを指定する必要があります。

.my-label {
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}
省略記号が必要な一般的な箇所
要素理由
パートのタイトルラベル(h2、パンくずリスト)サイドバーやパネルは、タイトルより狭くなるようにサイズ変更できます
ビューペインのヘッダータイトルビューコンテナーは狭くなることがあります
リストやツリーの行ラベル行の幅はリストコンテナーによって固定されます
タブラベル(エディタータブ)多数のタブは、収まるように幅が縮小されます
ウェルカムビューのボタンラベルボタンには max-width の制約があります
ステータスバーの項目多数の項目が水平方向の領域を奪い合います
通知メッセージのテキスト通知トーストや通知センターの幅は固定されています
ツールチップやホバーの見出しホバーには最大幅があります
ドロップダウンや選択項目選択ボックスの幅には上限があります
バッジのテキストや説明制約のある列内の補助テキストです
Flexコンテナーで注意すべき点

Flexの子要素は、デフォルトで min-width: auto になります。そのため、Flexアイテムがコンテンツ幅より小さくなるのを拒み、text-overflow: ellipsis が機能しなくなります。Flexの子要素に min-width: 0 を設定して修正します。

/* WRONG — ellipsis will NOT trigger inside a flex container */
.flex-parent {
	display: flex;
}
.flex-parent > .label {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* CORRECT — add min-width: 0 so the flex item can shrink */
.flex-parent > .label {
	min-width: 0;          /* ← this is the fix */
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

このパターンは VS Code 全体で使われています。たとえば、.monaco-icon-label-container は min-width: 0 と flex: 1 を設定し、ラベルテキストを切り詰められるようにしています。

固定要素と可変要素

行に固定サイズの要素(アイコン、アクションボタン)と可変のテキストがある場合:

.row {
	display: flex;
	align-items: center;
}
.row > .icon {
	flex-shrink: 0;        /* icon never shrinks */
	width: 16px;
}
.row > .label {
	flex: 1;               /* label takes remaining space */
	min-width: 0;          /* allows shrinking below content width */
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.row > .actions {
	flex-shrink: 0;        /* action buttons never shrink */
}

これは、ツリーの行、リスト項目、タブラベル、ビューペインのヘッダーにおける標準的なパターンです。

ホバーで全文を表示

テキストが省略記号で切り詰められる場合、全文にアクセスできるように、ホバーツールチップを表示する必要があります。ユーザーが読めるよう、切り詰める前の全文を指定して IHoverService.setupDelayedHover() を使用します。

this._register(this.hoverService.setupDelayedHover(labelElement, {
	content: fullLabelText,
}));

IconLabel とリストやツリーのレンダラーでは、これは自動的に処理されます。カスタムDOMの場合は、手動で追加する必要があります。

アンチパターン(絶対にしないこと)
  • 絶対に、テキストを省略記号なしでクリップしないでください。overflow: hidden が設定されている場合は、text-overflow: ellipsis も必ず設定してください。
  • 絶対に、ローカライズされる可能性のあるテキストに固定ピクセル幅を使用しないでください。ローカライズ後の文字列は長さが異なります。
  • 絶対に、overflow: hidden と white-space: nowrap を指定せずに text-overflow: ellipsis を使用しないでください。3つすべてが必須です。
  • 絶対に、切り詰める必要のあるFlexの子要素に min-width: 0 を設定し忘れないでください。
  • 絶対に、全文を表示するホバーやツールチップを用意せずにテキストを切り詰めないでください。

10. デザインシステムのサイズトークン(スペーシング、角丸、フォント、コーディコン、ストローク)

VS Code には、src/vs/platform/theme/common/sizes/baseSizes.ts に登録され、--vscode-* CSS 変数として出力されるデザインシステムのサイズスケールがあります。CSS を記述または編集するときは、トークンがある場合は常に、px 値を直接指定する代わりにトークン変数を使用してください。テーブルの全容と根拠は、自動挿入される .github/instructions/design-tokens.instructions.md に記載されています(正規の情報源です。このセクションも内容を一致させてください)。このセクションでは、より踏み込んだスタイリング作業のための判断基準を説明します。

参照する --vscode-* サイズ変数は、すべて build/lib/stylelint/vscode-known-variables.json の "sizes" 配列に(アルファベット順で)すでに存在している必要があります。そうでないと、stylelint/衛生チェックが失敗します。新しいトークンを追加する場合は、baseSizes.ts とこの JSON ファイルの両方に追加してください。

スペーシング — padding、margin、gap

スケール(px):0, 2, 4, 6, 8, 10, 12, 16, 20, 24, 28, 32, 36, 40 → --vscode-spacing-sizeNone、--vscode-spacing-size20 … --vscode-spacing-size400(トークンの数字は px × 10。つまり、size200 = 20px)。

重要なのはトークンではなく値です。 var() の採用は任意です。値がスケールに沿っていれば、px 値を直接指定しても問題ありません。リズムを崩すのは、スケール外の値(3、5、7、14、26px など)です。スケール外の値は最も近いスケール値に丸め、中間値は切り上げます(5px → 6px、3px → 4px、1px → 2px、26px → 28px)。ショートハンドの各長さは個別に確認されます(0 5px → 0 6px)。auto、%、em/rem、var()/calc() は変更しないでください。

角丸 — border-radius
px変数用途
2--vscode-cornerRadius-xSmall非常にコンパクトな要素
4--vscode-cornerRadius-smallコントロール(ボタン、入力欄)
6--vscode-cornerRadius-medium基本/内側のサーフェス
8--vscode-cornerRadius-large目立たせる/外側のサーフェス
12--vscode-cornerRadius-xLarge非常に目立たせるサーフェス
9999--vscode-cornerRadius-circle完全な角丸(ピル、ドット)

スケール外の値の丸め対応表(中間値は切り上げ):2→xSmall、3,4→small、5,6→medium、7,8→large、10,11,12→xLarge、14,16,18,20→xLarge、999→circle。

  • ピル型(半径が要素の高さの約半分。例:28h/14r、36h/18r、22×22/11r)→ --vscode-cornerRadius-circle。xLarge は使用しないでください。数値に最も近いトークンを使うと角張ってしまい、完全な角丸にする意図が損なわれます。
  • 変更しないもの: 50%、0、0px、inherit、calc()/var()。!important は保持してください。
フォントサイズとウェイト

汎用 UI スケール — サイズトークンとウェイトトークンを組み合わせます(「Strong」は対応するサイズトークン+semiBold で、別のサイズではありません)。

pxサイズ変数ウェイト
26--vscode-fontSize-heading1semiBold
18--vscode-fontSize-heading2semiBold
13--vscode-fontSize-heading3semiBold
13--vscode-fontSize-body1regular
11--vscode-fontSize-body2regular
12--vscode-fontSize-label1regular
11--vscode-fontSize-label2regular
10--vscode-fontSize-label3regular

汎用ウェイト:--vscode-fontWeight-regular(400)、--vscode-fontWeight-semiBold(600)。

非推奨 — --vscode-bodyFontSize(13)→ --vscode-fontSize-body1、--vscode-bodyFontSize-small(12)→ --vscode-fontSize-label1、--vscode-bodyFontSize-xSmall(11)→ --vscode-fontSize-body2。

従来の Agents 固有トークンである --vscode-agents-fontSize-* と --vscode-agents-fontWeight-* も非推奨です。対応する汎用トークンを使用してください。

  • medium(500)はありません。 font-weight: 500 はスケール外のため、semiBold に丸めます。同様に、700/bold は 400 と 600 のうち近い方に丸めます。
  • 「Strong」は別のサイズではありません。「Body 1 Strong」は、対応する --vscode-fontSize-* サイズトークン+semiBold です。Strong 用のサイズは追加しないでください。
  • normal ≡ 400 → regular。inherit、lighter、bolder、var()/calc() は変更しないでください。
Codicon のサイズ — アイコンの font-size

Codicon は 16px または 12px のみです。14px やその中間の値は使用しません。

px変数用途
16--vscode-codiconFontSize(基本)アイコンのデフォルトサイズ
12--vscode-codiconFontSize-compact高密度/インラインのクローム

コンパクトグリフの規則: アイコンをコンパクトな 12px サイズにする場合は、登録済みのグリフも *Compact バリアントに切り替えます(例:Codicon.close → Codicon.closeCompact、Codicon.add → Codicon.addCompact)。CSS の font-size だけではアイコンのサイズが変わるだけで、視覚的に最適化されたコンパクトグリフには切り替わりません。切り替えるには、登録済みのアイコン(Action2 の icon:/renderIcon)を変更する必要があります。グリフの元のクラスを対象とする CSS セレクターがない場合に限り、グリフを切り替えてください(例:.codicon-close)。グリフクラスをキーとするセレクター(.codicon-add、.codicon-chevron-down)は、クラスが -compact に変わると機能しなくなるため、セレクターも更新するか、.monaco-button のようなグリフに依存しないラッパークラスでサイズを指定してください。一部のアイコン(settings/sliders、agent、vm、info、lock、plus)にはコンパクトバリアントがありません。12px でも通常のグリフを使用してください。

ストローク — 境界線の幅

ストロークの太さは 1 種類のみです。1px → --vscode-strokeThickness。border: 1px solid <color> の省略記法と border-width: 1px に適用されます。その他の幅にはトークンがないため、そのままにしてください。

/* prefer */  border: var(--vscode-strokeThickness) solid var(--vscode-widget-border);
/* avoid  */  border: 1px solid var(--vscode-widget-border);

主なファイル

領域ファイル
SplitViewsrc/vs/base/browser/ui/splitview/splitview.ts
Gridsrc/vs/base/browser/ui/grid/grid.ts
スクロールバーsrc/vs/base/browser/ui/scrollbar/scrollableElement.ts
ワークベンチのグローバルスタイルsrc/vs/workbench/browser/media/style.css

コメント