๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
ํ”„๋ก ํŠธ์—”๋“œ/React

styled-components

by alswlfl 2022. 12. 8.

styled-components: JS ์•ˆ์— CSS๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (CSS in JS ๊ด€๋ จ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ค‘ ๊ฐ€์žฅ ์ธ๊ธฐ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)

emotion, styled-jsx

Tagged Template Literal

: ๋ฌธ์ž์—ด ์กฐํ•ฉ์„ ๋”์šฑ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ES6 ๋ฌธ๋ฒ•

  • Template Literal ์‚ฌ์šฉ ํ•  ๋•Œ, ${} ์•ˆ์— ์ผ๋ฐ˜ ๋ฌธ์ž์—ด์ด๋‚˜ ์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๊ฐ์ฒด๋ฅผ ๋„ฃ๋Š” ๊ฒฝ์šฐ
const object = {a:1};
const text = `${object}`
console.log(text);
// "[object Object]"
Tmeplate Literal: ๋‚ด์žฅ๋œ ํ‘œํ˜„์‹์„ ํ—ˆ์šฉํ•˜๋Š” ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด → ์—ฌ๋Ÿฌ ์ค„๋กœ ์ด๋ค„์ง„ ๋ฌธ์ž์—ด๊ณผ ๋ฌธ์ž ๋ณด๊ฐ„ ๊ธฐ๋Šฅ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
• ๋ฐฑํ‹ฑ(` `
  • Template Literal์— ํ•จ์ˆ˜ ๋„ฃ๋Š” ๊ฒฝ์šฐ
const fn = () => true
const msg = `${fn}`;
console.log(msg);
// "() => true"

Template Literal ์‚ฌ์šฉํ•˜๋ฉด์„œ, ๊ทธ ๋‚ด๋ถ€์— ๋„ฃ์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ’ ์กฐํšŒํ•˜๊ฑฐ๋‚˜ ํ•จ์ˆ˜ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ Tagged Template Literal ๋ฌธ๋ฒ• ์‚ฌ์šฉ

const red='๋นจ๊ฐ„์ƒ‰';
const blue='ํŒŒ๋ž€์ƒ‰';
function favoriteColors(texts, ...values){
	console.log(texts);
    console.log(values);
}
favoriteColors `์ œ๊ฐ€ ์ข‹์•„ํ•˜๋Š” ์ƒ‰์€ ${red}๊ณผ ${blue}์ž…๋‹ˆ๋‹ค.`

styled-components ์‚ฌ์šฉ

  • ์Šคํƒ€์ผ์„ ์ž…๋ ฅํ•จ๊ณผ ๋™์‹œ์— ํ•ด๋‹น ์Šคํƒ€์ผ์„ ๊ฐ€์ง„ ์ปดํฌ๋„ŒํŠธ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ
  • ex) div ์Šคํƒ€์ผ๋งํ•˜๊ณ  ์‹ถ์œผ๋ฉด styled.div, input ์Šคํƒ€์ผ๋งํ•˜๊ณ  ์‹ถ์œผ๋ฉด styled.input
import React from "react";
import styled from "styled-components";

const Circle = styled.div`
  witdh: 5rem;
  height: 5rem;
  background: black;
  border-radius: 50%;
`;

function App() {
  return <Circle />;
}

export default App;
  • props ๋„ฃ๊ธฐ
const Circle = styled.div`
  witdh: 5rem;
  height: 5rem;
  background: ${(props) => props.color || "black"};
  border-radius: 50%;
`;

