🦔

CSSフレームワークOpen PropsをNext.jsのApp Routerで使ってみた

2023/10/12に公開

きっかけ

State of CSSの CSS フレームワークで Tailwind を抑えて今年から「Open Props」が一位になっていて、気になったので調べてみました。

image

Open Props とは

https://open-props.style/

カスタムプロパティベース CSS フレームワークとのことですが、簡単に言っちゃうと CSS 変数の寄せ集めです。
ぶっちゃけこれだけ笑

color, gradients, shadows, aspect ratios, typography, easings, animations, sizes, borders, z-indexes, media-queries などが用意されていて、あとは CSS でのスタイリング時に使うだけです。

例えばボタンだったらこんな感じでスタイルできます。

button.blue {
  color: var(--blue-6);
  background-color: var(--blue-0);
  border: 1px solid var(--blue-1);
  text-shadow: 0 1px 0 var(--blue-2);

  &:hover {
    background-color: var(--blue-1);
  }
}

ファーストインプレッション

カスタムプロパティベース CSS フレームワークとのことでまず思ったのは以下の 3 項目でした。

  1. バックエンドエンジニアがフロント触る場合はしんどそう・・・
  2. React(Next.js)ではどう使えるかな?
  3. VSCode との親和性あるの?

この 3 項目についてちょっと深掘りして触っていこうかなと思います。

バックエンドエンジニアがフロント触る場合はしんどそう・・・

うん、これはおそらくめちゃくちゃしんどい。
「Open Props」は CSS をめっちゃ書きたい!or 書く必要がある時に力を発揮するフレームワークかなと思いました。
変数になっているだけで正直めっちゃ CSS 書きますもん!!ある程度 CSS に精通していないと正直しんどいだけ笑
バックエンドエンジニアが CSS 書くなら Tailwind ベースの UI フレームワークを使った方が楽です!

とはいえ、CSS を書ける人にとってはかなりスタイルが楽になるかなと思います。

例えばメディアクエリも用意されているのですでにあるルールに則って書くことができます。

@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);
@custom-media --md-phone (--md-only) and (--portrait);

@custom-media --xxl-only (1440px <= width <= 1920px);
@custom-media --xxl-n-above (width >= 1920px);
@custom-media --xxl-n-below (width < 1920px);

個人的に思う「Open Props」のメリットは ルールに則って CSS を 0 から書くことができることかなと思います。
自由に CSS を書くことができるけど変数によって文字のサイズやメディアクエリ、カラーなどのルールが設けられているので統一性を持たせることができる感じでしょうか。

ただ、自由に書くことができるからこそ CSS 設計の技量が必要ですね。

React(Next.js)ではどう使えるかな?

個人的には Next.js で開発する機会が圧倒的に多いのでこれは気になるところです。
結論から言うと超絶簡単に導入できます。

  1. インストール

まずはインストールします。

$ npm install open-props
  1. css ファイルに import

Next.js の app router であれば /appglobals.cssなどで css ファイルを作成して import します。

globals.css
/* the props */
@import "open-props/style";

/* optional imports that use the props */
@import "open-props/normalize";
@import "open-props/buttons";

/* just light or dark themes */
@import "open-props/normalize/dark";
@import "open-props/buttons/dark";
@import "open-props/normalize/light";
@import "open-props/buttons/light";

/* individual imports */
@import "open-props/indigo";
@import "open-props/easings";
@import "open-props/animations";
@import "open-props/sizes";
@import "open-props/gradients";
/* see PropPacks for the full list */
  1. Component 側で import

app router の場合は /app 直下の Layout.tsx で先ほどの globals.cssを import します。
pages router の場合は _app.tsx で import します。

import "./globals.css";

導入手順としてはこれだけでした。
実際にスタイリングをしてみても・・・

Button.tsx
import { FC } from "react";
import styles from "./Button.module.css";

export const Button: FC = () => {
  return <button className={styles.button}>ボタン</button>;
};

Button.module.css
.button {
  border-width: var(--border-size-1);
  border-color: var(--blue-10);
  color: var(--gray-0);
  border-radius: var(--radius-round);
  background: var(--blue-5);
}

変数の上書きも可能

ちなみに上書きもできました。globals.css で上書きができます。例えば --blue-10 の色を変えたければ下記のようにできます。

// この辺でimport

:root {
  --blue-10: #0000ff;
}

なのでサービスの primary カラーなどがあれば個別に指定しておいても良いですね。

VSCode との親和性あるの?

フロントエンド開発エディターの覇者である VSCode との親和性も気になるとこです。こちらも公式にすでにやり方が書いてありました。

VSCode のエクステンションと設定が必要とのことです。

  1. CSS Var Completeをインストール

image

  1. settings.json に以下を追記
{
  "cssvar.files": [
    "./node_modules/open-props/open-props.min.css",
    // if you have an alternative path to where your styles are located
    // you can add it in this array of files
    "assets/styles/variables.css"
  ],

  // Do not ignore node_modules css files, which is ignored by default
  "cssvar.ignore": [],

  // add support for autocomplete in JS or JS like files
  "cssvar.extensions": ["css", "postcss", "jsx", "tsx"]
}

上記で設定完了っぽいんですけど私の環境では再起動しないとダメでした。
ちなみに設定ができているといい感じにサジェストされます。

image

実際に使ってみた感想

感想としては「css modules」との相性が良さそうと思いました。

Next.js、React のスタイリングは個人的には styled-componentsなどのいわゆるランタイム CSS in JS が書き味としては好みなんですけど、パフォーマンスを考慮すると良くないし、React 公式も非推奨にしています。
となると vanilla-extract などのゼロランタイム CSS in JS か CSS modules になるんですけど、学習コストがかからないと言う点で CSS modules が無難かなと思います。その CSS modules を補助するフレームワークといった立ち位置かなと思いました。
新しくプロジェクト開発をする際に候補として CSS modules + Open Props はアリかなと思います!!

もちろん WEB 制作における HTML と CSS のマークアップでも使える CSS フレームワークですが、その場合は CSS の設計スキルが求められます。そこが CSS の一番難しいところなんですけどね。

Discussion