Next.js コンポーネントのスタイリングを学ぼう

こんにちは、Yuuichi(@WestHillWorker)です。

今までは特にデザイン部分に触れてくる部分を学習しなかったため、今回はデザインをスタイルする部分についてやっていこうと思います。

前回作成した天気予報のアプリにデザインを足していこうと思います。

スポンサーリンク

スタイリングについて

1つめは、CSSファイルベースのスタイル(SASSやPostCSSなどを含む)方法。

cssファイルをjsには含めないで別ファイルでインポートする方法になります。

2つめは、JSでCSSスタイルを含める方法です。1の別ファイルでスタイルする方法では、SSRを使用した際に考慮するべき問題が多いため、1の方法についてはNext.jsではお勧めしていないです。

上記の点より、2つめの個々のコンポーネントでスタイルできるJSでCSSを含めた方法について学んでいきます。

styled-jsx

Next.jsを作成したzeitのOSSとして提供されているstyled-jsxでコンポーネントに簡単にスタイルを定義できる機能があるため、こちらで実装していきましょう。

スタイルをあててきます

コンポーネントにスタイルをあてるため、<style jsx>という要素の内部にCSSを記述します。

pages/index.jsにstyle jsxを記述

トップページのpages/index.jsにスタイルを記述します。

import Layout from '../components/Layout';
import Link from 'next/link';
import fetch from 'isomorphic-unfetch';
const Index = props => {
  return (
    <Layout>
      <h1>天気予報 ニュース</h1>
      <ul>
        {props.wethers.map(wether => (
          <li key={wether.id}>
            <Link href="/wether/[id]" as={`/wether/${wether.id}`}>
              <a>{wether.location}</a>
            </Link>
          </li>
        ))}
      </ul>
      <style jsx>
        {`
        h1,
        a {
          font-family: 'Arial';
        }
        ul {
          padding: 0;
        }
        li {
          list-style: none;
          margin: 5px 0;
        }
        a {
          text-decoration: none;
          color: blue;
        }
        a:hover {
          opacity: 0.6;
        }
      `}
      </style>
    </Layout>
  )
};
Index.getInitialProps = async function () {
  const response = await fetch('http://localhost:3000/api/wether');
  const data = await response.json();
  console.log(`Show data fetched. Count: ${data.length}`);
  console.log(data);
  return {
    wethers: data
  };
}
export default Index;

肝になる点としては<style jsx>{`記述したいスタイル`}</style>となります。

他のcomponentsにもスタイルをあてる

せっかくなので、pages/wether/[id].jsにもスタイルをあててみましょう。

import Layout from '../../components/Layout';
import fetch from 'isomorphic-unfetch';
const Wether = props => (
  <Layout>
    <h1>{props.wether.location}の天気</h1>
    <p>{props.wether.wether}</p>
    <p>{props.wether.temperature}</p>
    <style jsx>
      {`
        h1,
        a {
          font-family: 'Arial';
        }
        p,
        a {
          color: black;
          font-family: 'Arial';
        }
    `}
    </style>
  </Layout>
);
Wether.getInitialProps = async function (context) {
  const { id } = context.query;
  const response = await fetch(`http://localhost:3000/api/wether?id=${id}`);
  const wether = await response.json();
  console.log(`Fetched wether: ${wether.id} ${wether.location}`);
  return { wether };
};
export default Wether;

先ほどのindex.jsと同じように<style jsx>{`記述したいスタイル`}</style>で記述します。

これで表示したいcomponents別でスタイルあてが完了となります。

ブラウザで確認

$ yarn dev
http://localhost:3000/

都道府県名の色が変わっていたりして、スタイルが変わっていると思います。

余談ですが、globalにスタイリングする方法については、以下の公式サイトでご参照ください。

Global Styles

お疲れ様でした!