React+Emotionでスタイリング|CSS in JSの基本から実践まで

React+Emotionを使ったCSS in JSの基本から実践的な活用方法まで解説。スタイリングの効率化とメンテナンス性の向上を図れます。

Learning Next 運営
42 分で読めます

みなさん、Reactでスタイリングするときに、CSSファイルの管理で困ったことはありませんか?

「コンポーネントが増えるとCSSがぐちゃぐちゃになる」「スタイルの競合が起きてしまう」「動的なスタイル変更が難しい」といった悩みを抱えている方も多いでしょう。

この記事では、そんな悩みを解決してくれるEmotionというCSS in JSライブラリをご紹介します。 EmotionとReactを組み合わせれば、スタイリングがもっと楽しく、効率的になりますよ。

Emotionとは何か?

Emotionは、JavaScriptの中でCSSを記述できるCSS in JSライブラリです。 従来のCSSファイルとは異なり、コンポーネントと密に連携したスタイリングが可能になります。

Emotionが選ばれる理由

Emotionが多くのプロジェクトで選ばれる理由は以下の通りです。

コンポーネントスコープ スタイルがコンポーネントに限定されるため、クラス名の衝突を避けられます。

動的スタイリング propsに応じた動的なスタイル変更が簡単に実装できます。

高いパフォーマンス 効率的なCSS生成とキャッシュ機能により、パフォーマンスが向上します。

優れた開発者体験 型安全性とIDEサポートにより、開発効率が向上します。

簡単に言うと、CSS管理の煩雑さを解決しながら、Reactの開発効率を向上させるツールです。

Emotionのセットアップをしよう

まず、Emotionをプロジェクトに導入する方法を見てみましょう。

インストール

Emotionの必要パッケージをインストールします。

# npm の場合
npm install @emotion/react @emotion/styled

# yarn の場合
yarn add @emotion/react @emotion/styled

Babel設定(オプション)

より効率的な開発のため、Babel設定を追加することもできます。

{
  "presets": [
    [
      "@babel/preset-react",
      { "runtime": "automatic", "importSource": "@emotion/react" }
    ]
  ],
  "plugins": ["@emotion/babel-plugin"]
}

TypeScript設定

TypeScriptを使用している場合は、tsconfig.jsonを設定します。

{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "@emotion/react"
  }
}

これで、Emotionを使う準備が整いました。

基本的なスタイリング方法を覚えよう

Emotionの基本的な使い方を見てみましょう。

css propを使った基本的なスタイリング

最も基本的なスタイリング方法は、css propを使用することです。

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

const buttonStyle = css`
  background-color: #007bff;
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
  
  &:hover {
    background-color: #0056b3;
  }
`;

function Button({ children }) {
  return <button css={buttonStyle}>{children}</button>;
}

export default Button;

このように、CSS-in-JSの記法でスタイルを定義できます。

インラインスタイルでの記述

より動的なスタイリングには、インラインでcssを記述することもできます。

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

function Alert({ type, children }) {
  return (
    <div
      css={css`
        padding: 16px;
        border-radius: 4px;
        margin: 10px 0;
        background-color: ${type === 'error' ? '#f8d7da' : '#d4edda'};
        color: ${type === 'error' ? '#721c24' : '#155724'};
        border: 1px solid ${type === 'error' ? '#f5c6cb' : '#c3e6cb'};
      `}
    >
      {children}
    </div>
  );
}

export default Alert;

propsに応じて動的にスタイルを変更することができます。 とても便利ですね。

styled-componentsスタイルの記述を試してみよう

Emotionでは、styled-components風の記述も可能です。

基本的なstyled記法

styledを使った基本的なコンポーネント作成方法です。

import styled from '@emotion/styled';

const StyledButton = styled.button`
  background-color: #007bff;
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
  transition: background-color 0.3s ease;

  &:hover {
    background-color: #0056b3;
  }

  &:disabled {
    background-color: #6c757d;
    cursor: not-allowed;
  }
`;

