GODRICH
#cssアニメーション#ボタン#ローディング#トランジション#スクロール#ダッシュボード#実用ui#デザイントレンド

css タイポグラフィ プレイグラウンド 9種 — webフォントを読み込まずに

css タイポグラフィとは、フォントのダウンロードを待たずにサイズ・太さ・字間・行間でページの読み心地を決める作業です。この9つのプレイグラウンドは webフォントを読み込まずに、OS がもともと持っているシステムフォントだけで組んであり、下のグリッドは今すぐ動きます。どれもコードをそのままコピペできます。

自動再生 · タイルを押すとその項目へ · すべて1つのzip

並びは人気順ではなく、文字の設計を進める順です。まずどの OS にも入っている書体の顔を並べて確かめ(01)、太さの軸を動かし(02)、字間と行間で息を整え(03)、一行の長さと行のリズムを決め(04)、見出しの段階を積み(05)、書体の骨格を見比べ(06)、見出しと本文の組み合わせを試し(07)、最初の一文字を飾り(08)、最後に画面の幅へ追従させます(09)。01〜03 は一文字の見た目、04・05 は文章全体の骨組み、06〜09 は書体同士の関係と場面への当てはめという、3つのまとまりでも読めます。9つとも 480×300px の枠で録画して確かめ、320px の幅でもはみ出しは0か所でした。動く文字をさらに試したい方にはキネティック・タイポグラフィのヒーローが、引用の飾りには引用・プルクオートのデザインが隣にあります。

01システムフォントスタック比較

同じ文章を3枚のパネルに並べ、serif・sans・mono のシステムスタックをそれぞれ着せる、デザインシステムのフォント指定ページの部品です。

システムフォントスタック比較
新しいタブで開く

01 · システムフォントスタック比較 — 計測 累積面積 23.762% · 動いたフレーム 14/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

font-familysystem-uiui-monospace

3つの宣言がこのデモの本体

// 見本。3枚のパネルがそれぞれのシステムスタックを着る — この3つの宣言がこのデモの本体
.fs__spec {
  margin: 0; color: $subject-cream;
  font-size: clamp(13px, 4.6vw, 20px); font-weight: 600; line-height: 1.45;
}
.fs__spec--serif { font-family: $serif; }
.fs__spec--sans { font-family: $sans; }
.fs__spec--mono { font-family: $mono; }

スタックは ui-serif · Georgia / system-ui · Segoe UI / ui-monospace · Consolas と、どの OS にも入っている顔ばかりで、20px の見本3枚は #1c191e を背景に 16.38:1 でそろいました。

タブで見本がそろって着替える

var SAMPLES = ['素早い茶色の狐', 'Hello Type 0123', 'CSSタイポ 2026'];
// タブを押すと3枚のパネルの見本の文がそろって着替える — プレビューのループはここで外す
tabs.forEach(function (tab, i) {
  tab.addEventListener('click', function () {
    fs.classList.remove('is-demo');
    tabs.forEach(function (t) { t.setAttribute('aria-pressed', String(t === tab)); });
    specs.forEach(function (spec) { spec.textContent = SAMPLES[i]; });
  });
});

タブを切り替えると押した側だけ aria-pressed が true になり、3枚の見本は「素早い茶色の狐」「Hello Type 0123」「CSSタイポ 2026」にそろって着替えます。

02ウェイト軸スライダー(100〜900)

スライダーで font-weight を 100 から 900 まで動かし、画面にはブラウザが実際に計算した値が追いかけて出る、エディタやツールのフォント設定パネルの部品です。

ウェイト軸スライダー(100〜900)
新しいタブで開く

02 · ウェイト軸スライダー(100〜900) — 計測 累積面積 5.237% · 動いたフレーム 14/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

font-weightfont-variation-settingsoninput

画面の数値はブラウザの計算値を読み直す

// oninput — ハンドルを掴んでいる間、毎フレーム追ってくる。
// 画面の数値は指定値をそのまま書き写すのではなく、getComputedStyle でブラウザが
// 実際に計算した font-weight を読み直した値。可変軸には font-variation-settings 'wght' を
// 一緒に渡す — 片方だけ変えると、可変フォントではもう一方の宣言がレンダリングに勝つ。
range.oninput = function () {
  wt.classList.remove('is-demo');
  var v = range.value;
  var pct = (v - 100) / 8;
  big.style.fontWeight = v;
  big.style.setProperty('--w', v);
  hangul.style.fontWeight = v;
  hangul.style.setProperty('--w', v);
  range.style.setProperty('--fill', pct + '%');
  range.setAttribute('aria-valuenow', v);
  out.textContent = getComputedStyle(big).fontWeight;
};

