StyledComponentsでのレスポンシブ対応の方法


StyledComponentsでのレスポンシブ対応

ReactやNextでStyledComponentsを使っているとレスポンシブ対応ってどうやるんだ?という疑問が出てきました。
色々調べてもあまり記事がなかった為、今回紹介する方法が正しいのかは分かりません。
使い勝手はいいと思います。

レスポンシブ対応の方法

今回の使用バージョン一覧

バージョンによって変わる可能性があるのでバージョンも載せておきます。
今回はNextJSを使用して構成しましたが、Reactでも同じように使う事ができます。

"next": "12.1.1",
"react": "17.0.2",
"react-dom": "17.0.2",
"styled-components": "^5.3.5"

Themeの作成

themeフォルダーを作成し、全体のテーマとなる値などを入れておきます。

ファイル構成
theme
├── setting
│   ├── breakpoint.ts //ブレイクポイントの設定
│   ├── colors.ts //カラーの設定
│   ├── fonts.ts //フォントの設定
│   └── zindex.ts //zindexの設定
└── theme.ts //全部の設定を一つにまとめる為のファイル

各種ファイルの設定

TailwindCSSをベースにブレイクポイントの設定をしました。
モバイルファーストで640,768,1024,1280で打ってあります。

breakpoint.ts
import {
  CSSObject,
  FlattenSimpleInterpolation,
  SimpleInterpolation,
  css,
} from 'styled-components';

export const breakpoint = {
  base: (
    base: CSSObject | TemplateStringsArray,
    ...interpolations: SimpleInterpolation[]
  ): FlattenSimpleInterpolation => css`
      ${css(base, ...interpolations)}
  `,
  sm: (
    sm: CSSObject | TemplateStringsArray,
    ...interpolations: SimpleInterpolation[]
  ): FlattenSimpleInterpolation => css`
    @media (min-width: 640px) {
      ${css(sm, ...interpolations)}
    }
  `,
  md: (
    md: CSSObject | TemplateStringsArray,
    ...interpolations: SimpleInterpolation[]
  ): FlattenSimpleInterpolation => css`
    @media (min-width: 768px) {
      ${css(md, ...interpolations)}
    }
  `,
  lg: (
    lg: CSSObject | TemplateStringsArray,
    ...interpolations: SimpleInterpolation[]
  ): FlattenSimpleInterpolation => css`
    @media (min-width: 1024px) {
      ${css(lg, ...interpolations)}
    }
  `,
  xl: (
    xl: CSSObject | TemplateStringsArray,
    ...interpolations: SimpleInterpolation[]
  ): FlattenSimpleInterpolation => css`
    @media (min-width: 1280px) {
      ${css(xl, ...interpolations)}
    }
  `,
};

カラーを保管して置くファイルです。
入っている値は適当なので各自のサイトテーマカラーを入れてください

colors.ts
export const colors = {
  // 汎用カラー
  black: '#000',
  white: '#fff',

  //テーマカラー
  primary: '#de1671',
  secondary: '#090105',
  subcolor: '#34051a',

  //その他
};

フォントファミリーやサイズ、文字の太さの数値を保管しておきます。
こちらもTailwindCSSを参考に構成しました。

fonts.ts
export const fonts = {
  family: {
    sans: '"Open Sans", sans-serif',
  },
  size: {
    xs: '0.75rem',
    sm: '0.875rem',
    base: '1rem',
    lg: '1.125rem',
    xl: '1.25rem',
    xl2: '1.5rem',
    xl3: '1.875rem',
    xl4: '2.25rem',
    xl5: '3rem',
    xl6: '3.75rem',
    xl7: '4.5rem',
  },
  weight: {
    thin: 100,
    extralight: 200,
    regular: 300,
    normal: 400,
    medium: 500,
    semibold: 600,
    bold: 700,
  },
};

zindexの値を保管しておきます。
使わない人は要らないかもしれませんが、数値が適当になりやすいので明確化したい人は作成してください。

zindex.ts
export const zindex = {
  modal: 100,
  drawer: 50,
  floating: 40,
  header: 30,
  footer: 20,
  front: 10,
  defalt: 1,
  background: -10,
}

全部の設定を一つにまとめる

先ほど作成した設定ファイルを一つにまとめて設定しておきます。
他にも必要な設定がある場合はこちらに追記するだけで設定されます。

theme.ts
import { fonts } from './setting/fonts';
import { zindex } from './setting/zindex';
import { colors } from './setting/colors';
import { breakpoint } from './setting/breakpoint';

export const theme = {
  breakpoint: breakpoint,
  colors: colors,
  zindex: zindex,
  fonts: fonts,
};

ThemeProviderの設定

作成したthemeを適用する為に、ThemeProviderを設定します。
_app.tsxに設定するとグローバルに設定する事ができます。

_app.tsx
return (
  <ThemeProvider theme={theme}>
    <Component {...pageProps} />
  </ThemeProvider>
);

使い方

import styled from "styled-components"

export const Title = () => {
  return (
    <StyleTitle>
      Hello Next.js
    </StyleTitle>
  )
}

const StyleTitle = styled.h1`
  ${({ theme }) => theme.media.base`
    color: ${theme.colors.black};
    font-size: ${theme.fonts.size.xs};
  `}
  ${({ theme }) => theme.media.sm`
    color: ${theme.colors.white};
    font-size: ${theme.fonts.size.sm};
  `}
  ${({ theme }) => theme.media.md`
    color: ${theme.colors.primary};
    font-size: ${theme.fonts.size.base};
  `}
  ${({ theme }) => theme.media.lg`
    color: ${theme.colors.secondary};
    font-size: ${theme.fonts.size.lg};
  `}
  ${({ theme }) => theme.media.xl`
    color: ${theme.colors.subcolor};
    font-size: ${theme.fonts.size.xl};
  `}
`

メリット・デメリット

メリット

  • 値の統一化がしやすい
  • レスポンシブが簡単に出来る
  • 簡単に設定できる

デメリット

  • VSCodeの補完機能が使えない
  • 書くのが面倒

参考資料

https://zenn.dev/nbr41to/articles/843535fb6e4e4f
https://zenn.dev/hirokikameda/articles/675999fe06c3fe