💈

line-height: 1を定義しなかった理由

2023/12/18に公開

これはSaaS Designer Advent Calendar 2023 の16日目の記事です。遅れてすみません…… 🙇‍♂️


様々なコンポーネントライブラリ及びその周辺のタイポグラフィに関するデザイントークンを見ていると、line-height: 1がトークンの評価された値として定義されていることが多い気がします。 (行高とするか行送りとするかの言及を避けるためただline-heightと書くことにします)。
例えばSmartHR Design Systemだと「NONE」としてラベルテキストに使うものと定義されています。
https://smarthr.design/products/design-tokens/leading/#h2-0
私の感覚値、改行しないテキスト、例えばButtonのラベルなどに対して使われることが多いと思っています。

この記事は、あえて line-height: 1 に相当するタイポグラフィのデザイントークンを定義しなかった私の思う理由を書き散らしたもの です。

なお、どちらが正しいとかを言いたいわけではないこと、1つのケースでしかないことは念頭においてください。
また今年のAdvent Calendarで、もう1記事、今度は line-height: 1 をおく理由、みたいな記事があがるかもしれません。公開はこちらの記事が早いですが、大変おもしろいテーマだと思い、そちらの記事をパクって書いています (なんだかAdvent Calendarっぽいですね)。
ぜひ見比べて、より自分のケースに合う思想を考えていただけると嬉しいです。

追記: 公開されてました!ぜひこちらも!

https://note.com/ono_k/n/n618b18210050


line-height: 1 を評価された値とするトークンが必要とされる理由

これは裏付けがあるわけではなく私の持論なので、むしろ聞いてみたいところですが、概ね以下のような意見がありそうです。

  • 1行しか入らないことを明示したい (2行になるならそのためのline-heightをあてたい)
  • テキストの上下の余白 (CSSでのline-heightは上下に余白として表現されます) が嫌

参考までに以前キャシさんから頂いたリプを貼っておきます:
https://twitter.com/UIAlchemist/status/1670466771646652416

(これはこれで私も破壊寸前の赤ベコになるぐらい同意な意見なんですよね……)

line-height: 1 を評価された値とするトークンを定義しない代わりにどうしているか?

この投稿の対象である、私が設計に関わっているデザインシステム「For Design System」では、タイポグラフィに関するデザイントークンに相当するものとして「テキストトークン」があります。

https://for-design-system.pages.dev/tokens/text

(マルチブランドのデザインシステムとして設計している関係で、各プロダクトのデザインシステムの1段階上のレイヤーとして機能させるため「テキストトークンフレームワーク」と呼んでいますが、サイズ周りは基本プロダクト間で共通のため今回はただ「テキストトークン」と呼びます。)

特徴として、サイズに対してfont-sizeline-heightが1:1で決めうちされています。
つまりボタンのラベルでも本文でも、同一のサイズなら同一の line-height となる設計です。
(ウェブサイトを見ての通り、長い文章のテキストにはあまり適していません…読みにくい…。)

経緯としては、もともと私は昔からline-height: 1の存在理由があまり理解できないまま流れついてしまい、このデザインシステムに関わったとき「困ったら作ろう」と思い放置していたところ、数年経っても特に困らなかった、というだけの話です。

ただし、これは決して魔法で解決しているわけではありません。以下の問題を別箇所または考え方で解消しているだけに過ぎません。

  • 1行しか入らないことを明示したい (2行になるならそのためのline-heightをあてたい)
  • テキストの上下の余白 (CSSでのline-heightは上下に余白として表現されます) が嫌

1行しか入らないことを明示したいことの解決

前提として、昔のことはわかりませんが、私の周りではボタンのラベルを2行にしないほうがいい、というのは通念化したイメージがあります。
なので、1行しか入らないことの明示としてわざわざトークンを増やして複雑性を増す必要はないかな、というのが自分の見解です。

また、私は1行のテキストしか入らない、とデザイナーが決められるかというとそうでもないと思っています。
簡単に思いつくのはユーザーが入力するようなテキストです。デザイナー以外がデザインに関わることも増えてきた昨今、もちろんガイドラインは制定しつつも皆が皆守れる仕組みを整えるのはコストが高いことは言わずとも伝わると思います。

