Studyplus Engineering Blog

スタディプラスの開発者が発信するブログ

Studyplus for SchoolのCSS事情

こんにちは。ForSchool事業部の石上です。最近、弊チームのスクラムマスター id:atomiyama さんから、「伝えにくい事とか相手の注意引きたい時に幼児言葉を使うと有効です。」というテクニックを教えてもらいました。今後はなるべく実践していきたいでちゅ 👶

今日は、Studyplus for SchoolのCSS事情について書かせてもらいます。

以前に書いたやりたいことベースでWebpackにCSS周りの設定をする - Studyplus Engineering Blogとだいぶ重複する部分もありますが、今回はWebpackのloaderの話ではなく、なにが欲しくてなにを使っているのかという形式で整理していきたいと思います。

ちょうど最近 id:tagucch さんがうちのチームに異動してきてくれたので、 id:tagucch さんへの説明も兼ねています。

CSSのためにいろいろ道具が必要になる背景

本題へ入る前に、そもそもなぜCSSを書くために余計な道具が必要となるのでしょう。CSSはブラウザが解釈できる言語なので、そのまま書いて配れば動くはずです。

しかし欲を出して、ちょっとでもCSSを書きやすくするためにはいろんなツールを入れる必要があります。

それらを今回改めて紹介していければと思います。

変数がほしい

CSSでは、セレクタ(画面内の要素)を指定して見た目を当てることができるわけですが、何度も同じスタイルを当てるのは大変です。なので、HTMLのclass属性に名前を指定してうまいこと管理することで繰り返しを避けられるわけですが、その指定だけでは管理しづらいこともあります。

たとえば、色コードです。そのサービスのブランドカラーのような色コードは、いろんなところで使うことがあります。テキストの色だったり、ボタンの背景色だったりします。

.primary-color-text {
  color: #008080;
}
.primary-color-button {
  background: #008080;
  color: #fff;
}

color, backgroundとそれぞれプロパティの種類は違いますが、当てたい色コードは同じです。CSSで変数が使えると以下のように書けます。

:root {
  --primary-color: #008080;
}
.primary-color-text {
  color: var(--primary-color);
}
.primary-color-button {
  background: var(--primary-color);
  color: #fff;
}

これはいいですね。名前がつくことで、色コードの意味を開発者が覚える必要もなくなりますし、変更を入れたいときも一箇所で済みます。

ただ、この記法はまだサポートされていないブラウザもあります。

このコードが使えないブラウザのために代替の手段が必要で、それが今のところはSassというツールです。Sassの変数を使えば、上記とほぼ同じように書けます。

$primary-color: #008080;
.primary-color-text {
  color: $primary-color;
}
.primary-color-button {
  background: $primary-color;
  color: #fff;
}

関数がほしい

変数と同じく、関数もあると嬉しいです。似たようなプロパティをまとめられて、使うところで少しだけ変えられると、とても便利です。ただ、これはCSSでは書けません。

Sassを使うと、以下のようにmixinというものを定義できます。たとえば、スクリーン幅をみて当てるスタイルを変えたいとき、以下のようなものを定義しておくと、各所で長ったらしいメディアクエリを書かずに済んで便利です。

/* mixin */
@mixin max-screen($break-point) {
  @media screen and (max-width: $break-point) {
    @content;
  }
}
/* 使うとき */
@include max-screen(768px) {
  width: 50%;
  /*...*/
}

スコープがほしい

Reactを使ってアプリケーションを作っているとUIの部品をコンポーネントと呼び、汎用的にするべしという風潮があります。実際そうしたほうが、繰り返し同じようなものを実装しなくて済むので幸せになれます。

そうすると、できれば見た目の定義もそのスコープに閉じ込めたくなります。そこで出てくるのがCSS Modulesです。

import * as styles from './styles.scss';

const Button = (props: Props) => {
  return (
    <button className={styles.root}>{props.children}</button>
  )
}
.root {
  background: $primary-color;
  /* ... */
}

Webpackのloader、css-loaderでCSS Modulesの設定をするとこのように書けるようになります。.rootは、ビルド時にアプリケーション内で衝突しない文字列に置き換えられるので、クラス名の衝突を気にせず短いクラス名でCSSを書けます。Button/styles.scssの.rootは、Buttonコンポーネントのスコープに閉じられています。

型がほしい

Studyplus for Schoolのフロントエンド側のコードはTypeScriptで書いているため、エディタ補完のありがたみを感じながら開発をしています。CSS Modulesを利用して、TypeScript側からクラス名を参照できるようになっているので、型もついているとなお嬉しいですね。className={styles.とタイピングしたら、指定できるclass名が補完されてほしい。

これには、Quramy/typed-css-modulesを利用して、CSSの型を生成して使っています。

まとめ

こんな感じで現状だといろいろ使っているのですが、個人的にはなるべく依存するツールは減らしていきたい気持ちがあります。いつかCSSだけで快適に書けるようになったらいいなと思いつつ、そうなるまでは必要なものを選んで使って、いらなくなったら捨ててというのをちゃんと繰り返していければいいかなと考えています。

これもう不要じゃん! とかこっちのほうがいいぞ! みたいものを見つけたときはどんどん変えていきたいのでご指摘もらえると嬉しいです! 👶