CSS Methodology
LismがどのようなCSS設計になっているかを説明します。
CSSの階層構造
詳細度が複雑になりがちな問題への対策として、LismではCSSの階層構造を明確に定義しています。
Layer | 役割 | @layer 基本詳細度 |
---|---|---|
Settings | SASSの設定変数, mixinなど直接スタイルに吐き出されないもの。 | - |
Reset | reset CSS | @lism-reset ~0-0-1 |
Base | :root でのトークン定義, HTML要素に対するスタイルの初期セット | @lism-base ~0-0-1 |
Layout State | レイアウト,デザインを組む上での特定の役割を持ち、複数のモジュールに対してつけ外しできるようなもの。 | @lism-layout 0-1-0 |
Layout Module | 基礎的なレイアウトを組むためのモジュール群。 | |
Dynamic Module | JavaScriptと組み合わせた動的な機能を持つモジュール群 | |
Atoms | 単体で具体的な役割を持つコンポーネント群 | @lism-layout 0-1-0 |
Blocks | ||
Components | ||
Utility Class | その他、機能やスタイルが明確なユーティリティクラス。 | @lism-utility 0-1-0 |
Props Class | 単一のCSSプロパティティに紐づいたクラス。 | 0-1-0 |
詳細度の値は、@layer
を使わない場合の目安数値です。
デザイントークン
タイポグラフィ、余白、カラー、シャドウなど、主要なプロパティに対して段階的なプリセット値やセマンティックなキーワードでCSSカスタムプロパティを定義しています。
トークンを流用することで、サイトを通してデザインに一貫性が生まれ、使用しているプロパティの意図も第三者が読み取れるようになります。
あとからサイト全体を微調整する必要が出てきてもトークンの値を変更するだけでよくなり、メンテナンス性も高まります。
詳しくはトークン解説ページを参照してください。
クラス設計
Lismでは、レイアウト・デザインの構成要素を細分化していくつかの種類に分類しています。
State クラス
分類 | 形式 | 例 |
---|---|---|
Layout State 状態として付け外しできるようなデザイン機能を持つもの | .is|has--{stateName} | .is--flow , has--divider |
Temporary State js操作等によって付け外しされるようなクラス | .-{state} | .-active , .-opened |
Layout State はそれ単体でスタイルを持ち、Temporary State はそれ単体ではスタイルを持ちません。
Module クラス
分類 | 形式 | 例 |
---|---|---|
Layoutレイアウトの構成単位となるようなモジュール | .l--{name} | .l--grid |
DynamicJSと組み合わせた動きのあるモジュール | .d--{name} | .d--tabs |
Atomコンテンツの構成要素としてそれ以上分割できない要素 | .a--{name} | .a--icon |
Blockシンプルな役割を持つ要素 | .b--{name} | .b--button |
Componentその他のコンポーネント | .c--{name} | .c--card |
Blocks はAtom,Layoutクラスで構成されるような粒度((他のBlock,Componentが内部に入らない規模)で、Componentは Layout,Atom,Block 等で構成されるような粒度でイメージしてください。
子要素を持つ場合
子要素も含めて一つのモジュールとして機能するものは、BEMでの Element にあたる文字列をクラスに付け加えます。
- 形式:
.c--{componentName}__{elementName}
- 例:
.c--hoge__item
バリエーションスタイル(Modifier) を用意する場合
モジュールのバリエーションスタイルを定義する場合、BEMでの Modifier を付け加えたクラスを作成します。
- 形式:
.{prefix}--{name}--{variant}
- 例:
.b--button--outline
基本的には元となる.{pefix}--{name}
も併記し、CSSコードの重複を避けるようにして運用します。
Prop クラス
特定のCSSプロパティに対応するユーティリティクラスを定義しています。
基本的にはそれぞれのクラスが単一のCSSプロパティをコントロールするためのになっています。(一部、例外もあります。)
Prop クラス には以下の3種類の形式があります。
形式 | 説明 | 例 |
---|---|---|
.-{prop}:{token|value} | トークンや主要な値を利用するためのユーティリティクラス(*1) | .-fz:l , .-ta:c |
.-{prop}: | 変数 --{prop}: を受け取るためのクラス(*2) | .-p: , .-fz: |
.-{prop}[:|@bp] | 変数 --[bp-]{prop} を受け取るためのクラス(*3) | .-p@sm , .-p@md |
*1: 全てのトークンにユーティリティクラスがデフォルトで用意されているわけではありません。
*2: 全てのCSSプロパティに対応するクラスがデフォルトで用意されているわけではありません。
*3: ブレークポイントに対応したクラスがデフォルトで用意されているものは一部のプロパティのみです。
.-ta\:c { text-align: center; }.-fz\:l { font-size: var(--fz--l); }
.-p\:{ padding: var(--p); }@container (min-width: 480px) { .-p\@sm\:{ padding: var(--sm-p); }}@container (min-width: 720px) { .-p\@md\:{ padding: var(--md-p); }}
(厳密には少し異なるものもありますが、イメージとしてはこんな感じです。)
レスポンシブ対応
直前に紹介した.-{prop}[:|@bp]
形式のクラスと--[bp-]{prop}
形式の変数によって、レスポンシブ対応を行います。
BOX
<div class="-p:20 sm_p: md_p: -bd:" style="--sm-p:var(--s30);--md-p:var(--s50);"> BOX</div>
その他の推奨規則
Lismパッケージに内蔵されているクラスではありませんが、次のような感じで命名すると統一感でると思います。
分類 | 形式 | 例 |
---|---|---|
ゾーニング | .z--{zoneName} | .z--header ,.z--sidebar ,.z--article |
ページの分類 | .p--{type}--{id|slug} | .p--front ,.p--archive ,.p--post--{id} ,.p--page--{slug} |
ユーティリティ | .u--{utilityName} | .u--hoge |
コンテナクエリ
Lismはコンテナクエリを標準で採用しています。
ブレイクポイントで値を切り替えるには先祖要素でコンテナ要素を定義する必要があります。
Lism でコンテナ要素を配置するには、.is--container
(<Container>
)が便利です。
ブレイクポイント
ブレイクポイントはモバイルファーストで定義しており、数値としては480px~1200pxまでの240px刻みで設定しています。
サイズ表記 | デフォルトの設定値 |
---|---|
sm | width >= 480px |
md | width >= 720px |
lg | width >= 960px |
(xl ) | width >= 1200px |
(xlサイズのサポートは別途SCSSの設定ファイルの上書きが必要)
これらの定義済みポイントは、SCSSであれば次のようにして簡単に利用できます。
@use '../path/to/node_modules/@lism-ui/core/scss/query' as query;
@include query.cq('sm') { // your styles...}
命名規則
…
補足事項
その他の補足事項を説明します。
単語の省略について
基本的にはEmmetの省略形 で統一するようにしています。
font-size
→fz
background-color
→bgc
text-align:center
に対応するクラス →.-ta:c
Emmet で明確に定義されていないものは、それっぽく省略しています。
object-fit
→obf
row-gap
→rowg
place-self
→pslf
また、次のように例外 (Emmetと違うもの、Emmetっぽくないもの)もあります。
colg
: (column-gap
)- Emmet では
colmg
だが、column
→col
,columns
→cols
とLism全体で揃えている。
- Emmet では
aslf
,jslf
- Emmet では
as
,js
になるがas
は Lism Prop と被り、js
は javascript が思い浮かぶので、少し変形しています。
- Emmet では
-fxw:nw
(flex-wrap:nowrap
)- Emmetに従えば
fxw:n
だが、whs:nw
(white-space: nowrap
) と揃えています。
- Emmetに従えば