加えて、海外のアプリケーションの開発とローカリゼーションに携わっていた経験から見ると、翻訳時に想定されていた幅に収まりきらないことは多々あります。
よく日本語は短く書ける言語なので… という話を見かけますが、そういうものばかりでもなく、つらい単語の話は結構昔ですがNoteにもほんの一部だけ載せたことがあるので興味がある人はぜひ。

https://note.com/qsf/n/n63fc3335c6e3?magazine_key=meaaaedb501bf

https://note.com/qsf/n/n43d2fc796978?magazine_key=meaaaedb501bf

https://note.com/qsf/n/n398758ec2543?magazine_key=meaaaedb501bf

で何が言いたいかというと、こういう1行に収まるべきものを1行に収めるべくellipsis (…) を使うことは多々あると思うのですが、日本語の場合大事な数字等が後半へ回ってしまうことや、翻訳の都合上どうしても形がおかしくなりラベルが省略される、なんていうことも本当によくあります (本来はその修正まで含めてローカリゼーションなのですが、どうしてもただの翻訳で終わってしまうことはよくありますよね…)。

もう1つ、文字サイズを大きくして使っているユーザーが世の中にはいます。こういうユーザー向けに表示した際にデザイナーの環境では1行だと思っていたものが2行以上になることはよくあります。このようなときも同様のことが言えます。

私は関わっているドメインの属性上もあり、世界観が壊れることより情報が見えないこと・読めないことのほうが怖いです。(コンテンツやコンテンツの属性にアクセスできないことがなぜ好ましくないかは昨今アクセシビリティの文脈で多く語られている気がします。)

なのでまとめると、

  • 1行しかいれたくない箇所があることは伝言ゲームに任せる
  • 1行しか入らない設計をなるべくしたくない理由がある

ことにより、解決…?していると考えています。

テキストの上下の余白の解決

例えば font-size: 16px,line-height: 1.6でボタンを作ると、ラベルの高さが25.6pxになってしまいます。そうなってくるときっと以下のいずれかにしたくなるでしょう。

  • ボタンの高さを固定値にする
  • line-height: 1にしてきれいにグリッド (16pxが基本なので8pxのグリッドが多いですよね) にのせる

私はこの現象を避けるため、このテキストトークンの設計をしたと言っても過言ではないと思っています。

幸いなことにCSSのline-heightは上下に同じ分だけ余白を足すことで実現してくれるので、実は上下のpaddingを使う際とそれ以外は変わりがない、と私は考えています (これはほんとか?とちょっと怪しい気がしています)。

余談ですがこのあたりはrriverさんがわりと包括的にまとめてくれているものが役に立つかもしれません。
https://parashuto.com/rriver/development/line-height-in-web-design#css-line-height

もとに戻ると、Webとは言葉ですので、プロダクトの素材が言葉であると考えると、この素材を素材に素直にありつついかに組み立てやすいものに加工するかを考えなくてはなりません。
Web上のオンスクリーンプロダクトは様々なものを細かく作り、寄せ集めて作る、部分最適より全体最適な場合がとても多いです。この場合、素材が一定のグリッドにのっていると作りやすい気が、私はしています。

このために、For Design Systemのテキストトークンではline-heightの値を4の倍数になるよう固定しています。

For Design Systemのテキストトークンの一覧表 https://for-design-system.pages.dev/tokens/text にあるものと同じ

こうすることで、例えば基本の r を使ったときは、高さが24pxになります。これを素材にしてChip は高さが24pxになるように、そしてSelectTextFieldButtonはすべてmediumが32px, largeが40pxになるように設計しました。TextAreaも2行以上でもきちんとグリッドにのってくれるのが嬉しいなと感じています。

まとめると、

  • そもそもline-heightありきで余白を考えてデータを作るので固定値や余白の問題と向き合わなくてすむ
  • line-heightをグリッドに沿うようにあてているので解決している

と考えています。

ちなみに、よくline-heightの値は数値のみで設定すべきという話がありますが、主に子の要素にも継承されるため… という問題だと理解しています。このテキストトークンの仕組みを取り入れるとfont-sizeによってline-heightを毎回当てる必要があり、その部分は書き方によっては面倒かもしれません。Tailwind CSSではテキストのサイズに対してセットで常にline-heightやletter-spacingを当てることができるので助かっています。私がTailwind CSSで気に入っている数少ない機能の1つです。

まとめ

理由があるなら line-height: 1 に評価されるトークンははなくても意外となんとかなるかもしれない

おわり

参考:

Discussion