styled-componentsのスタイル拡張について

2018年度に新卒で入社した東度です。配属当初はRailsでサーバーサイドを書いていたのですが、最近はReactでフロントを書いています。

自社プロダクトの一つであるVIDEO BRAINでは、CSS in JSのライブラリの一つであるstyled-componentsを使ってスタイリングをしているのですが、中でも度々登場するスタイル拡張について自身の勉強も兼ねて記事をまとめてみました。

styled-componentsとは

現在、CSS in JSの中で最も人気のあるライブラリで、要素にスタイルを付加したコンポーネントが作成できるというのが特徴です。

styled.div``のように記述すると、div要素にタグ付きテンプテートリテラル内のスタイルを付加したコンポーネントが返される仕組みとなっています。

以下の例では、button要素にスタイルを当てたButtonコンポーネントを定義しています。 定義したButtonコンポーネントを呼び出すと以下のボタンが出力されます。

// Button.js
import styled from 'styled-components';

export const Button = styled.button`
  margin: 1em;
  padding: 0.25em 1em;
  border: none;
  outline: none;
  border-radius: 3px;
  color: #fff;
  background-color: #404143;
`;

Image from Gyazo

スタイル拡張について

styledされたコンポーネントに対してstyled()コンストラクタでラップすると、スタイルを拡張した新しいコンポーネントを作成することができます。

例えばButtonコンポーネントの場合、色やサイズなどを調整して新しいコンポーネントを作成したい場合などがあるかと思います。以下の例ではButtonコンポーネントを継承し、スタイルを拡張した新しいボタン作成しています。

// Button.js
import styled from 'styled-components';

export const Button = styled.button`
  margin: 1em;
  padding: 0.25em 1em;
  border: none;
  outline: none;
  border-radius: 3px;
  color: #fff;
  background-color: #404143;
`;

export const RedButton = styled(Button)`
  background-color: #ff0000;
`;

export const GreenButton = styled(Button)`
  background-color: #00ff00;
`

export const BlueButton = styled(Button)`
  background-color: #0000ff;
`

Image from Gyazo

次に、styledされていないコンポーネントに対してスタイルを拡張する方法を紹介します。

styled-componentsでは、classNameに指定したスタイルを渡すことでスタイルを適用しています。 styledされていないコンポーネントに対しては、以下のように、propsで渡されたclassNameをコンポーネントのDOM要素に適用することで、スタイル拡張が行えるようになります。

// Hello.js
import React from 'react';
import styled from 'styled-components';

export function Hello({className, children}) {
  return(
    <a className={className}>
      {children}
    </a>
  );
}
export const StyledHello = styled(Hello)`
  color: #7F9DB5;
  font-size: 30px;
  font-weight: bold;
`; 
// App.js
import React, { Component } from 'react';
import { Hello, StyledHello } from './Hello.js'

class App extends Component {
  render() {
    return (
      <div>
        <Hello>Hello</Hello>
        <br />
        <StyledHello>Hello</StyledHello>
      </div>
    );
  }
}

export default App;

Image from Gyazo

まとめ

今回はstyled-componentsを使ったスタイル拡張について記事をまとめました。今後React等に触れていく中で、得られた知見などを共有できたらと思います。

最後に、告知になるのですが1月29日(火)に「スタートアップテック vol.2:スタートアップとフロントエンド」が開催されます。 弊社からも澤木(@ayatas0623)が「reduxのstate設計の話」について発表します。彼の勇姿を是非ご観覧ください!

イベントの詳細については下記のリンクからご確認ください。

connpass.com