function App() {
  return (
    <div>
      <StyledButton>通常のボタン</StyledButton>
      <StyledButton disabled>無効なボタン</StyledButton>
    </div>
  );
}

export default App;

propsを使った動的スタイリング

propsを使用して、動的にスタイルを変更することができます。

import styled from '@emotion/styled';

const StyledButton = styled.button`
  background-color: ${props => 
    props.variant === 'primary' ? '#007bff' : 
    props.variant === 'secondary' ? '#6c757d' : 
    '#28a745'
  };
  color: white;
  padding: ${props => props.size === 'large' ? '15px 30px' : '10px 20px'};
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: ${props => props.size === 'large' ? '18px' : '16px'};

  &:hover {
    opacity: 0.9;
  }
`;

function App() {
  return (
    <div>
      <StyledButton variant="primary">プライマリ</StyledButton>
      <StyledButton variant="secondary" size="large">
        セカンダリ(大)
      </StyledButton>
      <StyledButton variant="success">成功</StyledButton>
    </div>
  );
}

export default App;

このように、propsを使って柔軟にスタイルを制御できます。

テーマ機能を活用しよう

Emotionでは、テーマ機能を使って一貫したデザインシステムを構築できます。

テーマの定義

まず、アプリケーション全体で使用するテーマを定義します。

// theme.js
export const theme = {
  colors: {
    primary: '#007bff',
    secondary: '#6c757d',
    success: '#28a745',
    danger: '#dc3545',
    warning: '#ffc107',
    info: '#17a2b8',
    light: '#f8f9fa',
    dark: '#343a40',
    white: '#ffffff',
    gray: {
      100: '#f8f9fa',
      200: '#e9ecef',
      300: '#dee2e6',
      400: '#ced4da',
      500: '#adb5bd',
      600: '#6c757d',
      700: '#495057',
      800: '#343a40',
      900: '#212529'
    }
  },
  spacing: {
    xs: '4px',
    sm: '8px',
    md: '16px',
    lg: '24px',
    xl: '32px',
    xxl: '48px'
  },
  breakpoints: {
    sm: '576px',
    md: '768px',
    lg: '992px',
    xl: '1200px'
  },
  typography: {
    fontFamily: '"Helvetica Neue", Arial, sans-serif',
    fontSize: {
      xs: '0.75rem',
      sm: '0.875rem',
      md: '1rem',
      lg: '1.125rem',
      xl: '1.25rem',
      xxl: '1.5rem'
    },
    fontWeight: {
      light: 300,
      normal: 400,
      medium: 500,
      semibold: 600,
      bold: 700
    }
  }
};

テーマプロバイダーの設定

アプリケーション全体でテーマを使用するための設定です。

// App.js
import { ThemeProvider } from '@emotion/react';
import { theme } from './theme';
import MainComponent from './MainComponent';

function App() {
  return (
    <ThemeProvider theme={theme}>
      <MainComponent />
    </ThemeProvider>
  );
}

export default App;

テーマを使ったスタイリング

定義したテーマを使ってスタイリングを行います。

import styled from '@emotion/styled';

const Container = styled.div`
  max-width: 1200px;
  margin: 0 auto;
  padding: ${props => props.theme.spacing.md};
  
  @media (max-width: ${props => props.theme.breakpoints.md}) {
    padding: ${props => props.theme.spacing.sm};
  }
`;

const Title = styled.h1`
  font-family: ${props => props.theme.typography.fontFamily};
  font-size: ${props => props.theme.typography.fontSize.xxl};
  font-weight: ${props => props.theme.typography.fontWeight.bold};
  color: ${props => props.theme.colors.dark};
  margin-bottom: ${props => props.theme.spacing.lg};
`;

const Card = styled.div`
  background-color: ${props => props.theme.colors.white};
  border: 1px solid ${props => props.theme.colors.gray[200]};
  border-radius: 8px;
  padding: ${props => props.theme.spacing.lg};
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
`;

