Tailwind CSSを導入した一年を振り返りながら、今後の展開について考えてみた。



この記事は「株式会社エイチームフィナジーAdvent Calendar 2021」18日目の記事になります。
@themeaningof8が担当いたします。

## はじめに
今回は昨年導入したTailwind CSSでの開発で今年得た気づきの共有と、気づきを来年に向けてどのように生かしていくか考えをまとめていきたいと思います。

去年の記事はこちらになります。

https://note.com/kazkiueda/n/n1492a2746155

## 注意点
なお、こちらはあくまでも私たちのケースでにおける一意見で、全てのケースにおいてお勧めする手法ではないことにご留意ください。特にCSS設計やライブラリにおいては色々な論争がありますが、これらはそのプロジェクトにおける課題によって大きく変わってきますし、そもそも課題がないプロジェクトに決して低くない開発コストを投じてまで変更を加える必要があるとは思いません。また、メリットを実感しづらいのであれば仮にリプレイスがされたとしても成果として実感しづらいかと思います。

ただ、私たちが解決したかった課題と似た状況にある開発メンバーの方、事業責任者の方にとっては有用である可能性もあります。以下で課題感とそれに対するアプローチ、そして1年経って結果そのアプローチはどうだったか？をまとめていければと思いますので、よろしくお願いします。

## Tailwind CSS導入の経緯