スライダーを 900 へ動かすと計算値も 900、100 へ戻すと 100 と正しく返り、矢印キー1回で 600 まで動きました。

可変軸と近いウェイトの分かれ道

// ── 見本。上の行は可変軸に乗る latin、下の行は近いウェイトへ寄る日本語
.wt__spec { margin: 0; display: flex; flex-direction: column; align-items: center; }
.wt__big {
  margin: 0; color: $subject-ink;
  font-family: $sans; font-weight: 700;
  font-size: clamp(38px, 15vw, 64px); line-height: 1.05;
  font-variation-settings: 'wght' var(--w, 700);
}
.wt__hangul {
  margin: 0; color: rgba($subject-ink, .72);
  font-family: $sans; font-weight: 700; font-size: 13px; line-height: 1.5;
  font-variation-settings: 'wght' var(--w, 700);
}

上の行(latin)は 'wght' の可変軸をなめらかにたどり、下の行は可変軸を持たないシステムフォントが近いウェイトへ寄るという、この差こそがデモの主役です。

03字間・行間ツマミ

letter-spacing のスライダーは em 単位、line-height のスライダーは単位なしの倍数で動き、値が文字の横にすぐ表示される、ブログ本文の設定パネルの部品です。

字間・行間ツマミ
新しいタブで開く

03 · 字間・行間ツマミ — 計測 累積面積 13.345% · 動いたフレーム 22/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

letter-spacingline-heighttextContent

em の字間と単位なしの行間

// 値は textContent で文字だけをその場で差し替える — innerHTML ではないので偽装の余地がない。
// letter-spacing は em 単位、line-height は単位なしの倍数で本文に直接届く。
track.oninput = function () {
  st.classList.remove('is-demo');
  var v = Number(track.value).toFixed(2);
  text.style.letterSpacing = v + 'em';
  track.style.setProperty('--fill', ((track.value + 0.04) / 0.34 * 100) + '%');
  trackVal.textContent = v + 'em';
};
lead.oninput = function () {
  st.classList.remove('is-demo');
  var m = Number(lead.value).toFixed(2);
  text.style.lineHeight = m;
  lead.style.setProperty('--fill', ((lead.value - 1) / 1 * 100) + '%');
  leadVal.textContent = m;
};

実際に動かすと、字間 0.3em では 13px の本文に 3.9px が乗り、-0.04em では -0.52px、行間 2.0 では 26px まで開きます。

箱の高さが舞台を守る

// 本文の見本。箱の高さを固定する — 行間が 2.0 まで開いても舞台の外に出られない
.st__body {
  height: 130px; overflow: hidden;
  padding: $sp-2; border: 1px solid rgba($subject-ink, .14); border-radius: $r-control;
}
.st__text {
  margin: 0; color: $subject-ink;
  font-family: $sans; font-weight: 500;
  font-size: clamp(10px, 3.2vw, 13px); line-height: 1.7; letter-spacing: 0.02em;
  overflow-wrap: break-word;
}

行間をいちばん広げたときも、はみ出した分は箱の中で切れるので、無理に文字を縮めなくてもレイアウトは崩れません。

04段落リズムプレビュー

一行の長さを ch のスライダーで決め、ベースライングリッドをオンにして行が罫に乗るか確かめる、ニュース・マガジン本文のプレビュー部品です。

段落リズムプレビュー
新しいタブで開く

04 · 段落リズムプレビュー — 計測 累積面積 17.881% · 動いたフレーム 17/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

chrepeating-linear-gradienttext-wrap: pretty

ch の幅と同じ間隔のグリッド

.tr__sheet {
  --measure: 44;
  box-sizing: border-box; width: calc(var(--measure) * 1ch); max-width: 100%;
  padding: $sp-2; border-radius: $r-sm;
}
// グリッドの罫は行間と同じ $lh の間隔で繰り返す
.tr__sheet.is-grid {
  background-image: repeating-linear-gradient(
    to bottom,
    rgba($subject-blue, .26) 0, rgba($subject-blue, .26) 1px,
    transparent 1px, transparent $lh
  );
  background-position: 0 $sp-2;
}
.tr__p {
  margin: 0; color: $subject-ink;
  font-family: $serif; font-weight: 400; font-size: 13px; line-height: $lh;
  text-wrap: pretty;
}

