今日は、Reactを採用したプロジェクトでは最も人気のある「styled-component」について、エンジニア初心者、もしくはバックエンドエンジニア向けに解説します。
僕は、ピュアなReactのプロジェクト以外にも、GatsbyJS, Next.js, Material-UIなどを導入したプロジェクトでも、「styled-component」を使っています。
「styled-component」は、CSS in JS の使い難い部分を解決してくれる最高のライブラリです。初心者向けに解説していきますが、前提として、Reactのコンポーネントを例に解説していきますので、React、CSS、そしてSassを程度理解している必要があります。
Contents
CSS in JSとは何か?
まずは、さらっと「CSS in JS」について説明しておきます。
CSS in JSとは読んで字の如く、.jsのJavaScriptファイルにCSSを書いていこうというものです。このような設計にすることにより、コンポーネントごとにコードを切り離して開発することができます。例えば、 header.jsというファイルに、ReactとCSSをまとめて書くことにより、コンポーネント思考の開発が可能になります。
コンポーネント思考の開発によるメリットは、
- UIテストが書きやすくなる
- コードのメンテナンス性が向上する
などが挙げられます。
具体例を挙げると、CSSを書くときにも、長ったらしい命名規則を気にする必要はなくなるし、必要ではなくなったレガシーなCSSを自信を持って削除できるようになるでしょう。
このように、コンポーネント思考の開発はエンジニアにとって開発のストレスを軽減できる ナイスな手法ですが、CSS in JSが流行り出した2016年ごろには、「styled-component」のようなライブラリーは存在しておらず、CSS in JS では、まだまだ不便な点が多かった記憶があります。その一番の理由が、オブジェクトリテラルによるCSSの記述です。以下で、オブジェクトリテラルについて具体的例を挙げておきます。
CSSをオブジェクトリテラルで書くとは?
CSS in JSは、あくまで.jsファイルにCSSを書いていくので、通常はオブジェクトリテラルで書いていきます。つまり、CSSをJSのオブジェクトを記述するように書いていくということです。
コード例を挙げておきます。
CSS in JSでのオブジェクトリテラルでの例
import React from 'react';
import styled from 'styled-components';
// ここがstyled-componentを使っている箇所で,オブジェクトリテラルで記述。
const Heading = styled.h1({
color: "red",
fontSize: "32px",
textAlign: "center"
});
const App = () => (
<section>
<Heading>
Hello Heading!!!
</Heading>
</section>
);
export default App;
上記のコード例のHeading コンポーネントに注目してください。通常は、CSSファイルでは、font-sizeと記述しますが、このオブジェクトリテラルで記述すると、fontSizeとなります。また、CSSのバリュー部分は、クォーテーション(“”)で囲う必要があります。そして、通常のCSSでは、末尾はセミコロン(;)ですが、ここではカンマ(、)となります。
別の問題点として、CSSとは記述が異なるので、クロムコンソールなどからCSSをコピペして直接貼り付けるというようなことができません。貼り付けた後に、いちいちオブジェクトリテラルへ整形する必要があります。これが相当に面倒臭く、つまらない作業となります。
以上、「CSS in JSでオブジェクトリテラルで記述するさいの苦痛ポイント」をまとめると、
- 通常のCSSではfont-sizeと記述するが、オブジェクトリテラルで記述するとfontSizeとなる
- CSSのバリューの部分は、クォーテーション(“”)で囲う必要がある
- 通常のCSSでは、末尾はセミコロン(;)、オブジェクトリテラルではカンマ(、)となる
- CSSとは記述が異なるので、クロムコンソールなどからCSSをコピペして直接貼り付けることが出来ない(その後成形する必要がある)
「styled-component」は、上記の問題を解決するために、通常のCSSのように記述できるテンプレートリテラルによる書き方も提供してくれます。テンプレートリテラルによる書き方が推奨されているわけではありませんが、僕の周りのエンジニア、僕の関わってきたプロジェクトでは、全てテンプレートリテラルで記述しています。
ちなみにテンプレートリテラルとは、「styled-component」の独自の機能ではなく、ES6の仕様ですので、気になる方はMDNのテンプレートリテラルを一読ください。
それでは、「styled-component」を利用する利点、テンプレートリテラルによる実際の使い方を見ていきましょう。
「styled-component」の何が便利なのか?
「styled-component」を使うことによる利点をあげます。
- CSSプリプロセッサのstylisが組み込まれているので、SassのSCSS記法で記述できる。ちなみに、SassにはSCSS記法とSass記法がありますが、SCSS記法がメジャーです。
- ベンダープレフィックスも自動で追加されるので、自分でいちいち書く必要がない。ベンダープレフィックスとは、「-moz-や、-webkit-」のことで、クロムなどの各ブラウザで先行実装されている機能を使うための接頭辞。
- テンプレートリテラルでかける。オブジェクトリテラルで書く必要がない。
「styled-component」の使い方
それでは、実際に「styled-component」を使ったテンプレートリテラルによるReactコンポーネントへのスタイリングを見ていきましょう。
【超基本】HTML要素にスタイルを付けたコンポーネント
この例では、button要素にbackground-color
とpadding
のスタイリングをあてています。
import React from 'react';
import styled from 'styled-components';
// button要素にスタイルを当てたコンポーネントを作成
const ButtonInner = styled.button`
background-color: blue;
font-size: 1.3rem;
padding: 6px 16px;
`;
const Button = (props) => (
<ButtonInner>{props.children}</ButtonInner>
);
export default Button;
propsをわたしコンポーネントのスタイリングを切り替える
tureかfalseの2パターンを切り替える
まずはシンプルなtrueかfalseの2パターンを切り替えるケースです。例えば、セレクトされたボタンのスタイリングを切り替えるために、isSelectedというpropsをわたし、スタイルを切り替えるケースを見ていきましょう。
import React from "react";
import styled, { css } from "styled-components";
const ButtonInner = styled.button`
/* isSelected props の真偽によりスタイルを切り替える */
background-color: ${(props) => (props.isSelected ? "red" : "blue")};
font-size: 1.3rem;
padding: 6px 16px;
`;
const Button = (props) => (
<ButtonInner {...props}>{props.children}</ButtonInner>
);
const App = () => (
<section>
<Button />
<Button isSelected />
</section>
);
export default App;
3パターン以上あるときには{ css } from ‘styled-components’を使う
Buttonコンポーネントにsmall、largeのpropsをわたし、それによりスタイリングを切り替えていきます。つまり、small、largeを指定しない時は、デフォルトのサイズ、指定した時は、それぞれのスタイリングが適用される仕組みです。念のためですが、下の例では、デフォルトのスタイリングをトップに持ってきて、その下に、small, largeそれぞれのスタイリングを指定しています。もし、デフォルトのスタイリングをを最下部に持ってくると常にそのスタイリングが適用されますので、注意してください。
import React from "react";
import styled, { css } from "styled-components";
// button要素にスタイルを当てたコンポーネントを作成
const ButtonInner = styled.button`
background-color: blue;
font-size: 1.3rem;
padding: 6px 16px;
${(props) =>
props.small &&
css`
font-size: 1.2rem;
padding: 4px 10px;
`};
${(props) =>
props.large &&
css`
font-size: 1.4rem;
padding: 8px 22px;
`};
`;
const Button = (props) => (
<ButtonInner {...props}>{props.children}</ButtonInner>
);
const App = () => (
<section>
<Button small />
<Button large />
</section>
);
export default App;
というように、スタイリングの切り替えも簡単です。
スタイリングは同じだが、異なるHTMLタグを使いたいとき
例えば、ボタンというコンポーネントを例に説明します。ひとえに、ボタンと言ってもその役割は様々です。
例をあげると、
- ボタンの見た目をしたボタン(商品をカートにいれるボタンなど)
- ボタンの見た目をしているが、実際の役割は他のページへ遷移するためのリンク
①ではbuttonタグを使うべきでしょう。②ではa要素かReactでは<Link />を使うべきです。
一方で、プロジェクトの中でボタンの基本的なスタイリングは同じはずです。例えば、padding、font-weight, colorなどです。(もちろん、上記で紹介したようなボタンのステート変更によるスタイリングの切り替えは必要ですが。)
こんなときに役立つのが「as」prop です。
import React from "react";
import styled, { css } from "styled-components";
// button要素にスタイルを当てたコンポーネントを作成
const ButtonInner = styled.button`
background-color: blue;
font-size: 1.3rem;
padding: 6px 16px;
`;
const Button = (props) => (
<ButtonInner {...props}>{props.children}</ButtonInner>
);
// ボタンのスタイリングはそのままに、HTML tag を anchor tagに変更。
const LinkButton = (props) => (
<Button as="a" {...props}>
{props.children}
</Button>
);
export { Button, LinkButton };
という感じで、as propをパスしてHTMLタグを簡単に変更可能です。何もパスしなければ、デフォルトのbuttonタグを使うという感じです。
ボタン以外の使い所としては、ナビゲーションバーのチルドレンなどが考えられます。
styled-componentsを体系的に学びたい方におすすめのオンラインコース
「styled-components」には、上記で紹介したような基本的な内容だけでなく、他にも便利な機能がたくさんあります。「styled-components」を体系的に学びたい方向けに、「React styled-components v5 (2020 edition) 」というオンラインコースを紹介しておきます。
このコースをおすすめする理由は、
- 動画ベースですので、初心者にもついていきやすい。
- 「styled-components」のコードサンプルがたくさん手にはいるので、それを他のプロジェクトや仕事でも生かせる。
- すでに最新バージョン5に対応している。このスピード感で更新されるような教材は、日本語圏には、僕の知る限りない。
- 基本的な機能だけでなく、発展的な内容も含まれており、フロントエンドエンジニアのスキルを磨くには最適。
といった感じです。英語のコースですが、エンジニアを目指す、もしくはエンジニアであるならば、英語は勉強しておくことを強くおすすめします。日本語だけでWEB検索していたら、それだけで相当な遅れをとってしまいますし、英語がある程度できると、非日系企業への就職など、仕事の選択肢も大幅に広がります。
まとめ
「styled-components」は、React プロジェクトに相性抜群のライブラリです。「styled-components」を導入し、快適なフロントエンド環境を構築していきましょう。
[…] styled-componentsの使い方【初心者向け】|Watablog […]