1. Open Propsとは
Open Propsは、CSS変数(カスタムプロパティ)ベースのCSSフレームワークです。従来のBootstrapやTailwind CSSとは異なり、「コンポーネント」を提供するのではなく、デザインシステムの構築に必要な「CSS変数」のコレクションを提供します。
特徴
- デザイントークンを提供: 色、サイズ、アニメーション、シャドウなど、様々なデザイン要素をCSS変数として提供
- 非指示的(Non-prescriptive): スタイルの適用方法を強制せず、自由度が高い
- 一貫性のあるデザイン: 標準化されたデザイントークンにより、統一感のあるUIを作成可能
- インクリメンタルな採用: 必要な部分だけを選んで使うことができる
- カスタマイズ可能: プロジェクトの要件に合わせて変更可能
State of CSS 2023では、Tailwind CSSを抑えて人気No.1のCSSフレームワークとなりました。
2. インストールと導入方法
CDN経由での利用
HTMLやCSSファイルにCDN経由でインポートするだけで使用できます。
<!-- HTMLでの読み込み -->
<link rel="stylesheet" href="https://unpkg.com/open-props"/>
<!-- オプションの機能拡張 -->
<link rel="stylesheet" href="https://unpkg.com/open-props/normalize.min.css"/>
<link rel="stylesheet" href="https://unpkg.com/open-props/buttons.min.css"/>
または、CSSファイル内でインポートする場合:
/* メインのスタイル変数 */
@import "https://unpkg.com/open-props";
/* オプションのコンポーネント */
@import "https://unpkg.com/open-props/normalize.min.css";
@import "https://unpkg.com/open-props/buttons.min.css";
/* 特定のカテゴリだけをインポート */
@import "https://unpkg.com/open-props/colors.min.css";
@import "https://unpkg.com/open-props/sizes.min.css";
npm経由でのインストール
プロジェクトにnpmを使用している場合は、以下のコマンドでインストールできます。
npm install open-props
インストール後、CSSファイルでインポートします:
/* メインのスタイル変数 */
@import "open-props/style";
/* オプションのコンポーネント */
@import "open-props/normalize";
@import "open-props/buttons";
/* 特定のカテゴリだけをインポート */
@import "open-props/colors";
@import "open-props/sizes";
3. 主要な機能と変数
Open Propsは多岐にわたるデザイン要素をカバーしています。ここでは主要なカテゴリを紹介します。
カラー
/* グレースケール */
--gray-0, --gray-1, ..., --gray-12
/* 基本色 */
--red-0, --red-1, ..., --red-12
--blue-0, --blue-1, ..., --blue-12
--green-0, --green-1, ..., --green-12
/* その他多くの色 */
サイズ
/* 基本サイズ */
--size-1, --size-2, ..., --size-15
/* 流動的なサイズ(レスポンシブ対応) */
--size-fluid-1, --size-fluid-2, ..., --size-fluid-10
タイポグラフィ
/* フォントサイズ */
--font-size-1, --font-size-2, ..., --font-size-8
--font-size-fluid-1, --font-size-fluid-2, --font-size-fluid-3
/* フォントウェイト */
--font-weight-1, --font-weight-2, ..., --font-weight-9
/* モダンフォントスタック */
--font-sans, --font-serif, --font-mono
--font-system-ui, --font-transitional, --font-old-style
/* 他多数 */
アニメーションとイージング
/* イージング関数 */
--ease-1, --ease-2, ..., --ease-5
--ease-in-1, --ease-in-2, ..., --ease-in-5
--ease-out-1, --ease-out-2, ..., --ease-out-5
/* 他多数 */
/* アニメーション */
--animation-fade-in, --animation-fade-out
--animation-slide-in-up, --animation-slide-out-down
/* 他多数 */
シャドウ
/* 外側シャドウ */
--shadow-1, --shadow-2, ..., --shadow-6
/* 内側シャドウ */
--inner-shadow-0, --inner-shadow-1, ..., --inner-shadow-4
メディアクエリ
PostCSSプラグインを使用することで、名前付きメディアクエリも利用可能です:
@custom-media --portrait (orientation: portrait);
@custom-media --landscape (orientation: landscape);
@custom-media --md-only (480px <= width < 768px);
@custom-media --md-n-above (width >= 768px);
@custom-media --md-n-below (width < 768px);
4. 実践的な活用例
基本的なコンポーネントのスタイリング
カードコンポーネントのスタイリング例:
.card {
background: var(--surface-2);
border: var(--border-size-1) solid var(--surface-3);
border-radius: var(--radius-2);
padding: var(--size-4);
box-shadow: var(--shadow-2);
transition: transform 0.2s var(--ease-3);
}
.card:hover {
transform: translateY(var(--size-1-negative));
box-shadow: var(--shadow-3);
}
.card__title {
font-size: var(--font-size-4);
margin-bottom: var(--size-3);
color: var(--text-1);
}
.card__description {
font-size: var(--font-size-2);
color: var(--text-2);
line-height: var(--font-lineheight-3);
}
ダークモード対応
Open Propsを使うと、ダークモード対応が簡単です:
/* ライトモード(デフォルト) */
:root {
--brand: var(--brand-light);
--text-1: var(--text-1-light);
--text-2: var(--text-2-light);
--surface-1: var(--surface-1-light);
--surface-2: var(--surface-2-light);
}
/* ダークモード */
@media (prefers-color-scheme: dark) {
:root {
--brand: var(--brand-dark);
--text-1: var(--text-1-dark);
--text-2: var(--text-2-dark);
--surface-1: var(--surface-1-dark);
--surface-2: var(--surface-2-dark);
}
}
これにより、コンポーネント側では単に var(--text-1)
や var(--surface-1)
といった変数を使うだけで、自動的にテーマに応じた色が適用されます。
レスポンシブデザイン
流動的なサイズを使用することで、簡単にレスポンシブデザインを実現できます:
.hero-title {
font-size: var(--font-size-fluid-3);
padding: var(--size-fluid-2);
max-width: var(--size-content-3);
}
.content {
display: grid;
gap: var(--size-fluid-1);
}
アニメーションの活用
.fade-in {
animation: var(--animation-fade-in) forwards;
animation-duration: 0.5s;
animation-timing-function: var(--ease-3);
}
.button {
transition: transform 0.2s var(--ease-out-3);
}
.button:hover {
transform: scale(1.05);
}
5. フレームワークとの統合
Next.jsでの使用方法
Next.jsのApp Routerを使用する場合:
- Open Propsをインストール:
npm install open-props
- グローバルCSSファイル (
app/globals.css
) で変数をインポート:
/* メインのスタイル変数 */
@import "open-props/style";
/* オプションのコンポーネント */
@import "open-props/normalize";
@import "open-props/buttons";
:root {
/* カスタム変数の上書き */
--blue-6: #1e40af; /* 例:プライマリカラーの上書き */
}
- ルートレイアウト (
app/layout.tsx
) でCSSをインポート:
import './globals.css';
export default function RootLayout({ children }) {
return (
<html lang="ja">
<body>{children}</body>
</html>
);
}
- CSSモジュールでOpen Propsを活用:
/* Button.module.css */
.button {
border-radius: var(--radius-2);
padding: var(--size-2) var(--size-4);
background-color: var(--blue-6);
color: var(--gray-0);
font-weight: var(--font-weight-5);
transition: background-color 0.2s var(--ease-3);
}
.button:hover {
background-color: var(--blue-7);
}
VS Codeでの開発効率化
VS Codeでの開発効率を高めるには、以下の拡張機能と設定が役立ちます:
- CSS Var Complete 拡張機能をインストール
.vscode/settings.json
に以下の設定を追加:
{
"cssvar.files": [
"./node_modules/open-props/open-props.min.css"
],
"cssvar.ignore": [],
"cssvar.extensions": [
"css", "postcss", "jsx", "tsx"
]
}
これにより、CSS変数の入力補完が効くようになります。
6. 実践的なプロジェクト例
ブログサイトのデザインシステム構築
ブログサイトの主要コンポーネントをOpen Propsで構築する例:
/* 基本テーマ設定 */
:root {
--brand: var(--indigo-6);
--text-1: var(--gray-9);
--text-2: var(--gray-7);
--surface-1: var(--gray-0);
--surface-2: var(--gray-1);
--surface-3: var(--gray-2);
--link: var(--indigo-7);
--link-visited: var(--purple-7);
}
/* ダークモード */
@media (prefers-color-scheme: dark) {
:root {
--brand: var(--indigo-3);
--text-1: var(--gray-1);
--text-2: var(--gray-3);
--surface-1: var(--gray-9);
--surface-2: var(--gray-8);
--surface-3: var(--gray-7);
--link: var(--indigo-3);
--link-visited: var(--purple-3);
}
}
/* ベースレイアウト */
body {
font-family: var(--font-sans);
color: var(--text-1);
background-color: var(--surface-1);
line-height: var(--font-lineheight-3);
}
/* タイポグラフィ */
h1 {
font-size: var(--font-size-fluid-3);
font-weight: var(--font-weight-7);
line-height: var(--font-lineheight-1);
max-width: var(--size-header-2);
}
h2 {
font-size: var(--font-size-fluid-2);
font-weight: var(--font-weight-6);
line-height: var(--font-lineheight-1);
}
p {
font-size: var(--font-size-2);
max-width: var(--size-content-3);
}
a {
color: var(--link);
transition: color 0.2s var(--ease-3);
}
a:hover {
color: var(--brand);
}
/* コンポーネント */
.blog-card {
display: grid;
gap: var(--size-3);
padding: var(--size-4);
border-radius: var(--radius-2);
background-color: var(--surface-2);
box-shadow: var(--shadow-1);
transition: transform 0.2s var(--ease-3), box-shadow 0.2s var(--ease-3);
}
.blog-card:hover {
transform: translateY(var(--size-1-negative));
box-shadow: var(--shadow-3);
}
.button {
background-color: var(--brand);
color: var(--gray-0);
padding: var(--size-2) var(--size-4);
border-radius: var(--radius-2);
font-weight: var(--font-weight-5);
transition: background-color 0.2s var(--ease-3);
}
.button:hover {
background-color: var(--indigo-7);
}
7. CSS設計との組み合わせ
Open Propsは、単なるCSS変数の集合であるため、既存のCSS設計手法と組み合わせて使用できます。
BEMとの組み合わせ
/* BEMの命名規則とOpen Propsの組み合わせ */
.card {
background-color: var(--surface-2);
padding: var(--size-4);
}
.card__title {
font-size: var(--font-size-4);
color: var(--text-1);
}
.card__content {
color: var(--text-2);
}
.card--featured {
background-color: var(--brand);
color: var(--gray-0);
}
CSSモジュールとの組み合わせ
CSSモジュールはOpen Propsとの相性が特に良く、カプセル化されたスタイルとグローバルなデザイントークンの良いバランスを提供します。
/* Button.module.css */
.button {
background-color: var(--brand);
padding: var(--size-2) var(--size-4);
border-radius: var(--radius-2);
}
.primary {
background-color: var(--blue-6);
}
.secondary {
background-color: var(--purple-6);
}
import styles from './Button.module.css';
function Button({ children, variant = 'primary' }) {
return (
<button className={`${styles.button} ${styles[variant]}`}>
{children}
</button>
);
}
8. パフォーマンス最適化
必要な変数だけをインポートする
すべての変数を一度にインポートするのではなく、必要な変数だけをインポートすることでパフォーマンスを向上させることができます。
/* 全変数のインポート(避けるべき) */
@import "open-props/style";
/* 必要な変数だけをインポート(推奨) */
@import "open-props/colors";
@import "open-props/sizes";
@import "open-props/animations";
PostCSS JIT Propsプラグインの使用
postcss-jit-propsプラグインを使用すると、実際に使用されている変数だけをスタイルシートに含めることができます。
npm install postcss-jit-props
postcss.config.js:
const postcssJitProps = require('postcss-jit-props');
const OpenProps = require('open-props');
module.exports = {
plugins: [
postcssJitProps(OpenProps),
// 他のプラグイン
]
}
9. よくある質問と解決策
既存プロジェクトへの導入方法
段階的に導入することをお勧めします:
- まず、基本的な変数(色、サイズなど)だけを導入
- 新しいコンポーネントでOpen Propsの変数を使用
- 既存のコンポーネントを徐々に移行
ブラウザの互換性について
CSS変数は、すべてのモダンブラウザでサポートされています。IE11などの古いブラウザをサポートする必要がある場合は、フォールバック値を提供するか、PostCSSプラグインを使用して変換することを検討してください。
.element {
/* フォールバック値 */
background-color: #3498db;
/* CSS変数 */
background-color: var(--blue-6);
}
カスタマイズ方法
Open Propsの変数は、通常のCSS変数と同様に上書きできます:
:root {
/* Open Propsの変数を上書き */
--blue-6: #1e40af;
--radius-2: 8px;
}
10. まとめ
Open Propsは、CSS変数を活用した新しいタイプのCSSフレームワークです。従来のフレームワークとは異なり、コンポーネントではなくデザイントークンを提供することで、より柔軟で一貫性のあるデザインシステムの構築を可能にします。
特に以下のような場合に効果を発揮します:
- デザインシステムを構築したい場合
- CSSに精通している開発者やデザイナー
- フレキシブルなスタイリングが必要な場合
- レスポンシブで一貫性のあるUIを構築したい場合
Open Propsは、CSS変数の力を最大限に活用し、Web開発における新しいアプローチを提供しています。適切に使用することで、開発効率の向上とデザインの一貫性維持の両方を実現できます。