スライダーを 44ch に置くと見本の幅は 326.6px、28ch では 241.5px まで縮み、罫は行間 $lh(18px) と同じ間隔で並ぶので、行が乗っているかどうかが一目で分かります。

トグルは背景1行で終わる

// 実際に使う経路 — スライダーの値は ch の倍数としてそのまま入る。プレビューのループは同じ値を CSS キーフレームで揺らす
function applyMeasure() {
  sheet.style.setProperty('--measure', range.value);
  val.textContent = range.value + 'ch';
}
function stopLoop() { tr.classList.remove('is-demo'); }
range.addEventListener('input', function () { stopLoop(); applyMeasure(); });
grid.addEventListener('click', function () {
  stopLoop();
  var on = grid.getAttribute('aria-pressed') === 'true';
  grid.setAttribute('aria-pressed', on ? 'false' : 'true');
  sheet.classList.toggle('is-grid', !on);
});

トグルは aria-pressed の付け替えと is-grid の1クラスだけで、罫の on・off も値の表示も追加の要素なしで済みます。

05見出しスケールのはしご

比率を 1.125・1.25・1.333 から選ぶと、小さい段から大きい段までのサイズが calc() で積み直される、スタイルガイドの見出し体系ページの部品です。

見出しスケールのはしご
新しいタブで開く

05 · 見出しスケールのはしご — 計測 累積面積 48.553% · 動いたフレーム 16/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

calc()--ratiotoFixed

比率は calc の鎖が計算する

