📘

Lism CSSとは?CSS設計理論の概要

に公開
2

2025年 6月 11日、Lism CSS という CSSフレームワークを ver.0.1 として β リリースしました。

https://www.lism-css.com/

この Lism CSS の設計について、その概要を解説していきたいと思います。
TailwindCSSがデファクトスタンダードとなっていますが、ぜひ新しい選択肢として検討いただけたら幸いです。

はじめに

WEBサイト制作において、CSS設計は永遠の課題ですよね。
Lism CSS」は、この課題に対する新しい解決策として開発された、軽量でモダンな CSS フレームワークです。

独自のCSS設計理論をreset.cssレベルから構築しており、デザイントークン・レイアウトモジュール・CSSプロパティ単位のユーティリティクラスを組み合わせて、WEBサイト全体を支える骨組みとして機能します。

Every Layout、TailwindCSS、Bootstrap など既存の優れたフレームワークの長所を取り入れています。

Lismの主軸はあくまで設計理論のため、Lism CSS は、ビルド処理や設定が不要でも使えるようになっています。 CSSファイルを読み込むだけでも利用できるため、素の HTML サイトはもちろん、HTMX や WordPressにも導入できます。(WordPressでは、WordPress側のCSSを取り除いたりする処理が別途必要にはなってきます)

とはいえ、lism-cssパッケージからReactコンポーネント(またはastroコンポーネント)を使ってもらった方が確実に便利になっているので、ぜひそちらを活用いただけたらと思います。

導入方法

CDN 経由での利用

スタイルシートをCDNから読み込む
<link href="https://cdn.jsdelivr.net/npm/lism-css/dist/css/main.css" rel="stylesheet" />

※: アコーディオンやタブは、別途追加でscriptの読み込みが必要です。(CDNで配布してるので読み込むだけです)

npm パッケージとしての利用

さらに、React、Astro、Next.js などのモダンな開発環境では、専用のコンポーネントを使ってより快適に開発できるようにもなっています。

パッケージのインストール
npm install lism-css
プロジェクトにて
// CSSをグローバルにインポート
import "lism-css/main.css";

// 必要なファイルでコンポーネントをインポート
import { Box, Stack, Flex, Grid, ... } from "lism-css/react";

Lism CSS の特徴

1. レイヤー階層による明確な CSS 設計

Lism CSS では、CSS の階層構造を明確に定義することで、詳細度の複雑化を防いでいます。

レイヤー 役割 @layer
Reset reset CSS @lism.reset
Base トークン定義、HTML 要素のスタイル @lism.base
Layout State 汎用的なレイアウト機能 @lism.state
Layout Module 基礎的なレイアウトモジュール @lism.layout
Dynamic Module 動的な機能を持つモジュール @lism.dynamic
Components 具体的な役割を持つコンポーネント @lism.component
Utility Class 機能が明確なユーティリティ -
Props Class 単一 CSS プロパティに紐づくクラス -

この階層構造により、CSS 設計の見通しが良くなり、長期的なメンテナンスが容易になります。

2. レイアウトファースト + ユーティリティクラス

Lism CSS は「レイアウトファースト」な設計思想を採用しています。基本的なレイアウトはモジュールクラスで組み、装飾的な部分はユーティリティクラスで補完します。

<!-- レイアウトモジュール + ユーティリティクラス -->
<div class="l--stack -g:20 -p:30 -bgc:base-2">
  <h2>見出し</h2>
  <p>コンテンツ...</p>
</div>

3. デザイントークンによる一貫性

カラー、スペース、タイポグラフィ、シャドウなど、主要なプロパティに対して段階的・またはセマンティックなプリセット値を CSS 変数として定義しています。

/* スペーストークン(フィボナッチ数列ベース) */
--s10: 0.375rem;
--s20: 0.625rem;
--s30: 1rem;
--s40: 1.625rem;
--s50: 2.625rem;
...

/* カラートークン */
--c-base: #ffffff;
--c-text: #333333;
--c-main: #0066cc;

