ウェブサイトにおけるタイポグラフィのパターンの設計

ウェブサイトのタイポグラフィのルールは一貫性を欠いてしまいがちだ。

単純にページやコンポーネント単位でデザインしていると、その周辺の要素だけで判断することになるので、全体として見ると一貫性を失ってしまう。

僕が考える解決策は、コンポーネントからは独立したタイポグラフィだけを定義するルールセットを作ること。そして全てのコンポーネントは必ずいずれかのルールセットに従うようにする。

@mixin typography-heading {
  font-size: 2rem;
  line-height: 1.3;
}

.article-heading {
  @include typography-heading;
}

ルールセットは必ずセマンティックな(意味のある)命名をする。見た目に依存しない命名だと、デザイン変更のたびに大幅にコードを変更しなくて済むことが多い。そして、情報として同じ意味を持つ要素は、タイポグラフィも一貫させるという意図を強調させるためだ。

これに加えて、反復の原則をより意識すると、ルールセット内で利用する値はデザイン全体で共通のものにしたい。これをコードで表現すると、あらかじめ利用する可能性のある値は全て定義しておいた上で、ルールセットはその値を参照するだけになる。

$breakpoint-small: 480px;

$font-size-root: 16px; // browser default

$font-size: 1rem;
$font-size-x-small: (12px / $font-size-root * 1rem);
$font-size-small: (14px / $font-size-root * 1rem);
$font-size-large: (24px / $font-size-root * 1rem);
$font-size-x-large: (32px / $font-size-root * 1rem);
$font-size-xx-large: (48px / $font-size-root * 1rem);
$font-size-xxx-large: (64px / $font-size-root * 1rem);
$font-size-xxxx-large: (96px / $font-size-root * 1rem);
$font-size-xxxxx-large: (128px / $font-size-root * 1rem);

$line-height: 1.7;
$line-height-small: 1.3;

この段階で定義する値は、意味を持たない単なるサイズでしかないため、基準になる値からの相対的な命名にする。これらの値は自身がどこから参照されるかには興味がない。

line-heightのバリエーションはこれくらいシンプルでも問題ないと思っている。Vertical Rhythmを意識するといろいろあるけど、設計の単純化のためには考えない方がいい。

@mixin typography-heading {
  font-size: $font-size-x-large;
  line-height: $line-height-small;
}

@mixin typography-sub-heading {
  font-size: $font-size-large;
  line-height: $line-height-small;
}

@mixin typography-lead {
  @media (min-width: $breakpoint-small) {
    font-size: $font-size-large;
  }
}

@mixin typography-caption {
  font-size: $font-size-small;
}

@mixin typography-button {
  font-size: $font-size-small;
  line-height: $line-height-small;
}

@mixin typography-display {
  font-size: $font-size-x-large;
  line-height: $line-height-small;

  @media (min-width: $breakpoint-small) {
    font-size: $font-size-xx-large;
  }
}

先述したように、これらはセマンティックな命名をした上で、単に先ほど定義した値を参照するだけ。メディアクエリによるスタイルの変更は、できればやらない方が設計としては単純になる。が、これはさすがに避けられないのでこの層に書く。

html {
  line-height: $line-height;
}

.article-heading {
  @include typography-heading;
}

.article-body {
  // inherit from root
}

.article-footer {
  @include typography-caption;
}

.article-more-link {
  @include typography-button;
}

.page-heading {
  @include typography-display;
}

.page-summary {
  @include typography-lead;
}

実際のコンポーネントからは、先ほど定義したmixinincludeするだけになる。ルートからfont-sizeline-heightをそのまま継承して使えるものには何もしない。


当然これで答えだと思ってないので、みなさんのいろいろな意見を聞かせてください。

参考
hail2u/hail2u.net
twbs/bootstrap
Shopify/polaris
Material Design