2014年9月18日
MediumのCSSはこの上なく最高!
(2014-08-28)by fat
本記事は、原著者の許諾のもとに翻訳・掲載しております。
本エントリは翻訳リクエストより投稿いただきました。
ありがとうございます!リクエストまだまだお待ちしております!
自分は常に最高であれって思っている。最高の香りを身にまとい、最高の振る舞いをする。ごみ1つ捨てるのだって、ほかの誰よりイカしてなきゃ。
―Lil Wayne
最高傑作の自画像
ずっと長いこと恥も外聞も知らずに、MediumでCSSについて執筆しようと思っていました…。
それからどうなったって? 違うことをやっていた? 何てこと、どうやったら同じことができるかって? やり方を教わりたいって?
これから書くことは私たちのCSSについての覚書で、これまでに歩んできた道のりと現在のCSSについて述べています。
始まり(これまでの道のり)
だいたい2年ほど前、私はソフトウェアアプリケーション開発と(皆さんが読んでくれているといいのですが) medium.com に取り組むためにObvious Corp.に加わりました。
その時、Mediumは、すでに一連の”スタイル更新”を行っていました( スタイル更新とは
デザイナが過去に考え出したものよりも、より勝るものを思いついたことで、結果的に、CSS/LESS/SASSなどを書き直すということです )。スタイル更新が原因で、古いものが多く生み出されることになり、同社は、ページを運用するセマンティクスや、Spriteされていない/Retinaに対応していない画像アセットやそれ以外のものにおいて、LESSの言語的機能に偏っていました。
私はgitを使って、何とか2012年(ゾッとしますね)まで、さかのぼったプロフィールページを引き戻すことに成功しました。以下を見てみれば、やりきれないパターンに気づくと思います。
- すべてが. profile-page クラス以下にネストされていて、再利用可能なコンポーネントがゼロである(またほとんどすべてが. profile で始まっている)。
- @link-color のような一般的な総称名が使われていた。おそらく profile-page.less だけで使われていた。
- コードのネストが深い( .profile-page .profile-posts .home-post-summary .home-post-collection-image img は下位で発生しているセレクタであり、パフォーマンスが悪い)。
- Sprite画像がない。
- z-indexスケール、フォントスケール、カラースケール、スケールがない…。 https://gist.github.com/fat/a4af78882d0003d2345e
第1プロジェクト:OMG画像
当時、私はライブラリコード(Bootstrap、Ratchetなど)に取り組んでいて、可能な限り最高のCSSを記述しようと全力を注いでいました。
MediumのCSSは明らかに違っていました。何とかなるレベルの違いではなく、壊滅的な違いがそこにはありました。私はそれを直したかったのです。
全体を見て、最初に私が取り組んだのは画像でした。私たちが2012年に、Spriteを何も施していなかったことにかなり愕然としたのを、私は覚えています…。蓄積された何百という画像アセット、例えばプレースホルダ、矢印、アイコンなど、まるでアイコンの墓場のように/img/ディレクトリがあふれていました。
そんな現状を打開するために、私は2つのことをしました。1つ目はSUSと呼ばれる、ちょっとしたCSSのユーティリティスクリプトを書きました(SUSは今でも使っているので、ここでオープンソースが手に入ります( https://github.com/medium/sus )。これはGuillermo Rauchの助けを借りて主にIRCで書かれたものです。スタイルシートから画像を抽出して、それを独立したdata-uriファイルで遅延読み込みするために使用します。オリジナルコンセプトではなく、私たちが目指す方向へ進むための手助けとなり得るシンプルなコンセプトです。
2つ目はGeoff Teehanと私が腰を落ち着けて、Mediumの最初のアイコンフォントを作成したことです。当時、私たちは何をすべきか、全く分かりませんでした…。しかしIcoMoon、GitHubについて書かれたブログからヒントを受け、長い夜を過ごした後、私たちは、なかなかいいMediumアイコンを作成できたのです。これは大きな意味を持ちました。というのも、私たちはimgフォルダのほぼ97%を削除したのです。フォントは私のMacBook Pro Retinaディスプレイモデルでの見栄えもばっちりでしたし、使うリソースを大幅に減らせるようになりました。
第2プロジェクト:スケール
次の主要なプロジェクトは、z-indexスケールでした。z-indexは、すぐに手に負えなくなり、常にイライラさせられる曲者です。Mediumでは同じであってほしくありませんでした。
このプロジェクトが始まる前は、ある要素が z-index: 5 で、隣の要素は z-index: 1000000; 、さらに z-index: 1000001; や z-index: 99999; の要素もあるといった状況は実によく目にしました。
こうしたスタイルはコードベースの至る所で使われており、これらをソートするための名案は思い浮かびませんでした。
そのため、私はz-indexの値についてコードベース全体を手作業で調べるという骨の折れる仕事を行うことにしました。それから、コンポーネントにz-index(1~10に限定)を付ける時に用いるプライベートなスケール(z-index.lessの中でのみ有効)を導入しました。そして最終的に、このスケールによる実際の割り当てをすべてz-index.lessの中に移したため、さまざまなコンポーネントが互いにどのように位置付けられているかが分かるようになりました(これは実際、かなり便利です)。
下記は現在medium.comで使っているz-indexファイルです(訳注:gistリンク)。
https://gist.github.com/fat/1f6da6b3bd0311a1f8a0
もちろん、このz-indexスケールの次にはすぐ、カラースケール(ブラック、グレー、ホワイト、ブランドカラーなどに対する変数)やタイプスケール(フォントサイズ、太さ、文字間隔、行の高さなどに対する変数)を定めました。
また、変数名がより厳密でセマンティックになっていることに気づくかもしれません。この点については後述します。
第3プロジェクト:新たなスタイルガイド
Mediumにスケールを導入して程なく、私たちは新たなスタイルのコード”Cocoon”を作るという大きな作業に取り掛かりました。
Cocoonでは、いくつかの投稿テンプレート(Mediumにはもともと、単一の記事テンプレートだけでなく、画像テンプレートや引用テンプレートもありました)を旧式とし、投稿”カード”の代わりに投稿リストの仕組みも導入しました。
私たちはこれを、一歩下がってMediumの新たなスタイルガイドを作る機会だと捉えたのです。
このことに初めに取り組んだのは、私とDave Gamache、Dustin Senos、そして有能なChris Erwinでした。
私たちは、Mediumで実際のCSSやLESSを書くということに関して、考えを固めるのに時間をかけました。主に更新した点は次のとおりです。
- LESSを変数とミックスインに限定(ネスト、ガード、エクステンドなどは禁止): 言語のこのような機能は確かに強力になり得るが、経験の浅いLESS開発者にとってはしばしば問題の種になりやすいことが分かった。私たちはまた、純粋なCSSが提供する視覚的な美しさ(と一貫性)を優先したいと考えており、コードベースを無理のない範囲でできるだけその方向へ移行したかった。
- クラスとIDは小文字の単語をダッシュで連結: これは、私たちの多くがBootstrap、Skeleton、Ratchetなどを使ってCSSを書いていた時のやり方であり、ここでも同様にすることが理にかなうと考えた。もう1つの理由は、これがCSS言語自体で使われている命名法に従っているということである。例えばborder-radius-top-leftなど。
- ページレベルのスタイルよりもコンポーネントを優先: 私たちは、フロントエンドをライブラリコードのようにしたいと考え、profile.lessのようなファイルを、もっと細かな目的に合わせたbutton.less、dialog.less、tooltip.lessなどのファイルに分割する作業を始めた。
以下に全体を掲載します(訳注:gistリンク)。
https://gist.github.com/fat/b27700946c777adacdf4
決して完全ではありませんが、いくつかの基本概念を整理し、正しいと感じられる方向を示す指針となりました。
ですが残念ながら、このスタイルの更新のあとでさえ、いつコンポーネントを作るべきか、いつサブコンポーネントを作るべきか、といったことを考えるのに人々は苦労しているようでした。そして時々、目的のはっきりせず、単語を連ねただけの. nav-on-light-background-button や. button-primary-sidebar-over-blur のようなクラス名が付けられていました。
ページレベルでクラスにプレフィックスが付けられることはなくなりました(これは素晴らしいことです)が、その代わりに、任意の単語がダッシュで長々とつなぎ合わされるようになりました。例えば、. button → . button-primary → . button-primary-dark → . button-primary-dark-container → . button-primary-dark-container-label のように、うんざりするほど名前が長くなっていくのです。
第4プロジェクト:今後を見定める
大体この頃、世界一になるんだという壮大な目標を持って、私はCSSについて実にたくさんのことをMediumの内部で書き始めました。それが何を意味するのか本当はあまり分かっていませんでしたが、私たちのその時の方向性がどうもうまくいっていないことは分かっていました。
人々は困惑していました。さらに悪いことには、実際はそうでないにもかかわらず、みんな自分はとてもうまくCSSを書いていると思っていたのです。
そこで、私はいろいろ見てみることにしました。フレームワークを探したり、さまざまなツールを試したり、理念について調べたり、友人と話をしたり、友人の友人と話をしたりしました。そしてまもなく、私たちのCSSを望ましいと思われる形に変えるためには、主に3つのプロジェクトに取り組む必要があると特定したのです。
- 1.長々と続くクラス名を避けて読みやすさの向上を図るため、CSSの変数、ミックスイン、クラス名の新たなセマンティクスを導入する。
- 2.LESSの代わりに Rework を使ってより強力にミックスインを活用できるようにし、シンタックスをよりvanilla CSSに近づける。
- 3.CSSのパフォーマンスに関するツール(load time、fps、layout timeなど)を加えることでスタイルの変更や回帰をより簡単に突き止められるようにする。
第5プロジェクト:セマンティクス
コードベースにおいてセマンティクスをより厳密にしたいと思いました。なぜなら、私たちのチームの規模では、そうすることで基礎となるルールを作るのがより簡単になると感じたからです。また、人々が新しいCSSのクラスを作る時に、より気を配らなくてはならなくなるとしても、やや複雑にしたほうが良いと思いました。何が何でも長々と続くクラス名をなくしたいと考えていましたが、それができなくてもせめて作りにくくはしたかったです。
このことについてDaryl Koopersmithと良き友人であるNicolas Gallagherと詳しく話しました。
Nicolasと私にはおもしろい交友関係があります。Nicolasが私に言う事に対して私は間違ってると反論し、フランス語で悪口を言うんです(馬鹿や間抜けなど)。そして数週間そのことについて避けていたら、私は必ず彼は間違っていなかったと気づきます。そして彼のアイディアを自分のものにするんです。
今回も同じでした。数日後、最終的にNicolasが SUITCSS で書いたものと似たスタイルを使うのが良いと確信しました。似ているけどわずかにですが、より優れたものです。
そこで私はNicolasを徹底的に参考にすることから始めました。古いスタイルガイドを捨て、彼が書いたものを大量にコピーしあちこちを少しずつ編集したんです。
そうして今のスタイルガイドが完成したのです。以下に全体を示しますが、主に付け加えたものです。
- .javascriptセレクタに依存する要素となるクラス名にプレフィックスとして.js-を付ける。
- .u-underlineや.u-capitalizeといったように1つの目的を持ったユーティリティクラスのクラス名にプレフィックスとして.u-を付ける。
- ハイフンやキャメルケースに意味づけをし、コンポーネントと子孫コンポーネント、そして修飾子の分離を強調する。
- .is-disabledのようなstatefulクラス(jsでよくトグルになる)にプレフィックスとして.is-を付ける。
- 新たなCSSの変数のセマンティクス: [property]-[value]–[component]
- ミックスインでpolyfillのみを使用するようにしたら、プレフィックスとして.m-を付ける。
https://gist.github.com/fat/a47b882eb5f84293c4ed
スタイルガイドをコピーして貼り付けるやり方とCSSアプリケーションをすべてリライトするやり方は別物です。
ただ自己満足したいという気持ちもありましたが、ありがたいことに、このプロジェクトの重要性を会社に納得してもらうことができました。そしてMedium.comのCSSをリライトするために2週間半が与えられました。これは以前ブログにも書いた CSSの下線を直すプロジェクト に掛けた時間よりも短い期間でした。
このリライトはただCSSのコードをきれいにするだけでなく、大量にある古いスタイルの排除やサイト全体にわたる実装の効率化と一般化、ファイルのサブコンポーネント単位への細分化を行います。そして、驚くことにわずかなロールバックしか起こさないのです。
もちろんCSSのリファクタリングはテンプレートのリファクタリングにもなります。全面的にカプセル化や厳密なセマンティクスを増やします。今日では、例えばランダムなavatarクラスでたった1度しか機能しない大量の <IMG>
タグを使用するより、1つにまとめたavatarテンプレートを使用する方がやりやすくなります。その方法はサイズやスタイルなどの異なる修飾子をbooleanオプションを受け取って使用します。こうすることでスタイルの更新が簡単になり、実装してからバグが発生する頻度が下がります。
第Xプロジェクト:今後は?
間違いなく2年前より環境が良くなりました。MediumでCSSを書くのは実際にとても楽しいですし、開発者は様々な経験を得て素晴らしい製品をいくつも開発しています。
次のCSSプロジェクトはパフォーマンスについてになるでしょう。私たちはプロジェクトの新たなページを刻み続け、次の段階へと進めていきます。なんとも正確で信頼性の高いレイアウトを測定するツールを想像してみてください。そしてレンダリングのパフォーマンスは非常に重要です。しかし残念ながら2014年の現在ではまだ完成していません。
なので、まだまだやることはたくさんありますが、今のところはとても気分がいいです。それもいつも以上にです。
こんな長くてつまらない投稿を最後まで読んでくれてありがとうございます。
Katie、Dave、Mark、Koop、Kristopher、Nicolasそしてプロジェクト(そしてMediumのCSSを直すこと)をおそらく意識していなかったでしょうが手助けしてくれた方々に感謝を述べます。
株式会社リクルート プロダクト統括本部 プロダクト開発統括室 グループマネジャー 株式会社ニジボックス デベロップメント室 室長 Node.js 日本ユーザーグループ代表
- Twitter: @yosuke_furukawa
- Github: yosuke-furukawa