function MainComponent() {
  return (
    <Container>
      <Title>Emotionテーマ活用例</Title>
      <Card>
        <p>テーマを使って一貫したデザインを実現できます。</p>
      </Card>
    </Container>
  );
}

export default MainComponent;

このように、テーマを使うことで一貫したデザインシステムを構築できます。

レスポンシブデザインを実装しよう

Emotionでレスポンシブデザインを実装する方法を見てみましょう。

メディアクエリの活用

Emotionでは、CSS-in-JSの中でメディアクエリを使用できます。

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

const responsiveContainer = css`
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
  padding: 20px;
  
  @media (max-width: 768px) {
    grid-template-columns: 1fr;
    padding: 10px;
  }
  
  @media (max-width: 480px) {
    gap: 10px;
  }
`;

const responsiveCard = css`
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  
  @media (max-width: 768px) {
    padding: 15px;
  }
  
  @media (max-width: 480px) {
    padding: 10px;
  }
`;

function ResponsiveGrid({ items }) {
  return (
    <div css={responsiveContainer}>
      {items.map((item, index) => (
        <div key={index} css={responsiveCard}>
          <h3>{item.title}</h3>
          <p>{item.description}</p>
        </div>
      ))}
    </div>
  );
}

export default ResponsiveGrid;

テーマを使ったレスポンシブ設計

テーマのブレイクポイントを活用したレスポンシブ設計です。

import styled from '@emotion/styled';

const ResponsiveLayout = styled.div`
  display: flex;
  flex-wrap: wrap;
  gap: ${props => props.theme.spacing.md};
  
  @media (max-width: ${props => props.theme.breakpoints.md}) {
    flex-direction: column;
    gap: ${props => props.theme.spacing.sm};
  }
`;

const FlexItem = styled.div`
  flex: 1;
  min-width: 250px;
  padding: ${props => props.theme.spacing.lg};
  background: ${props => props.theme.colors.gray[100]};
  border-radius: 8px;
  
  @media (max-width: ${props => props.theme.breakpoints.sm}) {
    min-width: 100%;
    padding: ${props => props.theme.spacing.md};
  }
`;

function ResponsiveComponent() {
  return (
    <ResponsiveLayout>
      <FlexItem>
        <h3>コンテンツ1</h3>
        <p>レスポンシブなレイアウトのデモです。</p>
      </FlexItem>
      <FlexItem>
        <h3>コンテンツ2</h3>
        <p>画面サイズに応じて表示が変わります。</p>
      </FlexItem>
    </ResponsiveLayout>
  );
}

export default ResponsiveComponent;

テーマを使うことで、一貫したレスポンシブデザインを実現できます。

アニメーションとトランジションを追加しよう

Emotionでアニメーションを実装する方法を見てみましょう。

CSS トランジションの実装

基本的なホバーアニメーションの実装例です。

import styled from '@emotion/styled';

const AnimatedButton = styled.button`
  background: linear-gradient(45deg, #007bff, #0056b3);
  color: white;
  border: none;
  padding: 12px 24px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 16px;
  font-weight: 500;
  transition: all 0.3s ease;
  transform: translateY(0);
  box-shadow: 0 4px 15px rgba(0, 123, 255, 0.4);

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 25px rgba(0, 123, 255, 0.6);
  }

  &:active {
    transform: translateY(0);
    box-shadow: 0 2px 10px rgba(0, 123, 255, 0.3);
  }
`;

const FadeInCard = styled.div`
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  opacity: 0;
  transform: translateY(20px);
  animation: fadeInUp 0.6s ease forwards;
  
  @keyframes fadeInUp {
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }
`;

function AnimatedComponents() {
  return (
    <div>
      <AnimatedButton>ホバーしてみてください</AnimatedButton>
      <FadeInCard>
        <h3>フェードインアニメーション</h3>
        <p>カードが下から上にフェードインします。</p>
      </FadeInCard>
    </div>
  );
}

export default AnimatedComponents;

keyframesを使った高度なアニメーション

より複雑なアニメーションの実装例です。

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

