💈

styled-jsx を使って UI コンポーネントのスタイルを変えたい場合の注意

2021/05/13に公開

Next.js 上で Semantic UI React という UI コンポーネントを使って、画面を作っているのだが、Next.js にビルドインされている CSS in JS の styled-jsx を使うと少し困ったことがある

import { Button } from 'semantic-ui-react'

const App: React.VFC = () => (
  <>
    <Button>Button A</Button>
    <Button>Button B</Button>
    <Button>Button C</Button>
    <style jsx>{`
      .ui.button {
        color: red;
      }
    `}</style>
  </>
)

export default App

上記はスタイルが効かない

色々調べたが、スタイルをグローバルセレクターにするしかなさそうだ
https://github.com/vercel/styled-jsx/issues/142
https://github.com/vercel/styled-jsx#one-off-global-selectors

以下のように書き換えるとスタイルが適用される

import { Button } from 'semantic-ui-react'

const App: React.VFC = () => (
  <>
    <Button>Button A</Button>
    <Button>Button B</Button>
    <Button>Button C</Button>
    <style jsx>{`
      :global(.ui.button) {
        color: red;
      }
    `}</style>
  </>
)

export default App

ただし、上記だとすべての.ui.buttonに対して同じスタイルが適用されてしまうので、CSS の class 属性を使って、スコープを絞った方が良い

import { Button } from 'semantic-ui-react'

const App: React.VFC = () => (
  <>
    <Button className="button-a">Button A</Button>
    <Button>Button B</Button>
    <Button>Button C</Button>
    <style jsx>{`
      :global(.button-a.ui.button) {
        color: red;
      }
    `}</style>
  </>
)

export default App

まとめ

  • :global構文を使ったグローバルセレクター化は避けられない
  • グローバルセレクター化した場合は、CSS の class 属性を使ってスコープを絞った方が良い

Discussion