ナビゲーション

はじめに

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 を組み合わせて動作します。.action はこの例の @layer components 内で定義され、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 をアプリに接続し、構文チュートリアルで操作状態やレスポンシブ条件に対応するカードを作りましょう。記述中の入力補完や診断には、言語サービスを設定してください。