こんにちは、弥生 Misoca チームでマークアップをする方のデザイナー @kanizmb です。
今回、約1年をかけて古の Bootstrap の撤去および CSS 設計手法の導入(FLOCSS 化)をやり遂げたので、これらの変更をどのように進めていったかについてお話しします。
どういった状況だったか
Misoca ローンチは 2011年、当時最新であった Bootstrap 2.3.2 を用いて構築が始まりました。(*1)
当初は請求書の郵送に特化した非常にシンプルなサービスだったため、少しの上書きでスムーズに開発が進められ、Bootstrap のメリットを存分に生かせていたのだと思います。
しかし時は流れ、取引先管理、品目管理、外部サービスとの連携など、機能が増え続けるとどんどん綻びが出始めます。 設計方針もないままに野放図に差し込まれた CSS たちは、いつしか激しい詳細度バトルを繰り広げるようになります。
たとえば、コードで示すとこのような内容です。(コードはイメージです)
/* Bootstrap */ h2 { font-size: 20px; margin: 20px 0; } /* アプリ汎用スタイルを上書き */ .page-A, .page-B, .page-C, .page-D { #main { h2 { padding-bottom: 10px; border-bottom: 1px solid #eee; } } } /* 特定のページの一部を上書き */ .page-A { .team-member { h2 { margin-top: 30px; padding-bottom: 0 !important; border: none !important; } } } /* 特定のコンポーネント用に上書き */ .modal { h2 { margin: 0 !important; padding-bottom: 20px !important; } }
スコープが広い Bootstrap のスタイルを、全体用のスタイルで上書き、さらにそれらをページごとのスタイル・コンポーネントのスタイルで上書きしているため、 !important
や冗長な指定が山盛りになっていました。
新しくスタイルを追加するにはこれら既存のスタイルに打ち勝つ必要があり、さらに混沌を極めます。 こうなってしまうと容易に手が出せる状態ではありません。
これらの根本的な負債解消のために、デザイナー主導で CSS 改善プロジェクトを立ち上げて対応することにしました。
まずは相手を知る
嘆いていてもなにも始まらないので、まずは現存するファイル・スタイルの用途や影響範囲を調べていきます。
現状のディレクトリごとにスプレッドシートを作成し、既存の各ファイルがどこでどのように使われているか大まかに記入します。
調査の過程で過去の担当者からの叫び(FIXMEコメント)が多数発掘され、使命感が高まります。
FLOCSS 化
改変後の CSS 設計手法は、FLOCSS を採用しました。 後発の手法で導入事例も多く、日本語のドキュメントもあり、今後のチーム開発でルールや作法の共有がスムーズに行えると判断したためです。
(FLOCSS の具体的な設計手法の解説は公式ドキュメントやそれ以外にたくさん記事があるため、ここでは省略します)
作業に入る前に CSS 改善担当者間で FLOCSS 提唱者である谷 拓樹さんの「柴犬でもわかるFLOCSS」を読み合わせて認識の統一をしたのち、以下の手順で進めました。
STEP1. FLOCSS ルールに沿ってディレクトリ分類
先のファイルごと用途調査を元に、既存のファイルを FLOCSS のルールに沿ったディレクトリに分類していきます。1つのファイルで分類がまたがるスタイルが混在するものもありましたが、ここでは細かな点は一旦無視しています。
この段階ではまだ微妙なバランスの上に成り立っているスタイルが多いため、ファイルの移動により読み込み順が変わって表示崩れが起こらないか、慎重に確認しながら少しづつ移動しました。
なお、1ファイルで用途が多岐に渡る巨大な汎用ファイルについては保留にして触らずに置いておきます。
STEP2. FLOCSS ルールに沿った命名変更とスタイルの整理
大まかな分類が終わったら、各ファイルごとに記述されているスタイルがどこでどのように使われているかをスプレッドシートに書き出し、新しい命名や分類を検討しました。
新しい命名・分類では以下の点に配慮しています。
- HTML の構造に依存しすぎない
- スコープが絞り込まれていない状態で要素セレクタを使用しない(foundation は除く)
- BEM (MindBEMding) を使用し、名前から影響範囲や役割が想像できるようにする
- 今後の HTML 構造の変更や機能の追加に耐えられるよう、詳細度をなるべく低く抑える
たとえば以下のような変更です。
/* before */ body.team { .member-list { ul { ... } } } /* after */ .p-team-member__list { ... }
命名変更とあわせて他と共通化できる部分は統合し、重複するもの、似ているけど微妙に異なるもの、不要になっていたスタイルもバッサリと整理・削除しました。
この時、見た目が似ているからといって何も考えずに統合すると後から困る可能性があるため、その要素の性質や今後のデザイン方針を踏まえた変更でなければなりません。 このあたりはデザイナーが直接担当していることで、シームレスに判断しながら作業を進められました。
ユーティリティスタイルの併用
変更前のスタイルは要素セレクタが多用されるなどでスコープが広いスタイルが多く、整理の際にこちらを立てるとあちらが立たずといった場面がとても多くありました。
このような谷を埋めるためにマージンやフォントサイズ、色や配置指定のためのユーティリティスタイルを用意しました。
わずかな差はこのユーティリティスタイルで吸収しながら、コツコツ整理していきます。
自前の CSS コンポーネントへの置き換え
CSS 改善と並行して、ボタンやタブ、フォーム・ページングなどを Bootstrap のものから、自前のコンポーネントスタイルに置き換えるプロジェクトも動いていました。
この作業によって、アプリで使用されていた Bootstrap の CSS コンポーネントはすべて自前のスタイルに置き換えられました。 こちらの取り組みについて、詳しくは以下の記事にあります。
Bootstrap 撤廃
FLOCSS 化と自前のコンポーネントへの置き換えが終わった後、Bootstrap 用の CSS はほとんど用済みになっていました。 不要なものは削除し、どうしても必要なものは FLOCSS 分類したディレクトリに移し変えてすべての関連ファイルを削除します。
なお、JS 部分は別途フロントエンドチームが全て削除してくれています!
CSS 改善を支える仕組み
CSS 改善プロジェクトは非エンジニア2名によるプロジェクトだったため、リソース不足や技術的な壁にぶつかる懸念もありましたが、実際のところほとんど支障なく進行出来ました。
主な理由は以下の3点です。
高速・高品質コードレビュー
CSS のレビューはなかなか手をつけづらく滞りがちなものですが、Misoca ではレビュー待ち数を増やさないよう所属プロジェクトを問わず協力し合ってレビューし合う体制があるため、CSS 改善の PR も例外なくスムーズにレビューが通っていました。 この際、単純な見た目の違いはもちろん特別な操作を行った時にだけ表示される部分や、他の箇所との整合性までしっかり見てもらえます。
レビューや巻き戻しをしやすくするために PR を小さめに分けていた都合で後続の作業に影響が出やすい状況でしたが、全く困ることがありませんでした。
金曜PR13個出して帰ったら、月曜午前中に全部きっちりレビューされてほぼLGTMが2以上ついてる弊社すごい(ありがたや〜)
— カニ (@kanizmb) March 16, 2020
遊軍チームのサポート
デザイナーがリファクタリングを担当する事で、リファクタリングに伴うデザイン変更の細かな判断や今後の変更を前提とした設計がスムーズになる一方、動的な UI の変更や複雑な spec 修正が絡む変更はどうしてもやりきれない部分が出てきます。
こんな時、気軽に声をかけられるのがこぼれタスクを専門に扱う「遊軍」チームです。
「テスト通らない助けて〜」「やります!」と、気負わず相談できる環境にはとても助けられました。
最後の砦 ビジュアルリグレッションテスト
影響範囲の広いスタイルの移動や削除・命名変更では思わぬ差分が出てしまうことがあります。 リリース前にこれらの差分をとらえてくれるのが、ビジュアルリグレッションテストです。 変更前後のスクリーンショットを比較して、前後で差分が出ていないか検証してくれます
アプリ全体で微妙なズレまで拾ってくれるので、きちんと意図通りに変更されているかをしっかり確かめてから安全にリリースができました。
Bootstrap 撤廃 & FLOCSS 化 を終えて
よかったこと
!important
地獄からの脱却- 設計・命名ルールが定まり、どこにどう書くかを判断する基準が出来た
- 適用範囲が明確になり、変更や削除をあまり気を使わずに出来るようになった
- component の再利用性が高まって、新しくスタイルを書く量が減った
- HTML 側に書かれた class 名からスタイルがどのファイルに書かれているかすぐにわかり、grep して探さなくて良くなった
- 令和になっても Boostrap 2.3.2 を使っている負い目から解放された
気になること
- まだ判断に迷う部分がある
- project に置くか、component に置くか
- Modifer として扱うか、
.is-xxx
のような補助的な名前にするか
- BEM の Block 粒度のばらつき(特に project 内)
- 大きいものだとページ(Rails の Controller)単位だけど、コレジャナイ感
- BEM で命名が長大になってしまう場合の対処
- Block の中で Element が入れ子になる場合、みんなどうしているんだろう…?
今後やってみたいこと
- 現在部分的に導入している Scoped CSS を利用した Vue コンポーネント化範囲の拡張
まだまだ改善の余地はあると感じますが、ひとまず各スタイルが HTML の構造や他のスタイルと疎結合になり、今後新たな方針で進めるにしても舵を切りやすくなったと思います。
約1年をかけてコツコツ進めてきた CSS 改善がやっと形になって、感慨もひとしおです。(膨大すぎる作業を支えてくれたパートナースタッフの @riszw に感謝!)
宣伝
Misoca ではつらくない CSS 環境で開発を進めたいエンジニア・デザイナーを募集しています。
-
正確に言うと 2系が出たのは 2012年1月なので、ローンチ初期の段階は適宜アップデートしていて、ある時期に固定されたものと思われます。(追記)Misoca創業者の証言によるとローンチ時は1系で、1〜2年後に2系にアップデートされたとのことです。↩