SCSSをトークン化してみた. 3
前回はトークンの説明でした。
今回は実際に作ったトークンの中からプリミティブトークンを紹介してみます。
目次
全体構成
まずはfoundationのディレクトリ構成です。
プリミティブトークンとマップトークン、そして全体の仕組みの土台になるcoreがあります。
foundation/
├─ _index.scss
├─ core/
│ ├─ _base.scss
│ ├─ _functions.scss
│ ├─ _mq.scss
│ └─ _reset.scss
├─ maps/
│ ├─ _color-map.scss
│ ├─ _elevation-map.scss
│ ├─ _font-size-role-map.scss
│ ├─ _font-size-scale-map.scss
│ ├─ _font-weight-role-map.scss
│ ├─ _gradient-map.scss
│ ├─ _radius-map.scss
│ ├─ _shadow-map.scss
│ ├─ _space-map.scss
│ ├─ _transition-map.scss
│ └─ _z-map.scss
└─ primitives/
├─ _primitives-color.scss
├─ _primitives-font-weight.scss
├─ _primitives-shadow.scss
├─ _primitives-space.scss
├─ _primitives-transition.scss
└─ _primitives-typography.scss
プリミティブトークン
まずは元の値となるプリミティブトークンです。
これらがサイト全体のテイストに影響します。
primitives-color(色の素材トークン)
サイトで使う色の実値(#xxxxxx)だけを定義するプリミティブ層です。gray-100 や neutral-900 のような色の“素材”をここに集約し、text.default や bg.subtle などの意味付け(用途割り当て)は color-map 側で行います。これにより、色の直書きを防ぎつつ、配色変更もプリミティブ側の差し替えで一括反映できます。
// ==================================================
// Foundation: variables (Primitive Layer)
// 値そのもののみ定義。意味は color-map 側で付与。
// ==================================================
// ==================================================
// Base (non-scaled)
// ==================================================
$white: #ffffff;
$off-white: #f8f6f2;
$black: #13100e;
// ==================================================
// Grayscale
// ==================================================
$gray-50: #fdfefe;
$gray-100: #fcfdfe;
$gray-200: #f9fafc;
$gray-300: #e6eaee;
$gray-400: #cfd5db;
$gray-500: #b6bcc2;
$gray-600: #9ca2a9;
$gray-700: #7d838a;
$gray-800: #5e656c;
$gray-900: #3f464d;
// ==================================================
// Neutral Scale(ブラウン〜和色系)
// ==================================================
$neutral-50: #f5f3ef;
$neutral-100: #f4f1ed;
$neutral-200: #efede9;
$neutral-300: #eae5de;
$neutral-400: #cdc4bc;
$neutral-500: #a49a92;
$neutral-600: #7a7169;
$neutral-700: #655b54;
$neutral-800: #4f453e;
$neutral-900: #3a2f29;
// ==================================================
// Red Scale
// ==================================================
$red-50: #f8eded;
$red-100: #f2dede;
$red-200: #e4bebe;
$red-300: #c89a9a;
$red-400: #aa2e26;
$red-500: #8e2e2a;
$red-600: #712e2e;
$red-700: #692727;
$red-800: #621f1f;
$red-900: #5a1818;
// ==================================================
// Blue Scale
// ==================================================
$blue-50: #ebf1f7;
$blue-100: #d7e3ee;
$blue-200: #b4c9dd;
$blue-300: #7fa7c5;
$blue-400: #2f5c84;
$blue-500: #2a5275;
$blue-600: #244766;
$blue-700: #21405c;
$blue-800: #1d3a53;
$blue-900: #1a3349;
// ==================================================
// Gold Scale
// ==================================================
$gold-50: #f7f3eb;
$gold-100: #f2ece2;
$gold-200: #cbbfa8;
$gold-300: #8e837a;
$gold-400: #6e655e;
$gold-500: #5f574f;
$gold-600: #504940;
$gold-700: #484137;
$gold-800: #40382f;
$gold-900: #383026;
// ==================================================
// Green Scale
// ==================================================
$green-50: #e9f4ec;
$green-100: #d3e9db;
$green-200: #abd4b7;
$green-300: #7fbd93;
$green-400: #43a047;
$green-500: #398d3e;
$green-600: #2f7a36;
$green-700: #296b2f;
$green-800: #245d29;
$green-900: #1e4e22;
// ==================================================
// Yellow Scale
// ==================================================
$yellow-50: #fff7e8;
$yellow-100: #ffefcf;
$yellow-200: #ffe1a3;
$yellow-300: #ffd36f;
$yellow-400: #f9a825;
$yellow-500: #e29a12;
$yellow-600: #cc8c00;
$yellow-700: #b67c00;
$yellow-800: #a06d00;
$yellow-900: #8a5d00;
primitives-font-weight(太さの素材トークン)
フォントの太さを数値(400/600/700など)で一元管理するプリミティブ層です。ここでは regular / semibold / bold のような素材トークンと実値の対応だけを持ち、heading や body など用途ごとの割り当ては font-weight-role-map 側で行います。太さの直書きを防ぎ、サイト全体の太さ運用を最小の段階で安定させます。
// ==================================================
// Foundation: variables (Primitive Layer)
// ==================================================
// ==================================================
// Font
// ==================================================
$font-family-ja: 'Noto Sans JP', sans-serif;
$font-family-en: 'Lato', sans-serif;
$font-size-base: 16px;
primitives-shadow(影色の素材トークン)
box-shadow に使う影色の基準色($shadow-base)と、よく使う不透明度バリエーション($shadow-05〜$shadow-60)を素材としてまとめたプリミティブ層です。影の「用途(card/modalなど)」や「サイズ(sm/md/lg)」はここでは扱わず、shadow-map や elevation-map 側でこの素材を参照して影を組み立てます。
// ==================================================
// Foundation: primitives-font-weight (Primitives)
// 重さの唯一ソース(最小運用:3段)
// - regular: 本文
// - semibold: 強調 / UI
// - bold: 見出し
// ==================================================
$font-weight-map: (
'regular': 400,
'semibold': 600,
'bold': 700,
);primitives-space(余白スケールの素材トークン)
余白の共通スケール(none / xs〜7xl)を、ブレークポイント(xs/sm/md/lg/xl)ごとのレスポンシブ値として定義するプリミティブ層です。ここは「段階そのもの(スケール)」だけを持ち、container-inline や button-inline などの用途別キーは space-map 側で管理します。余白の基準を一箇所に集約することで、全体の“間”の調整がしやすくなります。
@use '../core/function' as *;
// ==================================================
// Foundation: primitives-space
// Token Type: Scale(段階) / Mixed: No
// Source: rem()(core/function)
// --------------------------------------------------
// Purpose: 余白の共通スケール(none / xs〜7xl)をレスポンシブ値で定義
// Keys: none, xs, sm, md, lg, xl, 2xl...7xl × (xs/sm/md/lg/xl)
// Notes: 用途別(container/button...)は maps 側で管理する
// ==================================================
$space-scale-map: (
'none': (
'xs': rem(0),
'sm': rem(0),
'md': rem(0),
'lg': rem(0),
'xl': rem(0),
),
'xs': (
'xs': rem(4),
'sm': rem(4),
'md': rem(8),
'lg': rem(8),
'xl': rem(8),
),
'sm': (
'xs': rem(8),
'sm': rem(8),
'md': rem(8),
'lg': rem(16),
'xl': rem(16),
),
'md': (
'xs': rem(8),
'sm': rem(16),
'md': rem(16),
'lg': rem(24),
'xl': rem(32),
),
'lg': (
'xs': rem(16),
'sm': rem(24),
'md': rem(32),
'lg': rem(32),
'xl': rem(40),
),
'xl': (
'xs': rem(24),
'sm': rem(32),
'md': rem(40),
'lg': rem(48),
'xl': rem(56),
),
'2xl': (
'xs': rem(32),
'sm': rem(40),
'md': rem(48),
'lg': rem(64),
'xl': rem(72),
),
'3xl': (
'xs': rem(40),
'sm': rem(48),
'md': rem(64),
'lg': rem(72),
'xl': rem(88),
),
'4xl': (
'xs': rem(64),
'sm': rem(64),
'md': rem(80),
'lg': rem(96),
'xl': rem(112),
),
'5xl': (
'xs': rem(80),
'sm': rem(80),
'md': rem(96),
'lg': rem(120),
'xl': rem(144),
),
'6xl': (
'xs': rem(96),
'sm': rem(96),
'md': rem(120),
'lg': rem(144),
'xl': rem(168),
),
'7xl': (
'xs': rem(120),
'sm': rem(120),
'md': rem(160),
'lg': rem(192),
'xl': rem(216),
),
);
primitives-shadow(影色の素材トークン)
box-shadow に使う影色の基準色($shadow-base)と、よく使う不透明度バリエーション($shadow-05〜$shadow-60)を素材としてまとめたプリミティブ層です。影の「用途(card/modalなど)」や「サイズ(sm/md/lg)」はここでは扱わず、shadow-map や elevation-map 側でこの素材を参照して影を組み立てます。
@use '../primitives/primitives-color' as *;
// ==================================================
// Foundation: primitives-shadow
// Token Type: Primitives / Mixed: No
// Source: primitives-color(実値の唯一ソース)
// --------------------------------------------------
// Purpose: 影色(ベース)と不透明度バリエーション(素材)を提供する
// Keys: $shadow-base, $shadow-05..$shadow-60
// Notes: semantic(用途)や scale(sm/md/lg)は扱わない
// ==================================================
// Figma: ds/primitives/black (inverse) に対応(影の基準色)
$shadow-base: $black;
// 透明度付きシャドウカラー(プリミティブ)
$shadow-05: rgba($shadow-base, 0.05);
$shadow-07: rgba($shadow-base, 0.07);
$shadow-09: rgba($shadow-base, 0.09);
$shadow-10: rgba($shadow-base, 0.10);
$shadow-12: rgba($shadow-base, 0.12);
$shadow-13: rgba($shadow-base, 0.13);
$shadow-16: rgba($shadow-base, 0.16);
$shadow-18: rgba($shadow-base, 0.18);
$shadow-22: rgba($shadow-base, 0.22);
$shadow-60: rgba($shadow-base, 0.60);
primitives-transition(動きの素材トークン)
transition の基本パラメータである duration(速さ) と easing(曲線) を、実値の唯一ソースとして定義するプリミティブ層です。ここでは fast/normal/slow や out/in-out/linear の“素材”だけを持ち、ボタン・カードなど用途別の動きプリセット(hover/active で何をどう変えるか)は transition-map 側で組み立てます。これにより、サイト全体の“動きの気配”を一貫させつつ、調整も一箇所で済みます。
// ==================================================
// Foundation: primitives-transition
// Token Type: Scale(段階) / Mixed: No
// Source: none(実値の唯一ソース)
// --------------------------------------------------
// Purpose: transition の基本パラメータ(duration / easing)を提供する
// Keys: $transition-duration-map / $transition-easing-map
// Notes: preset(用途)は扱わない
// ==================================================
$transition-duration-map: (
'fast': 0.24s,
'normal': 0.5s,
'slow': 1s,
);
$transition-easing-map: (
'out': cubic-bezier(0.16, 1, 0.3, 1),
'in-out': cubic-bezier(0.65, 0, 0.35, 1),
'linear': linear,
);
プリミティブトークンは以上です!
次回はマップトークンの紹介です。
今回は以上です!