0Pricing
Frontend Academy · レッスン

CSS-in-JS:Styled-components と Emotion

styled-components ではタグ付きテンプレートリテラルとして、Emotion では css prop としてコンポーネントスタイルを書き、Props で動的なスタイルを設定します。

「CSS-in-JS:Styled-components と Emotion」はCoddyKit上の無料Frontend Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはFrontend Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Frontend Academyコースには全4レッスンが含まれています。

CSS-in-JSとは

CSS-in-JSでは、コンポーネントのスタイルをJavaScript/TypeScriptに直接記述します。スタイルをコンポーネントと同じ場所で管理でき、propsから動的な値を利用でき、自動的にスコープ化されます。最も広く使われているライブラリはstyled-componentsとEmotionです。

Styled-componentsの基本

タグ付きテンプレートリテラルを使って、styled componentを定義します。その結果、スタイルが適用されたHTML要素を描画するReactコンポーネントが作成されます。

import styled from 'styled-components';

const Button = styled.button`
  background: ${props => props.primary ? '#6366f1' : 'white'};
  color: ${props => props.primary ? 'white' : '#6366f1'};
  padding: 8px 16px;
  border: 2px solid #6366f1;
  border-radius: 4px;
  cursor: pointer;

  &:hover {
    opacity: 0.9;
  }
`;

<Button primary>Primary</Button>
<Button>Outline</Button>

Emotion — css prop

Emotionのcss propを使うと、任意のJSX要素にスタイルを適用できます。@emotion/reactのpragmaまたはBabel presetが必要です。

/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';

function Card({ featured }: { featured?: boolean }) {
  return (
    <div css={css`
      padding: 16px;
      border-radius: 8px;
      border: ${featured ? '2px solid #6366f1' : '1px solid #e2e8f0'};
    `}>
      Content
    </div>
  );
}

propsからの動的なスタイル

どちらのライブラリでも、propsを読み取ってスタイルを計算できます。これが静的なCSSに対する主な利点です。クラスを切り替える必要がありません。

ThemeProviderによるテーマ設定

Styled-componentsとEmotionはどちらも、すべてのstyled componentにテーマの値を注入するThemeProviderをサポートしています。

import { ThemeProvider } from 'styled-components';

const theme = { colors: { primary: '#6366f1', bg: '#f7fafc' }, space: { sm: 8, md: 16 } };

<ThemeProvider theme={theme}>
  <App />
</ThemeProvider>

// Access in styled component:
const Card = styled.div`
  background: ${props => props.theme.colors.bg};
  padding: ${props => props.theme.space.md}px;
`;

Styled Componentsの拡張

既存のstyled componentを拡張すると、スタイルを重複させずにバリエーションを作成できます。

const Button = styled.button`
  padding: 8px 16px;
  border-radius: 4px;
`;

const DangerButton = styled(Button)`
  background: #e53e3e;
  color: white;
`;

グローバルスタイル

bodyのスタイルやリセットなどのグローバルCSSには、createGlobalStyle(styled-components)またはGlobal(Emotion)を使用します。

import { createGlobalStyle } from 'styled-components';

const GlobalStyle = createGlobalStyle`
  *, *::before, *::after { box-sizing: border-box; }
  body { margin: 0; font-family: system-ui; }
`;

<><GlobalStyle /><App /></>

CSS-in-JSの実行時コスト

CSS-in-JSライブラリは、JavaScriptを介して実行時にスタイルを挿入します。そのため、解析とスタイルの挿入にCPUコストがかかり、JavaScriptバンドルのサイズも増加します。vanilla-extractやlinariaなどの実行時処理がない代替手段は、ビルド時に静的なCSSを生成します。

実行時処理がない代替手段

vanilla-extract: TypeScriptでスタイルを記述し、静的なCSSにコンパイルします。linaria: CSS-in-JSの構文をCSS Modulesにコンパイルします。どちらも、実行時のオーバーヘッドなしでCSS-in-JSの使いやすさを実現します。

styled-componentsでのTypeScript

ThemeTypeを定義し、styled-componentsのDefaultThemeインターフェースを拡張すると、テーマを完全に型付けできます。

import 'styled-components';
import { theme } from './theme';

declare module 'styled-components' {
  export interface DefaultTheme extends typeof theme {}
}

CSS-in-JSを選ぶタイミング

CSS-in-JSは、実行時のJavaScriptの値に基づく動的なスタイル、テーマ機能を重視するデザインシステム、JavaScript中心のワークフローを好むチームに最適です。パフォーマンスが重要ではないUIでは、通常、実行時コストは許容範囲内です。

クイックチェック

静的なCSSソリューションと比較した場合、実行時に動作するCSS-in-JSライブラリの主なトレードオフは何ですか?

まとめ: CSS-in-JS

Styled-components: タグ付きテンプレートリテラルを使い、スタイル付きのReact要素を描画する。Emotion: css propまたはstyled APIを使用する。propsによる動的なスタイルでクラスの切り替えが不要になる。ThemeProviderがテーマの値を注入する。グローバルCSSにはcreateGlobalStyleを使用する。実行時コストが主なトレードオフである。実行時処理がない代替手段にはvanilla-extractとlinariaがある。

よくある質問

「CSS-in-JS:Styled-components と Emotion」レッスンは無料ですか?

はい。「CSS-in-JS:Styled-components と Emotion」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Frontend Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Frontend Academyコースには全4レッスンが含まれています。

「CSS-in-JS:Styled-components と Emotion」で何を学びますか?

styled-components ではタグ付きテンプレートリテラルとして、Emotion では css prop としてコンポーネントスタイルを書き、Props で動的なスタイルを設定します。 ブラウザで直接実行するハンズオンコードでFrontend Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Frontend Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのFrontend Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「CSS-in-JS:Styled-components と Emotion」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このFrontend Academyレッスンでコードを書いて実行できますか?

はい。すべてのFrontend Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. BEM 方法論:Block・Element・Modifier
  2. CSS Modules:スコープ付きクラス名
  3. CSS-in-JS:Styled-components と Emotion
  4. Tailwind CSS のユーティリティファーストアプローチ
← Frontend Academyに戻る