.ts__rung { display: flex; align-items: baseline; gap: $sp-2; }
.ts__glyph {
  flex: 1 1 auto; min-width: 0; color: $subject-cream;
  font-family: $sans; font-weight: 700; line-height: 1.15;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ts__rung--1 .ts__glyph { font-size: calc(var(--base) * 1px); }
.ts__rung--2 .ts__glyph { font-size: calc(var(--base) * var(--ratio) * 1px); }
.ts__rung--3 .ts__glyph { font-size: calc(var(--base) * var(--ratio) * var(--ratio) * 1px); }
.ts__rung--4 .ts__glyph { font-size: calc(var(--base) * var(--ratio) * var(--ratio) * var(--ratio) * 1px); }
.ts__rung--5 .ts__glyph { font-size: calc(var(--base) * var(--ratio) * var(--ratio) * var(--ratio) * var(--ratio) * 1px); }

比率 1.333 の5段目は 34.73px(ラベルは 34.7px)、1.125 では 17.62px までしか伸びず、同じ本文サイズでもはしごの高さが変わって見えます。

数値3組を重ねて置く理由

// 段の大きさは CSS が calc() の鎖で計算する。ラベルの数値は同じ式を JS でもう一度解き、toFixed で書く。
// 3つの比率の分を最初に全部書いておくので、プレビューのループが比率を変えても画面の数値が置き去りにならない
function buildLabels() {
  boxes.forEach(function (box) {
    var step = Number(box.getAttribute('data-step'));
    Object.keys(RATIOS).forEach(function (key) {
      var v = document.createElement('span');
      v.className = 'ts__v ts__v--' + key;
      v.textContent = (BASE * Math.pow(RATIOS[key], step)).toFixed(1) + 'px';
      box.appendChild(v);
    });
  });
}

数値は3つの比率の分を先に全部描いて opacity で切り替えるので、大きさと数字が違う比率を指す瞬間がありません。

06フォント解剖カード

大きな文字の上にベースライン・x ハイト・大文字の高さの罫を重ね、ex 単位の違いを見せる、タイポグラフィガイドや講習資料の部品です。

フォント解剖カード
新しいタブで開く

06 · フォント解剖カード — 計測 累積面積 41.664% · 動いたフレーム 15/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

::beforelinear-gradientex

x ハイトの罫だけが本当の寸法

.fa__rule {
  position: absolute; left: $sp-2; right: $sp-2;
  font-size: 52px;                     // ex がこの大きさの書体寸法に解けるようにする
  pointer-events: none;
}
.fa__rule::before {
  content: ""; display: block; height: 1px;
  background: linear-gradient(90deg, $color 0 6px, transparent 6px 10px);
  background-size: 10px 1px;
}
.fa__rule--base { bottom: calc(#{$sp-4} + #{$desc}); }
.fa__rule--x    { bottom: calc(#{$sp-4} + #{$desc} + 1ex); }
.fa__rule--cap  { bottom: calc(#{$sp-4} + #{$desc} + #{$cap}); }
// x ハイトの罫だけが見積もりではなく実際の書体寸法(ex) — 破線ではなく実線1本で区切る
.fa__rule--x::before {
  height: 2px;
  background: linear-gradient(90deg, $subject-orange-deep 0 100%);
}

x ハイトの罫だけが目分量ではなく実際の書体寸法で、serif のカードでは下から 176.0px、sans では 174.4px の位置に引かれます。

見本カードを選ぶクリックの経路

// 実際に使う経路 — 選んだ見本カードだけ前へ出る。プレビューのループは同じ切り替えを CSS のカットで回す
picks.forEach(function (b) {
  b.addEventListener('click', function () {
    fa.classList.remove('is-demo');
    var face = b.getAttribute('data-face');
    fa.classList.toggle('is-serif', face === 'serif');
    fa.classList.toggle('is-sans', face === 'sans');
    picks.forEach(function (x) {
      x.setAttribute('aria-pressed', x.getAttribute('data-face') === face ? 'true' : 'false');
    });
  });
});

ボタンを押すと is-demo が外れてプレビューのループが止まり、is-serif・is-sans の付け替えで今見ているカードだけに枠の色と薄い青の地が付きます。押された側は aria-pressed が true に変わるので、見た目の強調とスクリーンリーダーへの知らせが一度の操作でそろいます。

07見出し・本文ペアプレビュー

見出し書体と本文書体をそれぞれ選ぶと組み合わせがすぐ描かれ、イタリック・字間・行間のツマミが同じパネルに集まる、ランディングページ制作前の検討部品です。

見出し・本文ペアプレビュー
新しいタブで開く

07 · 見出し・本文ペアプレビュー — 計測 累積面積 26.822% · 動いたフレーム 21/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

font-familyfont-styleline-height

チップの顔を見本に移す

// チップはそれぞれの書体そのもので名前を書いている — computed の font-family をそのまま見本へ移す
function stack(btn) { return getComputedStyle(btn).fontFamily; }

function pick(btn) {
  pp.classList.remove('is-demo');
  var target = btn.getAttribute('data-row') === 'head' ? head : body;
  target.style.fontFamily = stack(btn);
  var row = btn.parentNode;
  var chips = row.querySelectorAll('.pp__chip');
  for (var i = 0; i < chips.length; i++) {
    var on = chips[i] === btn;
    chips[i].classList.toggle('is-on', on);
    chips[i].setAttribute('aria-pressed', on ? 'true' : 'false');
  }
}

見出し側を serif・本文側を sans にすると見出しは Georgia、本文は system-ui で描かれ、7通りの組み合わせを実際に操作して確かめました。

斜体と2つのツマミの値

// チップの文字はその書体そのもので打たれる — 名前と見本(Aa)が一緒にその書体の顔になる
.pp__chip--sans { font-family: var(--f-sans); }
.pp__chip--serif { font-family: var(--f-serif); }
.pp__chip--mono { font-family: var(--f-mono); }
.pp__chip--wide { font-family: var(--f-wide); }
.pp__spec { font-weight: 700; font-size: 12px; line-height: 1; }

イタリックを入れると見出しの font-style が italic になり、字間 0.08em は 1.92px、行間 1.9 は 24.7px と、数値も見本と一緒に動きます。

08ドロップキャップと引用の飾り

::first-letter を float で浮かせて段落の最初の文字を大きくし、initial-letter に対応するブラウザではそちらに任せる、マガジン風ブログ本文の装飾部品です。

ドロップキャップと引用の飾り
新しいタブで開く

08 · ドロップキャップと引用の飾り — 計測 累積面積 48.323% · 動いたフレーム 20/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

::first-letterfloatinitial-letter

2つの経路を分ける supports の分岐

// ドロップキャップの2つの経路。基本は float の道(すべてのブラウザ)、知っているブラウザは initial-letter の道へ任せる
.dq.is-cap .dq__text::first-letter {
  float: left;
  padding-right: $sp-1; padding-top: $sp-1;
  line-height: .82;
  font-weight: 700;
  font-size: calc(1.65em * var(--cap-lines));
  color: $subject-blue-deep;
}
@supports (initial-letter: 3) {
  .dq.is-cap .dq__text::first-letter {
    initial-letter: var(--cap-lines);
    float: none;
    padding-top: 0;
  }
}

Chrome 152 では CSS.supports(initial-letter) が true を返し、そのとき ::first-letter の float は none と計算されて initial-letter の経路が使われます。

行数は登録した数値で育つ

// initial-letter を知っているブラウザはそちらの経路へ渡る — バッジがどちら側かを知らせる
if (window.CSS && CSS.supports && CSS.supports('(initial-letter: 3)')) {
  badge.textContent = 'initial-letter 経路';
}

capBtn.addEventListener('click', function () {
  dq.classList.remove('is-demo');
  var on = dq.classList.toggle('is-cap');
  capBtn.setAttribute('aria-pressed', on ? 'true' : 'false');
});

var sizes = document.querySelectorAll('.dq__size');
for (var i = 0; i < sizes.length; i++) {
  sizes[i].addEventListener('click', function () {
    dq.classList.remove('is-demo');
    dq.style.setProperty('--cap-lines', this.getAttribute('data-lines'));
    for (var j = 0; j < sizes.length; j++) {
      var on = sizes[j] === this;
      sizes[j].classList.toggle('is-on', on);
      sizes[j].setAttribute('aria-pressed', on ? 'true' : 'false');
    }
  });
}

行数3では最初の文字が 61.875px・62×83px の箱に、行数4では 82.5px・86×110px に育ち、本文の行は 20.625px のまま動きません。

09レスポンシブ clamp() スケール

枠の端をドラッグすると枠の幅が rem で表示され、見出しサイズが clamp() の区間の中をなめらかに追う、レスポンシブサイトの見出し設計部品です。

レスポンシブ clamp() スケール
新しいタブで開く

09 · レスポンシブ clamp() スケール — 計測 累積面積 30.844% · 動いたフレーム 21/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

clamp()innerWidthmin()

cqw を見る箱ひとつ

// ── パネル: この箱がそのまま狭いビューポートの役。cqw 単位がこの箱の幅を見る
.cf__frame {
  position: relative;
  container-type: inline-size;
  width: min(62%, 30rem);
  box-sizing: border-box;
  padding: $sp-3 $sp-3 0;
  border-radius: $r-card;
  background: $stage-paper; box-shadow: $shadow-raised;
}
.cf__inner { min-height: 92px; }
.cf__title {
  margin: 0; color: $subject-ink;
  font-weight: 800; font-size: clamp(1.125rem, 13cqw, 3rem); line-height: 1.15;
}

箱に container-type: inline-size を置くと cqw はこの箱の幅を見るので、幅 336px では見出しは 40.56px まで育ちます。

ウィンドウ幅まで一緒に書く数値

// パネル幅(rem)・ウィンドウ幅(innerWidth を rem へ換算)・舞台に対する比率を書き直す。
// ループがパネル幅を動かす間も ResizeObserver が捉えて、数値が追ってくる。
function update() {
  var w = frame.offsetWidth;
  if (w === lastW) return;
  lastW = w;
  var winRem = window.innerWidth / 16;
  var ratio = Math.round(w / cf.clientWidth * 100);
  big.textContent = 'パネル ' + (w / 16).toFixed(1) + 'rem';
  sub.textContent = 'ウィンドウ ' + winRem.toFixed(1) + 'rem · 比率 ' + ratio + '%';
}

if ('ResizeObserver' in window) {
  new ResizeObserver(update).observe(frame);
  new ResizeObserver(update).observe(cf);
}
window.addEventListener('resize', update);
(function tick() { update(); requestAnimationFrame(tick); })();
update();

幅 432px ではパネル 27.0rem・比率 98% と表示され、ハンドルは矢印キー1回で 1rem(16px) ずつ動かせます。

フォントの組み合わせはシステムフォントでどこまでできるか?

手元に揃う4つの顔

見出しと本文の選択肢は sans(system-ui)・serif(Georgia)・mono(ui-monospace)・wide(Verdana) の4つで、どれも OS が最初から持っている顔です。「フォント 組み合わせ おすすめ」の記事は一組の紹介で終わりがちですが、このパネルでは 4×4 の 16通りをその場で着せ替えられ、代表的な7通りを実際に操作して Georgia と ui-monospace の濃さの差や Verdana の広がりを目で確かめられます。

選べる範囲と選べない範囲

システムフォントで決まるのは顔の選択・太さ・字間・行間・スケールの組み合わせまでで、ブランドの特定書体を1px も違わず再現する仕事は webフォントの領域です。「フォント 組み合わせ 相性」の判断は画面に並べて読むしかないので、07 のパネルで3行読んで合う・合わないを先に決め、土台が固まってから読み込みの重さと相談する順序が現実的です。書体そのものを扱う部分の仕様は MDN の font-family と font-weight を参照してください。

どこで壊れるか — 落とし穴

グリッドで見える動きは CSS キーフレームで、人が触る瞬間は JS の経路です。両者は別のコードなので、片方だけ生きていても測定は通ります。以下の3つは、実際に動かして初めて見つかった壊れ方です。

ループが計算値を汚す

02 のページを開いた瞬間、プレビューのループが font-weight を 100〜900 へ補間している途中だと、getComputedStyle が返すのは 135.25 のような中間値でした。この値を信じて初期表示に使うと、スライダーの 700 と表示が食い違います。HTML に書いた初期値 700 がスライダーと CSS の両方と一致している間は読み直さないことが、この落とし穴への答えです。実際に触った後は 100 は 100、900 は 900 と正しく返りました。

320px で静かに溢れるトラック

04 の初期値 44ch の見本は実測 326.6px で、stage の自動トラックは項目の max-content まで勝手に広がります。320px の画面ではこの列が画面幅を超え、警告もなく横にあふれます。列を minmax(0, 1fr) で締め直すと 320px でも scrollW は 320 のままで、はみ出しは0か所に戻りました。まとめた zip のパスワードは rdv7unke で、狭い画面での見え方もこの静的な経路で撮り直しています。

天井に届いた見出しは育たない

09 でパネル幅を 336px まで広げると見出しは 40.56px、432px では 48px で止まり、ハンドルをさらに +120px ドラッグして 442px にしても 48px のままです。clamp() の3番目の値(3rem)が天井で、届いた後は何も起きないように見えます。下限も同じで、176px のパネルでは 19.76px まで下がって止まります。天井を上げる前に、その幅で一行に収まるかを先に確かめるのがこの落とし穴の避け方です。

3つのバリエーションとアクセシビリティ

数字を3つ書き換えるだけで、9つの顔が一緒に変わります。

名前 書き換える値 変わる感じ
base $base 11 → 12 05 のはしご全体が一段大きくなる
lh $lh 18px → 20px 04 の行間もグリッドの罫も一緒に広がる
slope 13cqw → 16cqw 09 は同じ幅でも見出しが大きくなり、天井に早く届く

操作はすべて本物の button と input なので、キーボードとスクリーンリーダーの経路が生きています。02 のスライダーは矢印キーで動き(実測では ArrowRight 一回で 600 へ)、09 のハンドルは矢印キーで 1rem(16px) ずつ動かせ、押されている側は 01・04〜08 の aria-pressed が、今の値は aria-valuenow が伝えます。チップやタブは名前をその書体そのもので書いているので、動きを止めた静止画でも選択肢の顔が分かります。プレビューの動きは .is-demo クラスを外すだけで本物の操作に道を譲る作りなので、動きが止まっても機能は失われません。prefers-reduced-motion: reduce では9つのプレビューのループがすべて止まり、03 は字間 0.02em・行間 1.7 の落ち着いた本文が、05 は選んだ比率 1.25 のはしごが、08 は初期値の3行のドロップキャップが1枚の静止画として残ります。文字 59 か所のコントラストを描画後の色で測って AA 未達は0か所、最小は #f0f5fe を背景にした 4.91:1 でした。

FAQ

「webフォント おすすめ css」の記事を読んでからでないとフォント指定は決められませんか

読み込み方の話は webフォントを足すときに必要で、顔の選択・太さ・字間・行間という土台は先に決まります。9つで土台を固めてから読み込み方を調べる方が、どの書体を足すべきかの判断も早いはずです。

font-weight の細い 100 が日本語の部分だけ太く見えるのはなぜですか

日本語のシステムフォントは可変軸を持たないことが多く、指定に近いウェイトへ寄せて描かれます。02 では数値そのものは 100・900 と正しく返る一方で字形の側は段差で飛ぶので、細すぎないか・太すぎないかは日本語の見本で先に見ておくのが安全です。latin 側の見本は可変軸をなめらかにたどるので、両方の行を並べた 02 の構成が、この差を確かめるいちばん手軽な方法になります。

clamp() の最小値と最大値はどう決めればよいですか

最小は本文が読める下限(このデモでは 1.125rem=18px)、最大はその幅の一行に収まる上限(3rem=48px。パネル 432px で頭打ちになった実測値)です。この2点を決めてから、間の傾き(13cqw)を調整します。詳しくは MDN の clamp() を参照してください。

解凍パスワードを入力してください

パスワードはこの記事の本文の中にあります。読み進めると出てきます。