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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- BEM 方法論:Block・Element・Modifier
- CSS Modules:スコープ付きクラス名
- CSS-in-JS:Styled-components と Emotion
- Tailwind CSS のユーティリティファーストアプローチ