→ props ๊ฐ’์„ ์„ค์ •ํ•ด์คฌ์œผ๋ฉด, ํ•ด๋‹น ๊ฐ’์„ ๋ฐฐ๊ฒฝ์ƒ‰์œผ๋กœ ์„ค์ •ํ•˜๊ณ  ์„ค์ • ์•ˆํ–ˆ์œผ๋ฉด ๋ฐฐ๊ฒฝ์ƒ‰์„ ๊ฒ€์ •์ƒ‰์œผ๋กœ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค์ •

  • ์—ฌ๋Ÿฌ ์ค„์˜ CSS ์ฝ”๋“œ๋ฅผ ์กฐ๊ฑด๋ถ€๋กœ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ, css ์‚ฌ์šฉ(์Šคํƒ€์ผ ๋‚ด๋ถ€์—์„œ๋„ ๋‹ค๋ฅธ props ์กฐํšŒ ๊ฐ€๋Šฅ)
const Circle = styled.div`
  witdh: 5rem;
  height: 5rem;
  background: ${(props) => props.color || "black"};
  border-radius: 50%;
  ${(props) =>
    props.huge &&
    css`
      width: 10rem;
      height: 10rem;
    `}
`;
  • polished ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์Šคํƒ€์ผ ๊ด€๋ จ ์œ ํ‹ธ ํ•จ์ˆ˜ ์‚ฌ์šฉ
$ yarn add polished
import { darken, lighten } from "polished";

const StyledButton = styled.button`

  /*์ƒ‰์ƒ*/
  background: #228be6;
  &:hover {
    background: ${lighten(0.1, "#228be6")};
  }
  &:active {
    background: ${darken(0.1, "#228be6")};
  }
`;
  • ThemeProvider ๊ธฐ๋Šฅ ์‚ฌ์šฉํ•˜์—ฌ styled-component๋กœ ๋งŒ๋“œ๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์—์„œ ์กฐํšŒํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ „์—ญ์ ์ธ ๊ฐ’ ์„ค์ •
import React from "react";
import styled, { ThemeProvider } from "styled-components";
import Button from "./components/Button";

const AppBlock = styled.div`
  width: 512px;
  margin: 0 auto;
  margin-top: 4rem;
  border: 1px solid black;
  padding: 1rem;
`;

function App() {
  return (
    <ThemeProvider
      theme={{
        palette: {
          blue: "#228be6",
          gray: "#495057",
          pink: "#f06595",
        },
      }}
    >
      <AppBlock>
        <Button>BUTTON</Button>
      </AppBlock>
    </ThemeProvider>
  );
}

export default App;

theme ์„ค์ •ํ•˜๋ฉด ThemeProvider ๋‚ด๋ถ€์— ๋ Œ๋”๋ง๋œ styled-components๋กœ ๋งŒ๋“  ์ปดํฌ๋„ŒํŠธ์—์„œ palette๋ฅผ ์กฐํšŒํ•˜์—ฌ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

  ${(props) => {
    const selected = props.theme.palette[props.color];
    return css`
      background: ${selected};
      &:hover {
        background: ${lighten(0.1, selected)};
      }
      &:active {
        background: ${darken(0.1, selected)};
      }
    `;
  }}

→ ThemeProvider๋กœ ์„ค์ •ํ•œ ๊ฐ’์€ styled-component์—์„œ props.theme๋กœ ์กฐํšŒ ๊ฐ€๋Šฅ

  • ํŠธ๋žœ์ง€์…˜ ํšจ๊ณผ → CSS Keyframe ์‚ฌ์šฉ
    • ์‚ฌ๋ผ์ง€๋Š” ํšจ๊ณผ ๊ตฌํ˜„(๋‘ ๊ฐœ์˜ ๋กœ์ปฌ ์ƒํƒœ ๊ด€๋ฆฌ ํ•„์š”)
      • animate: ํ˜„์žฌ ํŠธ๋žœ์ง€์…˜ ํšจ๊ณผ๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ๋Š” ์ค‘์ด๋ผ๋Š” ์ƒํƒœ๋ฅผ ์˜๋ฏธ
      • localVisible: ์‹ค์ œ๋กœ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ๋ผ์ง€๋Š” ์‹œ์ ์„ ์ง€์—ฐ์‹œํ‚ค๊ธฐ ์œ„ํ•œ ๊ฐ’