😺

Reactでのstyled-components(CSS-in-JSを使ったスタイリング)

に公開

最初に

2024年8月1日に投稿した記事です。諸事情によりこちらに投稿します。

styled-components

CSS-in-JSという手法で、コンポーネント内にCSSも一緒に書くものです。
その中でもstyled-componentsという
ライブラリを使うstyled-componentsを使った手法がります。

メリット

  • css, class, id の管理が(比較的)楽になってくる
  • ローカルスコープなスタイルができる

アプリケーションが拡大してくるとCSSの管理が大変になることが多く、
class名をあてる必要がないので、styled-componentを定義し、中身を変えるだけということができます。

ex)

const Wrapper = styled.div`
  margin: 32px;
`;

...

export const FooComponent = () => (
  <Wrapper>
    <Button />
  </Wrapper>

const Wrapper = styled.div`
  margin: 16px;
`;

...

export const FooComponent = () => (
  <Wrapper>
    <Button />
  </Wrapper>

styles-componentsをインストール

以下のコマンドでstyles-componentsをインストールします。

npm install styled-components

TypeScriptで実装する場合は@types/styled-componentsもインストールします。
package.jsonに記載されていればOKです。

{
  "dependencies": {
    "styled-components": "^6.1.12"
  }
}

拡張機能

VSCodeに拡張機能として、以下のツールを入れるといいです。

styled-components.vscode-styled-componentsです。

スクリーンショット 2024-08-01 18.48.28.png

これを入れるとコンポーネントを使う時にハイライト機能がかかるみたいで、コードの整形に役に立つみたいです‼︎

Styled-components導入

以下のコードで導入しました。
CSSをStyle-Buttonの中に導入して、 <StyledButton の中に下のコードのように記述しました。

import { useState } from "react";
import styled from "styled-components";//インポート

const StyledButton = styled.button `//タグ付きテンプレート
  margin: auto;
  border-radius: 9999px;
  border: none;
  display: block;
  width: 120px;
  height: 60px;
  font-weight: bold;
  cursor: pointer;
  background: ${({isSelected}) => isSelected ? 'pink' : ''};
`;
const Example = () => {
  const [isSelected, setIsSelected] = useState(false);

  const clickHandler = () => setIsSelected((prev) => !prev);

  return (
    <>
      <StyledButton isSelected={isSelected} onClick={clickHandler}>ボタン</StyledButton>
      <button
        className={`btn ${isSelected ? "selected" : ""}`}
        onClick={clickHandler}
      >
        ボタン
      </button>
      <div style={{ textAlign: "center" }}>
        {isSelected && "クリックされました。"}
      </div>
    </>
  );
};

export default Example;

動作確認

  • クリック前

<img width="729" alt="スクリーンショット 2024-08-01 19 26 31" src="https://github.com/user-attachments/assets/cb968b7d-a422-46f9-a93a-24ab39c531f2">

  • クリック後

<img width="719" alt="スクリーンショット 2024-08-01 19 24 47" src="https://github.com/user-attachments/assets/ad1459dc-34c5-4574-b379-f1d3db01f159">

継承

継承でボタンなどを使いまわすこともできます。
緑色のボタンを追記してホバーしたら赤色になるようにしました。

import { useState } from "react";
import styled from "styled-components";

const StyledButton = styled.button `//タグ付きテンプレート
  margin: auto;
  border-radius: 9999px;
  border: none;
  display: block;
  width: 120px;
  height: 60px;
  font-weight: bold;
  cursor: pointer;
  background: ${({isSelected}) => isSelected ? 'pink' : ''};
`;
//以下追記 
const GreenButton = styled(StyledButton)`
  background-color: green;

  :hover {
    color: red;
    opacity:0.7;
  }

  span {
    font-size:1em;
  }
`;

const Example = () => {
  const [isSelected, setIsSelected] = useState(false);

  const clickHandler = () => setIsSelected((prev) => !prev);

  return (
    <>
      <StyledButton isSelected={isSelected} onClick={clickHandler}>ボタン</StyledButton>
//追記 <GreenButton isSelected={isSelected} onClick={clickHandler}><span>サブボタン</span></GreenButton>
      <button
        className={`btn ${isSelected ? "selected" : ""}`}
        onClick={clickHandler}
      >
        ボタン
      </button>
      <div style={{ textAlign: "center" }}>
        {isSelected && "クリックされました。"}
      </div>
    </>
  );
};

export default Example;

スクリーンショット 2024-08-01 19.44.50.png

資料

https://www.udemy.com/course/react-complete-guide/?couponCode=LEADERSALE24B

https://github.com/styled-components/styled-components

Discussion