const pulseAnimation = keyframes`
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.05);
  }
  100% {
    transform: scale(1);
  }
`;

const rotateAnimation = keyframes`
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
`;

const pulseStyle = css`
  animation: ${pulseAnimation} 2s ease-in-out infinite;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 20px;
  border-radius: 10px;
  text-align: center;
  margin: 20px 0;
`;

const spinnerStyle = css`
  width: 40px;
  height: 40px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #007bff;
  border-radius: 50%;
  animation: ${rotateAnimation} 1s linear infinite;
  margin: 20px auto;
`;

function AnimatedDemo() {
  return (
    <div>
      <div css={pulseStyle}>
        <h3>パルスアニメーション</h3>
        <p>継続的に拡大縮小するアニメーション</p>
      </div>
      <div css={spinnerStyle}></div>
    </div>
  );
}

export default AnimatedDemo;

このように、Emotionを使って様々なアニメーション効果を実装できます。

パフォーマンスを最適化しよう

Emotionを使用する際のパフォーマンス最適化について解説します。

スタイルの分割と再利用

コンポーネント間でスタイルを効率的に再利用する方法です。

// styles/common.js
import { css } from '@emotion/react';

export const commonStyles = {
  button: css`
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 16px;
    transition: all 0.3s ease;
  `,
  
  card: css`
    background: white;
    border-radius: 8px;
    padding: 20px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  `,
  
  flexCenter: css`
    display: flex;
    justify-content: center;
    align-items: center;
  `
};

// 使用例
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
import { commonStyles } from './styles/common';

const primaryButton = css`
  ${commonStyles.button}
  background-color: #007bff;
  color: white;
  
  &:hover {
    background-color: #0056b3;
  }
`;

function MyComponent() {
  return (
    <div css={commonStyles.card}>
      <div css={commonStyles.flexCenter}>
        <button css={primaryButton}>クリック</button>
      </div>
    </div>
  );
}

export default MyComponent;

メモ化による最適化

React.memoを使ってスタイルの再計算を最適化する方法です。

import React, { memo } from 'react';
import styled from '@emotion/styled';

const StyledCard = styled.div`
  background: ${props => props.theme.colors.white};
  border-radius: 8px;
  padding: ${props => props.theme.spacing.lg};
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  border-left: 4px solid ${props => 
    props.status === 'success' ? props.theme.colors.success :
    props.status === 'error' ? props.theme.colors.danger :
    props.theme.colors.info
  };
`;

const Card = memo(({ title, content, status }) => {
  return (
    <StyledCard status={status}>
      <h3>{title}</h3>
      <p>{content}</p>
    </StyledCard>
  );
});

export default Card;

条件付きスタイリングの最適化

条件に応じたスタイリングを効率的に行う方法です。

import styled from '@emotion/styled';

const OptimizedButton = styled.button`
  ${props => props.theme.commonStyles.button}
  
  ${props => {
    switch (props.variant) {
      case 'primary':
        return `
          background-color: ${props.theme.colors.primary};
          color: white;
          &:hover { background-color: ${props.theme.colors.primaryDark}; }
        `;
      case 'secondary':
        return `
          background-color: ${props.theme.colors.secondary};
          color: white;
          &:hover { background-color: ${props.theme.colors.secondaryDark}; }
        `;
      default:
        return `
          background-color: transparent;
          color: ${props.theme.colors.primary};
          border: 1px solid ${props.theme.colors.primary};
          &:hover { background-color: ${props.theme.colors.primaryLight}; }
        `;
    }
  }}
`;

function OptimizedComponent() {
  return (
    <div>
      <OptimizedButton variant="primary">プライマリ</OptimizedButton>
      <OptimizedButton variant="secondary">セカンダリ</OptimizedButton>
      <OptimizedButton>デフォルト</OptimizedButton>
    </div>
  );
}

export default OptimizedComponent;

これらの最適化により、パフォーマンスの向上を図ることができます。

実践的なコンポーネント例を作ってみよう

