【解説】Variableを使ったボタンコンポーネントの作りとメリット
Figmaユーザーの中には「Variableをどう使うべき?」という悩みを持つ方もいるかと思います。Variableは本当に有用なのでしょうか?私も疑問に思ったので実験してみると、肥大化したコンポーネントを87.5%も圧縮でき、しかもCSSをより適切に出力できることも分かりました。そのプラクティスを、あるファイルの解説を通して具体的にシェアします。まさにLittle Big Thingsでした。
現在100人の購読を目標に頑張っています。友人や同僚の方々などにぜひシェアして応援くださいますと幸いです!
Introduction
前回、Varibaleを使った新しいボタンコンポーネントのFigmaファイルを皆さんにシェアしました。
今回は、このボタンコンポーネントの解説を行い、Variableの使い方やどのようなことを実現出来るのかお見せします。
これを見ただけでVariableが使えるようになるわけではありませんが、ちょっとだけスタート地点を前にする”ゲタ”になれるよう整理してきました。
お昼休憩に友人や同僚, 部下のデザイナーに作ったものを見せてもらうような、気軽な感覚でご覧ください。
そしてぜひFigmaコミュニティから同ファイルを触ってみてください。
今回使うファイル:Button Components by variable
新ボタンコンポーネント
コンセプト
このボタンコンポーネントは、
4つのスタイルと5つのState、
4つのサイズへ変化可能です。
また、ラベルがある/無い状態の両方を持ち、さらにライトモード/ダークモードの2モードをフォローしています。
作りの解説
では320種ものパターンをどのように実現しているのでしょうか?
まず前提として、320種すべてを手作りしているわけではありません。Variableを活用し、動的に変数を与えることで変形させています。
といっても、ファイル内のVariableは実は大変スリムになっています。たったこれだけしかありません。
paddingHoliz(水平方向のパディング)
paddingVert(垂直方向のパディング)
Radius(角丸の値)
そしてボタンのサイズごとに上記3変数に値を持たせるため、Large, Middle, Small, xSmallという4つのモードを作っています。
色とダークモードは別ライブラリから呼び込み
余談として、使用しているVariableは実のところこれだけではありません。
色については、個人的に開発・保守しているUIデザイン用の別途ライブラリから読み込んでおり1、そちらのVariableで指定しているカラーコードやプリミティブ・トークンがコンポーネントの色として当たっています。
こだわり
新旧比較:スリム化
Variableを使うことでまずやりたかったことは、スリム化でした。
なぜスリム化したかったかを理解いただくため、そしてどれだけスリム化できたかを分かりやすく説明するために、Components(OLD)ページを見てみましょう。
こちらはVariableが無かった時期に作った同じボタンコンポーネントです(以降、”旧版”と呼称します)。
この旧版では160種*2種をvariantsとして持っており、一見すると1つのボタンとは思えないほど肥大化しています。変化可能なパターンとvariants数が1:1の関係であり効率的ではなかったためでした。
しかしVariableによって一目瞭然、これを解消しています。
paddingを変数に
このスリム化を実現できた理由の1つが、paddingをVariableにした点です。paddingHolizとpaddingVertという変数がこれにあたります。
この2つのVariableは「作りの解説」の節で解説した通りボタンサイズごとの値を定義されているので、これをそれぞれ水平方向のGap, 垂直方向のGapに適用することで、ボタンサイズごとにvariantsを作る必要が無くなりました。
サイズはL, M, S, XSの4つに分かれているため、このVariableだけで4分の3(=75%)が削減されたというわけです。
FigmaでMaterial Designを実現できるように
このボタンコンポーネントでは、HIG式とMaterial Design式の両方のスタイルを表現可能にしています。
しかし、Variableが無い旧版はエンジニアにとってフレンドリーな作りではありませんでした。というのも、Material DesignのカラーシステムをFigmaでは正確に実現出来なかったのです。
Material Designでは、ある要素が動的に色が変わる際の仕組みとして、別の色をオーバーレイさせる方法を取ります。これによってホバーした時に少しハイライトされるようなマイクロインタラクションを実現するわけです。
ただFigmaではこれを実現するには、上にかぶせる色を適用するための疑似要素を空のframeとして作る必要がありました。これはstateLayerなどと呼ばれます2。
これがVariableを使うことで、不要になりました。Variableであれば、Styleと違い2つ以上のトークンを1つのレイヤーに追加できるためです。
これはFigmaのレイヤーが1つ削減できただけでなく、Figmaが吐き出すCSSにも影響を与えました。
ということで、新旧それぞれのCSSを見てみます。
stateLayerを使った場合のCSS(スタイル部分のみ):
border-radius: 12px;
background: var(--sys-primary-green-light-primary, #006B56);
こちらでは、stateLayerとして与えているはずの半透の明白色のカラーコードもトークンも何故か書かれていません。つまり普通に間違っています。
この原因は、上述したstateLayerという空の疑似要素レイヤーがそのカラーコードを持っているからです。そちらを掴んでCSSを見てみると、次のように記述されています。
background: var(--state-layer-on-fill-opacity-008-on-light, rgba(255, 255, 255, 0.08));
つまり2つのレイヤーを見なければ実装の役に立ちません。
この構造では、エンジニアがFigmaのDev Modeでこのコンポーネントを見ると色を間違えて実装してしまいやすいということです。
たとえ間違いに気づいたとしても、よほどFigmaに明るいかレイヤー構造を予め共有されていなければ、Figmaのどこを見れば直せるのか分かりません。
しかも、上記2つのCSSをただ合わせても正しく動きません。backgroundのプロパティを1要素が2つ同時に持つことは出来ないからです。background-colorなりbackground-imageなりに手動で書き換えるべきことに思い至る必要があります。
そう難しいことではないですが、シンプルに面倒です。実質的にFigmaのDev Modeによるハンドオフは不可能に近い状態でしょう。
Variableを使った場合のCSS(スタイル部分のみ):
border-radius: var(--button-labeled-radius, 12px);
background: linear-gradient(0deg,
var(--sys-state-layer-on-fill-hover, rgba(255, 255, 255, 0.08)) 0%,
var(--sys-state-layer-on-fill-hover, rgba(255, 255, 255, 0.08)) 100%),
var(--sys-theme-green-primary, #006B56);
次に新版を見てみます。
こちらでは、stateLayer用のトークンがlinear-gradientによってしっかり記述されており、このまま使ってもほぼ意図通りのスタイルになります(※border: noneだけ足りてない)。
なにより、旧版のようにエンジニアが色々考える面倒が圧倒的に少なくなりました。
エンジニアからの評価
このボタンコンポーネントを知り合いのエンジニアにレビューしてもらったところ、更にいくつか指摘, 発見がありました。
なぜlinear-gradientなのか
1つは、linear-gradientで書く(書かれている)ことや、そもそもhoverなどのstateのスタイルとして上から色をかぶせるように作ることに気持ち悪さを感じなくはない(そういう人もいる)ということです。
実際のところ、Material DesignをWebプロダクトで使う場合何らかのライブラリを使うことが多いので、このような生のコードを見ることは少なく、見慣れないかもしれません。
純粋にプラクティスとしてはどうなんでしょうか?フロントエンドエンジニアの皆さんコメントでぜひ教えてください。
paddingVert VS buttonHeight
もう1つは、ボタンのHeightは固定の方がいいかも、という指摘です。
現在は「paddingを変数に」の節で説明した通り、垂直方向のパディングがボタンの高さを決めています。しかしこれだと他の要素と合わせて使う際に、少々使いづらいのです。
例えばメールフォームを作るとして、input部分とボタンの高さは合わせることが多いと思いますが、ボタンの高さが変動するとしたらinput部分の作りもボタンに合わせ変動させる必要があります。
単品としてそのように合わせること自体はよいのですが、これは”ボタンと合わせて使う時用の実装” という感じになります。さすがにもうちょっと疎な作りに出来るべきでしょう。
この点は改良ポイントと言えますね。
今後対応するアップデートを行おうと思っています。ボタンの高さ自体をVariableにして、buttonHeightなどとすることになるでしょう。この時、paddingVertは削除します。
アップデートについて
本ボタンコンポーネントは既にFigmaコミュニティに公開していますが、今後も保守していきます。
ただFigmaコミュニティにはアップデートをお知らせするような機能はありませんので、アップデートを皆さまに届けるのが容易ではありません。
そこで、チェンジログとしてFigmaファイルの更新などのお知らせを行う用のセクションを別途作成しました。
こちらはSubstackのシステムを活用していますが、本ニュースレターとは別に更新していきます。ご興味ある方はRSSやSubstackアプリでフォローしてみてくださいね。
さて、ニュースレターの品質を向上するため毎号ごとにアンケートを行っています。あなたの時間を少しでも良いものにするため、ご協力くださいますと幸いです🙏
【これはstateLayerなどと呼ばれます】
Material Design公式のFigmaファイルより。