クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【React】styled-componentsのcreateGlobalStyleでbodyタグにCSS設定(Reactとメタ言語の比較-4)

Reactの続きです。前回はJSONデータをJSXに読み込んで表示しました。今回からはCSS編に入っていきます!メタ言語スターターキットのSass(SCSS)の設定をCSS in JSに組み込んでいきます。今回はstyled-componentsのcreateGlobalStyleでbodyタグにCSSを設定します。それではいきましょう!

【目次】

※参考:前回記事
【React】JSONデータをJSXに読み込んで表示する(Reactとメタ言語の比較-3) - クモのようにコツコツと

※参考:Reactを習得するためにやったことまとめ
qiita.com

前回のおさらい

前回、メタ言語スターターキットのEJSモジュールをJSXコンポーネント化した。EJSとほぼ同じ構成にできた。

https://cdn-ak.f.st-hatena.com/images/fotolife/i/idr_zz/20210202/20210202065525.jpg

※参考:【React】JSONデータをJSXに読み込んで表示する(Reactとメタ言語の比較-3) - クモのようにコツコツと

Sass(SCSS)をCSS in SJ(styled-components)に移行する

今回からはCSS編に突入!Sass(SCSS)をCSS in SJ(styled-components)に移行する。

Sass(SCSS)モジュールはEJSモジュールとほぼ同じ構成で作った。class名をBEM記法でつけていた。

※参考:【メタ言語】フロントエンド開発スターターキットを作った(EJS、Sass(SCSS)、TypeScript) - クモのようにコツコツと

styled-componentsはこの環境にすでにインストールしてある。

※参考:【React】React + TypeScript + CSS in JSの開発環境を作る(Gitエラー対処も) - クモのようにコツコツと

styled-componentsはコンポーネントに直接スタイルを設定できるので、BEMのclass名がどうなっていくのか確かめたい。

CSS(index.tsx)のリンクを切る

これまで「index.tsx」で「index.css」をインポートしていた。(index.cssの内容はメタ言語スターターキットからコンパイルしたスタイル)

※参考:react-from-meta-lang/index.css at 90ccf46c70cbfe09aeb3e3b0fb2be51af15e8ae5 · ryo-i/react-from-meta-lang · GitHub

いったんこのCSSのリンクを切る!

// import './index.css';

ローカルでアプリ起動すると…

$ npm start

おお!生まれたまんまの姿にw f:id:idr_zz:20210209190331j:plain

bodyタグの隙間を無くしたい

ちょっと気になったのはbodyタグにブラウザデフォルトのmarginが入っていること。 f:id:idr_zz:20210209191320j:plain

これを無くしたいのだが、ReactのJSXはAppコンポーネントが起点になっているんだよなー

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

styled-componentsでbodyタグに設定できるのだろうか。


調べるとstyled-componentsにはグローバル設定(htmlタグやbodyタグ)をするためのcreateGlobalStyleという機能が用意されているらしい!

※参考:styled-components: API Reference

よし、いっちょやってみっかー

変数をJSONファイル化する

Sass(SCSS)ではモジュールを跨いで設定したい共通の値を「_variable.scss」というファイルに変数として設定した。

$base-color: #ff0000;
$text-color: #333;
$text-color_w: #fff;
$bg-color_g: #eee;
$text-size: 14px;

※参考:【メタ言語】フロントエンド開発スターターキットを作った(EJS、Sass(SCSS)、TypeScript) - クモのようにコツコツと


これとほぼ同じ構成でJSON化する。「src」フォルダに「css_variables.json」というファイルを保存。

{
    "variable": {
        "baseColor": "#ff0000",
        "textColor": "#333",
        "textColor_w": "#fff",
        "bgColor_g": "#eee",
        "textSize": "14px"
    }
}

なお、base-という名前だと下記のエラーになったためキャメルケースにした。

Property 'base' does not exist on type '{ "base-Color": string; // (中略) }'.  TS2339

styled-componentsと変数のJSONファイルをインポート

「index.tsx」にstyled-componentsと先ほど作った変数のJSONファイル(css_variables.json)をインポートする。

import styled from 'styled-components';
import cssVariables from './css_variables.json'

変数variavleで冒頭のvariableキーまでを取得する。

const variavle = cssVariables.variable;

createGlobalStyleでグローバルスタイルを設定

Sass(SCSS)ではグローバルな設定は「_base.scss」に設定していた。

body {
    margin: 0;
    padding: 0;
    font-family: sans-serif;
    font-size: $text-size;
    color: $text-color;
    *, *:before, *:after {
        box-sizing: border-box;
    }
    a {
        color: $base-color;
    }
}

$text-size$text-colorで変数を読み込んでいる。

※参考:【メタ言語】フロントエンド開発スターターキットを作った(EJS、Sass(SCSS)、TypeScript) - クモのようにコツコツと


styled-componentsのcreateGlobalStyleを使ってグローバルスタイルを設定する。

※参考:styled-components: API Reference

変数GlobalStyle

const GlobalStyle = createGlobalStyle`
  body {
    margin: 0;
    padding: 0;
    font-family: sans-serif;
    font-size: ${variable.textSize};
    color: ${variable.textColor};
    *, *:before, *:after {
        box-sizing: border-box;
    }
    a {
        color: $base-color;
    }
  }
`;

変数textSizetextColorはプレースホルダーを使って読み込む。

※参考:【React】styled-componentsでCSS in JSを事始める - クモのようにコツコツと

グローバルスタイルをコンポーネントとして配置

最後にAppコンポーネントと同じ場所にGlobalStyleコンポーネントを配置。

ReactDOM.render(
  <React.StrictMode>
    <GlobalStyle />
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

ブラウザで確認 f:id:idr_zz:20210209194247j:plain おお、bodyタグの隙間がなくなって文字がぴったりくっついた!w


ソース(GitHub)※今回のコミットまで

※参考:GitHub - ryo-i/react-from-meta-lang at 90ccf46c70cbfe09aeb3e3b0fb2be51af15e8ae5

プレビュー(GitHub Pages)

※参考:Reactとメタ言語の比較

最後に

ということでstyled-componentsのcreateGlobalStyleでbodyタグにCSS設定できましたー。コンポーネントの外に設定するという意味では以前react-helmetでheadタグを打ち替えたのを思い出しました。

※参考:【React】react-helmetでheadタグの中身を動的に打ち替える(Reactとメタ言語の比較-2) - クモのようにコツコツと

まあやったことはbodyタグの隙間を無くしただけで、まだ全然スタイルが当たってない、赤ちゃんみたいな状態ですw

これからstyled-componentsでコンポーネントに直接スタイルを当てて、元の姿に戻していきたく思います。それではまた!


※参考:前回記事
【React】JSONデータをJSXに読み込んで表示する(Reactとメタ言語の比較-3) - クモのようにコツコツと