ちょっとした技術メモを忘れないうちに書いていく

GatsbyJS CSSを指定する(CSS Modules)

2019-05-28

管理がそこそこ楽でプラグインを使わないスタイルの指定方法(CSS Modules)


GatsbyJSでCSSを指定する

GatsbyJSでCSSを別ファイルで管理する方法はCSS ModulesとCSS-in-JSという方法(チュートリアルではEmotionとStyled Componentsを紹介していました)があります。
今回はCSS Modulesについて説明します。 CSS Modulesはボタン、リンクなどの部品ごとにCSSファイルを作成し、管理を行います。 CSSを指定した要素のclass名は自動で重複しないため、CSSファイル間でclass名を気にしなくても大丈夫です。

サンプルページの作成

適用するページを作成します。

import React from "react"

export default () => (
    <div>
        <h1>Hello world!</h1>
        <p>Gatsbyでスタイル指定</p>
        
        <button>ボタン</button>
    </div>
)

ブラウザで表示するとこんな感じになっています。 gatsby_css_1.png

まずは直接CSSを指定する

直接指定する場合は各要素にstyle属性を追加し、CSSの内容をオブジェクトで指定します。 styleの中はキャメルケースで記述するので、max-widthはmaxWidthと記述します。

import React from "react"

export default () => (
    <div
        style={{
            margin: `auto`,
            maxWidth: `500px`,
            border: `1px #000000 solid`,
        }}
      >
        <h1
            style={{
                color: `aqua`,
            }}>
            Hello world!</h1>
        <p
            style={{
                fontSize: `60px`
            }}>
            Gatsbyでスタイル指定</p>

        <button
        style={{
                backgroundColor: `navy`,
                color: `white`,
                fontSize: `60px`

            }}>ボタン</button>
    </div>
)

これだけでけっこうな行数になりました。
ブラウザで確認して、CSSが適用されていることを確認します。 gatsby_css_2.png

CSS ModulesでCSSの内容を別ファイルで管理する

CSS Modulesを利用し、同じCSSの内容を別ファイルに移動します。
src/pagesにCSSを記述するファイルindex.module.css、button.module.cssを作成します。 index.module.cssにはページに対するCSS
button.module.cssにはボタンに対すCSSを記述します。
※CSS Modulesで扱うには拡張子は「.module.css」にする必要があります。

/* index.module.css */
.container {
    margin: auto;
    max-width: 500px;
    border: 1px #000000 solid;
}

.title {
    color: aqua;
}

.text {
    font-size: 80px;
}
/* button.module.css */
.normal {
    background-color: navy;
    color: white;
}

別ファイルのCSSを適用するため、index.module.cssをstylesとしてインポートします。
各要素にclassNameを追加し、index.module.cssの内容を指定します。

// index.js
import React from "react"
import styles from "./index.module.css"
import button from "./button.module.css"

export default () => (
    <div className={styles.container}>
        <h1 className={styles.title}>Hello world!</h1>
        <p className={styles.text}>Gatsbyでスタイル指定</p>
        <button className={`${button.normal} ${styles.text}`}>ボタン</button>
    </div>
)

button要素の様にCSS Modulesで複数指定したい場合は、テンプレートリテラルを使います。
ブラウザで確認すると、CSSが適用されています。 gatsby_css_3.png

出力されたHTMLを表示すると、class名が自動で出力されていることが確認できます。

html_code.png

CSS Modulesで要素に対してCSSを記述する時は注意

CSS Modulesは部品へのCSS適用を目的としていますが、要素に対してCSSを指定することも可能です。
この場合、importしたコンポーネントの要素にも適用されてしまうので注意が必要です。