実際のプロジェクトで使える実践的なコンポーネント例を見てみましょう。

多機能なボタンコンポーネント

様々な用途に対応できるボタンコンポーネントです。

import styled from '@emotion/styled';

const StyledButton = styled.button`
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: ${props => 
    props.size === 'small' ? '6px 12px' :
    props.size === 'large' ? '16px 32px' :
    '10px 20px'
  };
  font-size: ${props => 
    props.size === 'small' ? '14px' :
    props.size === 'large' ? '18px' :
    '16px'
  };
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-weight: 500;
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
  
  ${props => {
    const { variant, theme } = props;
    const colors = theme.colors;
    
    switch (variant) {
      case 'primary':
        return `
          background: ${colors.primary};
          color: white;
          &:hover { background: ${colors.primaryDark}; }
        `;
      case 'secondary':
        return `
          background: ${colors.secondary};
          color: white;
          &:hover { background: ${colors.secondaryDark}; }
        `;
      case 'outline':
        return `
          background: transparent;
          color: ${colors.primary};
          border: 2px solid ${colors.primary};
          &:hover { 
            background: ${colors.primary};
            color: white;
          }
        `;
      default:
        return `
          background: ${colors.gray[100]};
          color: ${colors.dark};
          &:hover { background: ${colors.gray[200]}; }
        `;
    }
  }}
  
  &:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
  
  &:focus {
    outline: none;
    box-shadow: 0 0 0 3px ${props => props.theme.colors.primary}33;
  }
`;

const LoadingSpinner = styled.div`
  width: 16px;
  height: 16px;
  border: 2px solid transparent;
  border-top: 2px solid currentColor;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  
  @keyframes spin {
    to { transform: rotate(360deg); }
  }
`;

function Button({ 
  children, 
  variant = 'default', 
  size = 'medium',
  loading = false,
  disabled = false,
  icon,
  ...props 
}) {
  return (
    <StyledButton
      variant={variant}
      size={size}
      disabled={disabled || loading}
      {...props}
    >
      {loading && <LoadingSpinner />}
      {!loading && icon && <span>{icon}</span>}
      {children}
    </StyledButton>
  );
}

export default Button;

カスタマイズ可能なカードコンポーネント

柔軟性の高いカードコンポーネントの実装例です。

import styled from '@emotion/styled';

const CardContainer = styled.div`
  background: ${props => props.theme.colors.white};
  border-radius: 12px;
  box-shadow: ${props => 
    props.elevated ? 
    '0 10px 25px rgba(0, 0, 0, 0.1)' : 
    '0 2px 8px rgba(0, 0, 0, 0.08)'
  };
  overflow: hidden;
  transition: all 0.3s ease;
  border: 1px solid ${props => props.theme.colors.gray[200]};
  
  ${props => props.hoverable && `
    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 15px 35px rgba(0, 0, 0, 0.15);
    }
  `}
`;

const CardHeader = styled.div`
  padding: ${props => props.theme.spacing.lg};
  border-bottom: 1px solid ${props => props.theme.colors.gray[200]};
  background: ${props => props.theme.colors.gray[50]};
`;

const CardTitle = styled.h3`
  margin: 0;
  color: ${props => props.theme.colors.dark};
  font-size: ${props => props.theme.typography.fontSize.lg};
  font-weight: ${props => props.theme.typography.fontWeight.semibold};
`;

const CardSubtitle = styled.p`
  margin: 4px 0 0 0;
  color: ${props => props.theme.colors.gray[600]};
  font-size: ${props => props.theme.typography.fontSize.sm};
`;

const CardBody = styled.div`
  padding: ${props => props.theme.spacing.lg};
`;

const CardFooter = styled.div`
  padding: ${props => props.theme.spacing.md} ${props => props.theme.spacing.lg};
  border-top: 1px solid ${props => props.theme.colors.gray[200]};
  background: ${props => props.theme.colors.gray[50]};
  display: flex;
  justify-content: space-between;
  align-items: center;
`;