/* 倍音列に基づくフォントサイズ */
--fz-4xl: calc(1em * var(--_fzmol) / (var(--_fzmol) - 5));
--fz-3xl: calc(1em * var(--_fzmol) / (var(--_fzmol) - 4));
--fz-2xl: calc(1em * var(--_fzmol) / (var(--_fzmol) - 3));
--fz-xl: calc(1em * var(--_fzmol) / (var(--_fzmol) - 2));
--fz-l: calc(1em * var(--_fzmol) / (var(--_fzmol) - 1));
--fz-m: 1em;
--fz-s: calc(1em * var(--_fzmol) / (var(--_fzmol) + 1));
--fz-xs: calc(1em * var(--_fzmol) / (var(--_fzmol) + 2));
--fz-2xs: calc(1em * var(--_fzmol) / (var(--_fzmol) + 3));

これらのトークンを活用することで、サイト全体のデザインに一貫性が生まれ、後からの調整も容易になります。

トークン一覧ページはこちら

4. CSSプロパティごとのユーティリティクラス

Tailwindcss のように、特定のCSSプロパティとその値の組み合わせについて、主要なものを-{prop}:{value}という形式で定義しています。
Lism では、これらを Propクラスと読んでいます。(Utility クラスはまた別であります。)

.-d\:n { display: none }
.-p\:10 { padding: var(--s10) }
.-px\:20 { padding-inline: var(--s20) }
.-fz\:l { font-size: var(--fz-l) }
.-ta\:c { text-align: center }
.-bxsh\:20 { box-shadow: var(--bsxh-20) }

Propクラス一覧はこちら

5. 独自のレスポンシブ対応

Lism CSS の最も特徴的な機能の一つが、CSS 変数とクラスを組み合わせたレスポンシブ対応です。

先ほど紹介した Propクラス の派生クラスとして、-{prop}_{bp}という形式のレスポンシブ対応用のクラスを定義しています。

.-p{ padding: var(--p); }

/* @sm ~ */
@container (min-width: 480px) {
  .-p_sm{ padding: var(--p_sm); }
}

/* @md ~ */
@container (min-width: 720px) {
  .-p_md{ padding: var(--p_md); }
}

(全てのCSSプロパティに対して用意されているわけではありませんが、SCSSで読み込む場合はカスタマイズで増やすことも可能)

例えば、padding を 20 → 30 → 50 と切り替えるには次のようにします。

html
<div class="-p:20 -p_sm -p_md -bd" style="--p_sm:var(--s30);--p_md:var(--s50)">
  <p>Example</p>
</div>

上記は専用コンポーネントを使えば、より簡潔に記述できます:

jsx
<Lism p={[20, 30, 50]} bd>
  <p>Example</p>
</Lism>

コンテナクエリの採用

Lism CSS では、コンテナクエリをデフォルトで採用しています。これにより、親要素のサイズに応じた柔軟なレスポンシブデザインが可能になります。

また、ブレイクポイントは、特定のデバイスサイズに依存しない 240px 刻みで設定されています:

  • sm: width >= 480px
  • md: width >= 720px
  • lg: width >= 960px(オプション)
  • xl: width >= 1200px(オプション)

主要なレイアウトコンポーネントの例

主要なレイアウトモジュールを、いくつか紹介します。

Flex (l--flex)

Flexboxで横並びレイアウトを実現します。

jsx
<Flex fxw='wrap' jc='center' g='20'>
  <div>Flex Content</div>
  <div>Flex Content</div>
  <div>Flex Content</div>
</Flex>
html
<div class="l--flex -g:30 -jc:c">
  <div>Flex Content</div>
  <div>Flex Content</div>
  <div>Flex Content</div>
</div>

Grid (l--grid)

Grid レイアウトを組み立てるコンポーネントです。

jsx
<Grid gtc={['1fr 1fr', '1fr 2fr']}>
  <Box p='30' bgc='blue:20%'>A</Box>
  <Box p='30' bgc='purple:10%'>B</Box>
</Grid>
html
<div class="l--grid -gtc -gtc_sm" style="--gtc:1fr 1fr;--gtc_sm:1fr 2fr">
  <div class="l--box -p:30 -bgc:mix" style="--_bgc1:var(--blue);--_mixpct-bgc:20%">A</div>
  <div class="l--box -p:30 -bgc:mix" style="--_bgc1:var(--purple);--_mixpct-bgc:10%">B</div>
