[CSS設計] ITCSSとは

日本国内であまり言及のない CSS 設計手法である ITCSS(Inverted Triangle CSS)について基本情報を記述する。

TL;DR

  • CSS を実装上の問題点
  • ITCSS とはどういうアーキテクチャなのか
  • ITCSS が CSS 実装への課題へどういうアプローチをしているか

CSS の問題

CSS の仕様(グローバルスコープや詳細度)により、スタイル定義は複雑化しやすく破綻しやすい。

  • カスケードと継承
  • ソースの順番に大きく依存する
  • 詳細度

CSS の定義において、ソースの記述順と詳細度は非常に重要である。これらの関係性が複雑になっていくと、既存定義を上書きするためにまた新しい定義をしていく必要がでてきてしまい、多くの無駄や冗長性が発生し、破綻してしまう。

詳細度の解決方法

── CSS を詳細度順で書く。

コードの記述順をいきあたりばったりで記述していくとする。そうすると、下記の図のように詳細度(山なりになっている箇所)が意図しない部分で現れていき、あとから対応をしていく度にコードの複雑さが増してしまう。複雑性が増したコードの場合、コードの末端で上書きしたつもりでもコードの先頭部分での定義の詳細度が強いケースなどもあり得る。

悪い記述順

対して、コードを詳細度を意識した順番で記述していくとする。そうすると、下記のように当然詳細度は徐々に上がっていく形になる。あとから対応が必要な場合、別の場所の詳細度に影響を受けずに後述していけば良くなり、コードの見通しも良くなる。

良い記述順

大まかにいえば、ITCSS はこの詳細度での記述順を可視化するための枠組みである。

ITCSS

ITCSSは、CSS のための健全でスケーラブルに管理されたアーキテクチャである。

ITCSS とは何か

  • 逆三角形の CSS アーキテクチャ
  • 健全でスケーラブルな管理されたアーキテクチャ
  • ライブラリではなく、考え方の流儀
  • メタフレームワークであり、フレームワークのためのフレームワーク
    信じられないほどシンプル
ITCSS 逆三角形

CSS のスタイル定義を詳細度の広い順に記述(階層化)することを提唱している。その記述が逆三角形として視覚化されるため、この呼び名となっている。

レイヤー

ITCSS には、デフォルトで下記の 7 つの種別(レイヤー)で分類する。

  1. Settings
  2. Tools
  3. Generic
  4. Base
  5. Objects
  6. Components
  7. Trumps
ITCSSの構造

必要に応じてレイヤーを追加や削除ができる。

  • CSS プリプロセッサを利用していない場合、SettingsToolsなどのレイヤーを削除しても良い
  • OOCSS を使用していなければObjectsレイヤーを削除しても良い
  • テーマ性が必要であればThemeレイヤーを追加しても良い

レイヤーの原則として、上位レイヤーを下位レイヤーが上書きできるような実装になっていなければ良い。そのため、プロジェクトに応じて必要なレイヤーを継ぎ足しすることも問題ない。

Settings

プリプロセッサなどで利用するグローバル変数や全体の設定を置く(SASS 変数や CSS Variables の定義)。

$font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
  "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
  "Segoe UI Symbol", "Noto Color Emoji" !default;

$color-ui: #bada55;
$spacing-unit: 10px;

Tools

プリプロセッサで利用するmixinfunctionなどの定義を置く。

@function str-replace($string, $search, $replace: "") {
  $index: str-index($string, $search);

  @if $index {
    @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index +
            str-length($search)), $search, $replace);
  }

  @return $string;
}

@mixin font-brand() {
  font-family: "UI Font", sans-serif;
  font-weight: 400;
}

Generic

リセットスタイル(normalize.css など)や固有のリセットスタイル定義を置く。低詳細度、広範囲に当たる初期のスタイルを定義する。

@import "~normalize.css/normalize.css";

* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

Base

素の HTML 要素(a, h1…6, ul…li など)のスタイルを定義する。クラスセレクターなどは使用せず、要素セレクターのみで定義する。

ul {
  list-style: square outside;
}

※ Base ではなく Elements という記述の資料もあるが、提唱者の資料をみると Base のようであった

Objects

OOCSS(Object Oriented CSS)の概念に基づいた定義をする。装飾を持たないレイアウトを定義する。

.ui-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.ui-list__item {
  padding: $spacing-unit;
}

Components

名前の付けられた明確なコンポーネント(UI パーツ)を定義する。

.products-list {
  @include font-brand();
  border-top: 1px solid $color-ui;
}

.products-list__item {
  border-bottom: 1px solid $color-ui;
}

Trumps

ヘルパー・ユーティリティ系のスタイルを定義する。1 つの DOM にのみ影響するものに焦点を置いて定義する。明示的なスタイル定義(テキストの中央寄せ等)などスコープがもっとも狭い定義になる。

.one-half {
  width: 50% !important;
}

最下層のレイヤーであるため、 ID セレクターや!importantの定義が許容される。

レイヤーの特徴

  • 詳細度はレイヤーが下位へいくごとに増す
  • 一度に DOM のより小さな部分に影響を与えていきます
  • 下のレイヤーを上のレイヤーが上書きすることはしない

ITCSS の成果

  • すべてのコードを置く場所がある
  • 人々は、どこを見ればどんな種類のルールがあるか分かる
  • 健全なソースの順序
  • 無駄を省き、冗長性を高める
  • スケーラビリティの向上
  • 詳細度戦争が終わる

参考