function Card({ 
  title, 
  subtitle, 
  children, 
  footer, 
  elevated = false,
  hoverable = false,
  ...props 
}) {
  return (
    <CardContainer elevated={elevated} hoverable={hoverable} {...props}>
      {(title || subtitle) && (
        <CardHeader>
          {title && <CardTitle>{title}</CardTitle>}
          {subtitle && <CardSubtitle>{subtitle}</CardSubtitle>}
        </CardHeader>
      )}
      <CardBody>{children}</CardBody>
      {footer && <CardFooter>{footer}</CardFooter>}
    </CardContainer>
  );
}

export default Card;

これらのコンポーネントは、実際のプロジェクトでそのまま使用できる実用的な例です。

よくある問題と解決方法

Emotionを使用する際によく遭遇する問題と解決方法をまとめました。

スタイルの競合問題

問題: 複数のスタイルが競合してしまう

解決方法:

// スタイルの優先順位を明確にする
const baseStyle = css`
  color: blue;
`;

const overrideStyle = css`
  ${baseStyle}
  color: red; /* これが優先される */
`;

// または、より具体的なセレクタを使用
const specificStyle = css`
  &.my-component {
    color: red;
  }
`;

TypeScript との型安全性

問題: TypeScriptで型エラーが発生する

解決方法:

// 型定義を追加
interface ButtonProps {
  variant: 'primary' | 'secondary' | 'outline';
  size: 'small' | 'medium' | 'large';
  children: React.ReactNode;
}

const StyledButton = styled.button<ButtonProps>`
  padding: ${props => props.size === 'large' ? '16px 32px' : '10px 20px'};
  background: ${props => props.variant === 'primary' ? '#007bff' : '#6c757d'};
`;

パフォーマンスの問題

問題: 大量のスタイルによるパフォーマンス低下

解決方法:

// スタイルの分割と再利用
const commonStyles = {
  button: css`
    /* 共通スタイル */
  `,
  card: css`
    /* 共通スタイル */
  `
};

// メモ化の活用
const MemoizedComponent = memo(styled.div`
  /* スタイル */
`);

これらの対策により、安定したEmotion活用が可能になります。

まとめ:Emotionで効率的なスタイリングを実現しよう

React+Emotionを使ったCSS-in-JSスタイリングについて、基本から実践まで詳しく解説しました。

Emotionの主なメリット

コンポーネント指向 スタイルとコンポーネントの密結合により、保守性が向上します。

動的スタイリング propsに応じた柔軟なスタイル変更が可能です。

優れた開発者体験 型安全性とツールサポートにより、開発効率が向上します。

高いパフォーマンス 効率的なCSS生成とキャッシュ機能により、パフォーマンスが向上します。

豊富な機能 テーマ、アニメーション、レスポンシブ対応など、様々な機能を活用できます。

実装のポイント

効果的なEmotion活用のための重要なポイントです。

  1. 基本的な使い方の理解: css prop と styled の使い分け
  2. テーマシステムの活用: 一貫したデザインシステムの構築
  3. パフォーマンスの最適化: メモ化と効率的なスタイル管理
  4. 実践的なコンポーネント設計: 再利用可能で保守性の高いコンポーネント

学習の進め方

Emotionの習得は以下の順序で進めることをおすすめします。

  1. 基本的なスタイリング: css prop を使った基本的な記述
  2. styled-components: styled を使ったコンポーネント作成
  3. テーマ機能: 一貫したデザインシステムの構築
  4. レスポンシブ対応: メディアクエリとブレイクポイント
  5. アニメーション: トランジションとkeyframesの活用
  6. 最適化: パフォーマンスとメンテナンス性の向上

Emotionは、Reactアプリケーションのスタイリングを劇的に改善する強力なツールです。 コンポーネント指向の開発と相性が良く、保守性の高いスタイリングを実現できます。

ぜひ、実際のプロジェクトでEmotionを活用して、効率的で美しいUIを構築してみてください。

関連記事