</div>

Center (l--center)

内部の要素を上下左右中央揃えで配置するためのコンポーネントです。

jsx
<Center g='10' ar='3/2' lh='xs'>
  <Text fz='l'>TEXT</Text>
  <Text fz='s'>Lorem ipsum dolor sit amet.</Text>
</Center>
html
<div class="l--center -g:10 -ar:3/2 -lh:xs">
  <p class="-fz:l">TEXT</p>
  <p class="-fz:s">ロレムイプサムの座り雨。</p>
</div>

Columns (l--columns)

指定した列数でカラムレイアウトを作成できるコンポーネントです。

jsx
<Columns cols={[1, 2, 3]} g='30'>
  <Lism bgc='base-2' p='30'>Box1</Lism>
  <Lism bgc='base-2' p='30'>Box2</Lism>
  <Lism bgc='base-2' p='30'>Box3</Lism>
  <Lism bgc='base-2' p='30'>Box4</Lism>
  <Lism bgc='base-2' p='30'>Box5</Lism>
  <Lism bgc='base-2' p='30'>Box6</Lism>
</Columns>
html
<div class="l--columns -g:30" style="--cols:1;--cols_sm:2;--cols_md:3">
  <div class="-bgc:base-2 -p:30">Box1</div>
  <div class="-bgc:base-2 -p:30">Box2</div>
  <div class="-bgc:base-2 -p:30">Box3</div>
  <div class="-bgc:base-2 -p:30">Box4</div>
  <div class="-bgc:base-2 -p:30">Box5</div>
  <div class="-bgc:base-2 -p:30">Box6</div>
</div>

WithSide (l--withSide)

メディアクエリやコンテナクエリに依存せず、維持したいコンテンツの長さを基準にして横並びと縦並びの切り替えを行うことができる2カラムレイアウトを作成できます。

jsx
<WithSide sideW='12rem' mainW='20rem' g='30'>
  <Box p='20' bd bdc='blue'>
    <p>Main Content</p>
    <Dummy />
  </Box>
  <Box data-is-side p='20' bd bdc='red'>
    <p>Side Content</p>
  </Box>
</WithSide>
html
<div class='l--withSide -g:30' style='--sideW:12rem;--mainW:20rem'>
  <div class='l--box -p:20 -bd' style='--bdc:var(--blue)'>
    <p>Main Content</p>
    <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit, sed do eiusmod tempor. Non facere laudantium ex eos doloribus aut dolore nisi.</p>
  </div>
  <div class='l--box -p:20 -bd' style='--bdc:var(--red)' data-is-side='true'>
    <p>Side Content</p>
  </div>
</div>

Utility クラスの例

レイアウトというよりデザイン的な装飾を担う機能は、u--ではじまるユーティリティクラスを定義して利用ます。

Utilityクラス一覧はこちら

u--cbox

--keycolorで指定したキーカラーをベースに、ボックスをカラーリングするユーティリティクラスです。

jsx
<Lism className='u--cbox' keycolor='blue' p='30'><Dummy length='codes' /></Lism>
<Lism className='u--cbox' keycolor='red' bd p='30'><Dummy length='codes' /></Lism>
<Lism className='u--cbox' keycolor='purple' bd bdc='keycolor:base:25%' p='30'><Dummy length='codes' /></Lism>
<Lism className='u--cbox' keycolor='#688f04' bd='is' bdw='4px' p='30'><Dummy length='codes' /></Lism>
html
<div class='u--cbox -p:30' style='--keycolor:var(--blue)'>...</div>
<div class='u--cbox -bd -p:30' style='--keycolor:var(--red)'>...</div>
<div class="u--cbox -bd -bdc:mix -p:30" style="--keycolor:var(--purple);--_bdc1:var(--keycolor);--_bdc2:var(--c-base);--_mixpct-bdc:25%">...</div>
<div class='u--cbox -bd:is -p:30' style='--keycolor:#688f04;--bdw:4px;'>...</div>

u--clipText

