40
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NRI OpenStandiaAdvent Calendar 2023

Day 12

StyleX:FacebookやInstagramで利用されているCSS-in-JS

Last updated at Posted at 2023-12-11

約1週間前の2023/12/5にMeta社が開発するCSS-in-JSライブラリ、StyleXオープンソースとして公開されたので触ってみました。

StyleX

FacebookやInstagram、ThreadsなどMeta社のプロダクトで利用されており、この度晴れてオープンソース化したCSS-in-JSです。

React Finland 2021の講演で既に紹介されており、この時点では2021年にオープンソース化の見込みとなっていました。

特徴

特徴は上記でまとまっていますが、改めて大事なところを抜粋し意訳します。

Fast

  • No runtime style injection.
  • All styles are bundled in a static CSS file at compile-time.
  • Optimized runtime for merging class names.

速いです。いわゆるゼロランタイムで、コンパイル時に静的なCSSファイルを生成しバンドルします。

Scalable

  • Minimize CSS output with atomic CSS.
  • The CSS size plateaus even as the number of components grows.
  • Styles remain readable and maintainable within growing codebases.

スケーラブルです。最適化されたアトミックCSS1を生成するので、コードベースが大きくなってコンポーネントが増えても、CSSファイルのサイズは線形に増大せずある程度で落ち着きます。

Type-Safe

  • Type-safe APIs.
  • Type-safe styles.
  • Type-safe themes.

タイプセーフです。

React Server Components との相性

その仕組みゆえ、React Server Components でも動作します。

ドキュメントに明示的にその記載はありませんが、GitHubのissueでメンテナーの方も"StyleXはReact Server Componentsで動作する"と答えています。

Will all the StyleX features work without restrictions in all React components?

Yes. All of StyleX will work with React, Next and React Server Components.

触ってみる

ここから実際に触ってみます。プロダクション向けには、

の3つが現時点ではサポートされています。今回はNext.jsで使ってみました。

viteプラグインは、issueで議論されています。

インストールと設定

packageのインストールし.babelrc.js、next.config.js を以下に従い設定します。

...が、create-next-appして、packageインストールして、上記の設定コピペしてもうまく動かなかったので、おとなしく公式が出しているexampleの.babelrc.js、next.config.jsを拝借しました。

スタイリングの実装

スタイルやテーマの定義、利用方法は公式ドキュメントにまとまっています。

ここでは、create-next-appで作成した画面をStyleXで実装するとどうなるか、CSS Modulesとの対比で記載してみます。

CSS Moduleの場合

page.module.css より抜粋
.main {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  padding: 6rem;
  min-height: 100vh;
}

.description {
  display: inherit;
  justify-content: inherit;
  align-items: inherit;
  font-size: 0.85rem;
  max-width: var(--max-width);
  width: 100%;
  z-index: 2;
  font-family: var(--font-mono);
}
page.tsx より抜粋
export default function Home() {
  return (
    <main className="main">
      <div className="description">
          {/*(略)*/}
      </div>
    </main>
    )
}

StyleXの場合

tokens.stylex.ts より抜粋
// デザイントークン(CSS変数)の定義
export const tokens = stylex.defineVars({
    maxWidth: "1100px",
    borderRadius: "12px",
    //(略)
page.tsx より抜粋
import * as stylex from '@stylexjs/stylex';
import { tokens } from "./tokens.stylex";

//スタイルの定義
const styles = stylex.create({
  main: {
    display: "flex",
    flexDirection: "column",
    justifyContent: "space-between",
    alignItems: "center",
    padding: "6rem",
    minHeight: "100vh"
  },
  description: {
    display: "inherit",
    justifyContent: "inherit",
    alignItems: "inherit",
    fontSize: "0.85rem",
    maxWidth: tokens.maxWidth,
    width: "100%",
    zIndex: "2",
    fontFamily: tokens.fontMono,
  }
  
  //(略)

});

export default function Home() {
  return (
    {/*スタイルの利用*/}
    <main {...stylex.props(styles.main)}>
      <div {...stylex.props(styles.description)}>
          {/*(略)*/}
      </div>
    </main>
    )
}  

基本的には

という形になります。

生成されたCSS

StyleXで実装した画面を開発者ツールで覗いてみます。

image.png

以下のように、実行時にはタグに複数のクラスが付与されており、1クラスが1つの機能/役割を持っていることがわかります。これが特徴の一つ、アトミックCSS1を生成する、ということでしょう。

<main class="x78zum5 xdt5ytf x1qughib x6s0dn4 x1hm14om xg6iff7">
.xg6iff7 {
    min-height: 100vh;
}

.x1qughib {
    justify-content: space-between;
}

はまったところ

使い方は直感的で、触った範囲では概ね問題なく動きましたが、いくつかはまったポイントがありました。

  • .babelrc.jsnext.config.jsがドキュメントの設定ではうまく動作しなかった
    • => 公式のexampleの設定をコピーして利用
  • stylex.defineVarsで定義した変数をaliasを利用してインポートできない
    • => 変数のインポートではaliasを利用しない。こちらのissueです。

まだStyleXは公開されたばかりですし、これから改善してくものと思われます。

おわりに

React Server Componentsに対応している点や、FacebookやInstagramのようなプロダクトで実績がある点は魅力的です。

一方で、触ってみると上記のようにやや粗削りな印象もありました。これからユーザのフィードバックが集まり洗練されれば、プロダクションで利用するスタイリング手法の選択肢に入ってくるのかなと思いました。

今後の動きに注目、期待したいです。

  1. アトミックCSSという言葉は一般的なんでしょうか?私は「1クラスに最低限の(≒1つの)役割のみ持たせたCSSの設計手法」ととらえています。Tailwind のようなUtility Firstと同じようなイメージです。 2

40
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?