去年、事業のCSS設計を既存のコーディング規約から見直し、Tailwind CSSを導入しました。導入にあたり考慮した内容に関しては[去年の記事](https://note.com/kazkiueda/n/n1492a2746155)を参考にしていただければと思います。

私たちは以下のような効果を生み出すことで、**コーディングの際のデザイナーの煩わしさや難しさを減らすことで事業内での制作の選択肢を増やせないか？**というのをテーマとして掲げました。

結果、実装メンバーとレビュワーの責任を明確にして、ミスへの恐怖心を減らすことができるようになったかなと思います。

### 開発・レビューの際の影響範囲の明確化
コーディングに関して発生するミスのうち、約90％は下記の２つでした。

#### タイポなどの凡ミス
- 打ち間違い、意図しない削除 など
    - コードレビュー時にChangesとして確認できるので、本番リリースまでに止まることがほとんど
        - 致命的なミスになりにくい

#### （共通セレクタなどで）観測範囲外での変更に気づけなかった
- 影響範囲の判断ミス、見落としなど
    - 確認箇所が漏れていると、誰も気づけない
        - 本番リリース時に気づくなど大きなミスになりやすい

凡ミスに関しては目視確認によってほとんどのケースでリリースが止まりますが、観測範囲外で問題が起きると検証自体が抜けるため、リリース作業完了後に発覚し切り戻しということになりかねません。

またもちろんミスは起きてほしくないことなので、弊社ではそのようなミスが起こった際に振り返りをして対策を講じてきましたが、今までデザイナーのミスに関しては運用ルールの厳格化で乗り切ってきたところがあり、それ故に次回以降検証に慎重になり、実装ペース自体も落ちていってしまうという課題がありました。この課題が後述する**コーディング規約（ドキュメント）の低減、仕組み化**にも繋がってきます。

このようなミス防止のアプローチとして弊社でもVisual Regression Testing (以下VRT)の導入が進んでおり、こちらにより根本的なミス発生の防止を進めると同時に、Tailwind CSSの導入とscssへの記述の原則廃止により、作業での影響範囲の明確化と削除のしやすさを担保することで、リファクタリングをカジュアルにできる環境を作りたいと思っていました。

### マークアップの際の設計力の平準化
CSSはハードルが低いが故にミスも起こりやすく、現在に至るまでさまざまな設計手法が提唱されています。そういった設計手法は先人の知恵で私自身も大きな恩恵を受けてきたし素晴らしいなと思うのですが、特に事業会社で日々高速でサービス改善の施策を回していて思うのは、CSSは**誰かがルールを破ると途端に壊れる**ということでした。これは**新任メンバーに仕事を移譲しにくい**ということでもあります。

コーディング規約の遵守がおぼつかないメンバーに仕事を任せる際は、レビュワーにも大きな負担がかかるため、「じゃあ自分でやろう」となりがちですが、これでは一向にメンバーがコーディング業務を行えません。

そこで、弊社コーディング規約でのCSS設計（BEM）ではどのような課題を解決しているのか分解してみました。

* Block,Element,Modifierによって、スタイルの状態を表す
* 優先度、名前の衝突回避
* その他BEMだけでは解決できないケースへの対応ルール

これならばユーティリティファーストな設計+部品のコンポーネント化でも実現できそうだし、CSSの設計も必要なさそうです。さらに命名規則や上書きルールなど弊社独自のルールも必要なさそうです。

このように**コーディング以外に強みのあるメンバーの余計な心配を減らし、さらにレビュワーの心理的なプレッシャーを減らすことで、タスクをアサインする際の選択肢を増やすことができないか**と思っていました。

### コーディング規約（ドキュメント）の低減、仕組み化
前述したように不具合の再発防止策や不具合の起きにくいような運用ルールを作っていった結果、割としっかりした規約になったのですが、**新任のOJTにだんだん時間がかかるように**なったり、**外部パートナーへ依頼する際の作業コストが高すぎる**ことが問題になりだしました。さらに、ルールを守るとそれなりに時間がかかるが故に、ルールを守らないケースも散見されるようになりはじめました。事業内で頑張ってくれてるメンバーの気持ちになるとなかなか頭の痛い問題です。

ただ、どれだけしっかりとした規約でも事業の中で軽んじられたり恣意的に運用されている時点で、機能しているとは言い難いですよね。

なので、今回の変更で**ルールを増やさざるを得ない要因を排除することによって運用ルールの確認をできるだけ減らす**ということをしたいと思っていました。

## 現状、どのような開発手法か？
Tailwind CSSでの設定をベースとした制作スタイルが確立されています。

### Figma
Tailwind CSSのデフォルト設定を元にデザインをできるように、プリセットを準備しています。
![スクリーンショット 2021-12-13 16.58.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155482/6e9bd2e5-14be-e339-1079-119da9578197.png)

### VS Code
Tailwind CSS IntelliSenseやESLintによって、ユーティリティクラスの検索や自動並び替えをしています。

### コーディング規約
**「一部イレギュラー時には責任者に確認」「子コンポーネントでは余白を持たない」以外のルールは撤廃**し、各コンポーネントやテンプレートファイルへのユーティリティクラスへの記述で記述している箇所以外の検証が必要ない状況を作っています。
複数回出現するパーツに関してはコンポーネント化し、CSSでの共通部品化はしないことにしています。

## 1年運用してみてどうだったか？
### 課題は解決できたのか？
8割ぐらいは解決できたのではないかなと思います。少なくとも「新人メンバーに実装を問題が起こりにくく、見つけやすい」ところまでは持っていけたと思います。

#### 開発・レビューの際の影響範囲の明確化
概ね負債の元を排除できていると感じます。特にレビュワー側の負担が大きく減ったことにより結果として高い品質を担保しやすくなったことが要因です。

課題感として、**HTMLからはクラスが削除されているがCSSの削除が抜けているケース**を起きにくくしたいというのがありました。これはCSSの削除の必要性がChangesからは判断できないことが原因でしたが、現在の運用ではHTMLタグの削除=CSSの削除となるので無くなりました。CSSのコピペやまずいCSS設計など将来的に負債になりそうな実装に関しても、現段階では仕組みによって防げていると感じています。

以前ならベースとなる部品をコピーしてきて作りたい時に、CSSの命名だったり考えないといけないことが多かったし、それ故に検証に慎重にならざるを得ないケースがあったのですが、今はHTMLだけコピーすれば良いし、改変もHTMLの編集だけで済むので怖さがないですしレビューも単純明快です。作業を他のメンバーにどんどん渡せるという好循環が生まれており、こちらは想定通りで上手く行っています。

#### マークアップの際の設計力の平準化
物理的にCSS設計そのものをとっぱらったわけなので、作業依頼のハードルは下がりました。

ただユーティリティクラスだといってもコーディングには変わりがないので、その点でレビューの打ち返しが0になったわけではありませんが、「クラス命名」と「CSS設計」が無くなったことにより打ち返しの大部分が無くなり、その結果経験が浅いメンバーをアサインできるようになってきました。

ユーティリティクラスを覚えるのがめんどくさそうという声もありましたが、チートシートをみながら作業してもらうことで問題は起きていません。
https://tailwindcomponents.com/cheatsheet/

しかし、Tailwind CSSでのコーディングは制約を設ける作業になるので、ケースによっては素のCSSで書くよりも難しく感じることもあるようで、ここは課題かなと思います。とはいえ、1年前よりやれることも増えて本当の意味でユーティリティクラスのみで書けるようになりつつあります。
https://tailwindcss.com/docs/installation

#### コーディング規約（ドキュメント）の低減、仕組み化
これは明らかに減りました。

実質「一部イレギュラー時には責任者に確認」以外のルールはなく、また設定自体が守ってほしい規約となっているので、基本的に好きにコーディングしてもらっています。また、細かなページ間の余白などに関しては、コードレビューではなくデザインレビューが持つべき責務だと判断し、デザインレビュー時に確認するようにしています。

## 新たに取り組みたい課題
この1年半ほどの間の取り組みによって一旦当初の目的は達せられましたが、新たな課題も出てきています。来年はこのような課題に対してもアプローチしていきたいなと思っています。

### コンポーネントでのマークアップの際の検証コストの低下
コンポーネント単位での開発によってDRYにユーティリティクラスを書くことが可能になったのですが、同時にコンポーネントの拡張に際しての設計やメディアクエリのみでのスタイルの変更に限界を感じつつあります。できれば仕組み的に解消したい部分なのですが、特に既存コンポーネントの拡張に関しては、実装する前に方針確認をする、ぐらいしか対策が見つかっていません。

メディアクエリの問題に関しては、有望なものとして[Container Queries](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries)がありますが、プロジェクトに導入するには時期尚早な気もします。

対策として、Reactコンポーネントに関してはコンポーネントの幅に応じてスタイルを変化させるカスタムフックを自作し、現在効果検証中です。

### Tailwind CSSのバージョンアップの際のメンテナンスを自分以外もできるようにする
デザイナーの中で自分以外に困った人をフォローできるようになれば、もう少し導入しやすくなるなと思っているので、そこは課題です。

## 何のための課題解決か？
この一年間、さまざまな試行錯誤によって事業におけるデザイナーの開発における課題には一旦アプローチできたかなと思います。しかし、これは事業のためになっているのでしょうか？

事業における開発体験の向上は、何の為に必要なのでしょうか？

私は、**顧客に提供する価値を向上させるために使える時間を最大化する**ことだと思います。
雑務や待ち時間といった「非生産的な時間」を少しでも減らし、サービスをよくすることにたくさん時間を割けるようにすることだと思います。

規約の見直しや技術選定は、その課題解決の一構成要素にすぎません。

そういった意味では、私たちの取り組みは「不具合防止」や「リファクタリング」といった本来顧客へ提供する価値の向上から少しずれた業務を一定の割合減らすことには成功したのかなと思います。これからの改善の際にも**顧客と向き合う時間を増やせているか？**と自問自答しながら業務改善を続けたいと思います。

# さいごに
1年を振り返ってみて、実装フローの改善に一定の効果は出ましたが、お話しした通り今回の施策は**顧客と向き合う時間を増やす**ことができるようになっただけではダメで、業務効率化がサービス改善にちゃんと生かされなければば意味がないと思っています。今回作れた時間でより一層顧客と向き合っていければと思います！