color:transparentbackground-clip:textを適用して、テキストで背景をくり抜くためのユーティリティクラスです。

jsx
<Center>
  <Box className='u--clipText' bg='linear-gradient(45deg, var(--blue), var(--pink))'>
    <Text fz='5xl' fw='900' lts='l'>TEXT</Text>
  </Box>
</Center>
html
<div class="l--center">
  <div class="l--box u--clipText -bg" style="--bg:linear-gradient(45deg, var(--blue), var(--pink))">
    <p class="-fz:5xl -fw:900 -lts:l">TEXT</p>
  </div>
</div>

u--outerR & u--innerR

親要素の角丸とPaddingの値から、内側の要素の角丸を計算するユーティリティペアクラスです。
親要素(u--outerR)に p(--p), bdrs(--bdrs) の指定が必須となります。

jsx
<Lism className='u--outerR' p='20' bd bxsh='20' bdrs='50'>
  <Frame className='u--innerR'>
    <Media ar='ogp' src='/img/img-4.jpg'/>
  </Frame>
</Lism>
html
<div class="u--outerR -p:20 -bd -bxsh:20 -bdrs:50">
  <div class="l--frame u--innerR">
    <img class="-ar:ogp" src="/img/img-4.jpg">
  </div>
</div>

足りないクラスは、どんどん足していってください

lism-cssパッケージで配布しているCSSファイルに内包されているPropクラスについては、容量が大きくなりすぎないように、主要なプロパティとその値の組み合わせを厳選しています。

Components層(@lism.component)も定義はしていますが標準では何もクラスは入っていません。

Lismの設計に則り、足りないクラスは適宜追加してご利用ください。

コンポーネントの設計例もいくつか公式ドキュメントに載せていますので、コピペしてカスタマイズしてみてください。

(もちろん全部をクラス化する必要もなく、局所的にしか使わないものはstyle属性に書いてもいいと個人的には思っています。)

まとめ

Lism CSS は、モダンな CSS 機能(@layer、コンテナクエリ、CSS 変数)を積極的に活用しながら、シンプルで使いやすいフレームワークとして設計されています。

  • 軽量:必要最小限の CSS で、約30KB〜から利用可能
  • 柔軟:レイアウトモジュールとユーティリティクラスの組み合わせで自由度の高いデザインが可能
  • 保守性:明確な階層構造とデザイントークンにより、メンテナンスコストを削減
  • 汎用性:ビルド不要で、あらゆる環境で使用可能
  • 拡張:サイトごとに追加で必要なCSS・クラスを自由に追加

WEBサイト制作の効率化と品質向上を求めるコーダーにとって、Lism CSS は強力なサポーターとなります。

少しクセが強く学習コストも高めですが、慣れてくればとても直感的に使用できるようになります。
1ミリでも気になった方は、ぜひ一度、詳細な公式ドキュメントをご覧ください。


リポジトリ: https://github.com/lism-css/lism-css
ライセンス: MIT

Githubでスターをポチッと押していただけるだけでも励みになります!

使ってみて何かご意見ご感想等ありましたら、ここのコメント欄か、もしくはDiscordサーバーに参加して投げていただけますと非常に嬉しいです。

Discussion

junerjuner

コンテナクエリでは、レスポンシブに値を切り替えるには先祖要素でコンテナ定義をしておく必要があることに注意してください。

これは 小さなビューポート単位として利用できるのでは……?

クエリに該当するコンテナーが利用できない場合、コンテナーのクエリー長の単位は、既定でその軸の小さなビューポート単位 (sv*) に設定されます。

https://developer.mozilla.org/ja/docs/Web/CSS/CSS_containment/Container_queries#コンテナークエリーの長さ単位

了

コメントありがとうございます。すみません、私が書いた”コンテナ定義しておく必要がある”というのはcontainer-type: inline-size;を宣言しておかないとコンテナサイズの利用がうまく利用できない、という意味でした。cqiとかはそれがなくともsv*の値が入ってくると思いますが、@container (min-width: 480px)などのコンテナクエリでプロパティ切り替えようとすると、意図した動作になりませんので注意が必要です...という内容の文言でした(省略しすぎて申し訳ないです)