Styled-components

์œค์„œยท2023๋…„ 9์›” 27์ผ
0

[Nomad Coders] React JS Master Class

๋ชฉ๋ก ๋ณด๊ธฐ
1/5

๐Ÿ“š Styled-components

Styled-components๋ž€?

JS ๋‚ด์—์„œ CSS ์ฝ”๋“œ๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ. ๋ฆฌ์•กํŠธ๋กœ ๊ฐœ๋ฐœํ•˜๋‹ค ๋ณด๋ฉด ๊ต‰์žฅํžˆ ๋งŽ์€ ํŽ˜์ด์ง€ ํŒŒ์ผ๋“ค๊ณผ ํƒœ๊ทธ๋“ค์ด ์ƒ๊ธธ ์ˆ˜๋ฐ–์— ์—†๋Š”๋ฐ, CSS ํŒŒ์ผ์„ ๋”ฐ๋กœ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ Class name์„ ๊ณ ๋ฏผํ•˜์ง€ ์•Š์•„๋„ ๋˜๋ฏ€๋กœ ๋งค์šฐ ํŽธ๋ฆฌํ•˜๋‹ค. โœจ

์„ค์น˜

npm install styled-components

yarn add styled-components

์„ค์น˜ ํ›„ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” JS ํŒŒ์ผ ๋‚ด์—
๐Ÿ‘‰๐Ÿป ย import styled from 'styled-components';

๋ฌธ๋ฒ•

const (์‚ฌ์šฉํ•  ์ปดํฌ๋„ŒํŠธ๋ช…) = styled.(ํƒœ๊ทธ๋ช…)`
CSS code ~ ..

โœ… CSS ์ฝ”๋“œ๋Š” ๊ผญ ๋ฐฑํ‹ฑ ``์œผ๋กœ ๊ฐ์‹ธ์ค˜์•ผ ํ•œ๋‹ค. ๋˜ํ•œ ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„์ด๊ธฐ ๋•Œ๋ฌธ์— ์‹œ์ž‘์€ ๋Œ€๋ฌธ์ž๋กœ!

์˜ˆ์‹œ

import styled from "styled-components";
function App() {
  const Father = styled.div`
    display: flex;
  `;
  const BoxOne = styled.div`
    background-color: teal;
    width: 100px;
    height: 100px;
  `;
  const BoxTwo = styled.div`
    background-color: tomato;
    width: 100px;
    height: 100px;
  `;
  const Text = styled.span`
    color: white;
  `;

  return (
    <Father>
      <BoxOne>
        <Text>Hello</Text>
      </BoxOne>
      <BoxTwo />
    </Father>
  );
}

export default App;

์ถœ๋ ฅ ํ™”๋ฉด

์œ„ ์ฝ”๋“œ๋Š” ํ™”๋ฉด๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค. ๊ธฐ์กด์˜ CSS ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•ด์„œ style์„ ์ฃผ๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ์ง๊ด€์ ์ด๊ณ  ํƒœ๊ทธ์˜ ์ค‘๋ณต์„ฑ์ด ์—†์–ด์ง€๋ฏ€๋กœ ๊น”๋”ํ•ด์ง„๋‹ค! ๋˜ํ•œ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ, ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ์„ฑ์ด ๋†’์•„์ง„๋‹ค.

Adapting & Extending

๐Ÿ’ก ์œ„ ์ฝ”๋“œ์˜ BoxOne๊ณผ BoxTwo๋Š” background-color๋งŒ ๋‹ค๋ฅธ ์‚ฌ์‹ค์ƒ ๊ฑฐ์˜ ๊ฐ™์€ ์ฝ”๋“œ์ด๋‹ค. ์ด ์ฝ”๋“œ๋“ค์„ ์ข€ ๋” ๊ฐ„๊ฒฐํ•˜๊ณ  ์ค‘๋ณต ์—†์ด ์ž‘์„ฑํ•  ์ˆ˜๋Š” ์—†์„๊นŒ?

const Father = styled.div`
  display: flex;
`;
const Box = styled.div`
  background-color: ${(props) => props.bgColor};
  width: 100px;
  height: 100px;
`;
const Circle = styled(Box)`
  border-radius: 50px;
`;

function App() {
  return (
    <Father>
      <Box bgColor="teal" />
      <Circle bgColor="tomato" />
    </Father>
  );
}

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์—ฌ, ๊ฐ ์ปดํฌ๋„ŒํŠธ์— bgColor๋ผ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋„ฃ์–ด ๊ฐ๊ฐ ๋‹ค๋ฅธ ๋ฐฐ๊ฒฝ์ƒ‰์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ! ๋‹ค์–‘ํ•œ ๊ฐ’๋“ค์„ props๋กœ ๋„˜๊ฒจ์ฃผ์–ด ์กฐ๊ฑด๋ถ€ ์Šคํƒ€์ผ๋ง์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ๋˜ํ•œ Box ์ปดํฌ๋„ŒํŠธ์— border-radius ์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜์—ฌ Box ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™•์žฅํ•œ Circle ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.


์ถœ๋ ฅ ํ™”๋ฉด

As & Attrs

๐Ÿ’ก ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ์˜ ์Šคํƒ€์ผ์€ ๊ทธ๋Œ€๋กœ, ํƒœ๊ทธ๋ช…๋งŒ์„ ๋ฐ”๊พธ์–ด ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

< ์ปดํฌ๋„ŒํŠธ๋ช… as = "์›ํ•˜๋Š” ํƒœ๊ทธ๋ช…" />

const Btn = styled.button`
  color: white;
  background-color: tomato;
  border: 0;
  border-radius: 15px;
`;

function App() {
  return (
    <>
      <Btn>Log in</Btn>
      <Btn as="a" href="/">
        Log in
      </Btn>
    </>
  );
}

export default App;

๐Ÿ’ญ ์†์„ฑ์„ ์ค€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉํ•  ๋•Œ, ์†์„ฑ์„ ์ปดํฌ๋„ŒํŠธ๋งˆ๋‹ค ์ ์šฉํ•ด์ฃผ์–ด์•ผ ํ•จ. ๐Ÿคจ Attrs๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋Ÿฌํ•œ ์ค‘๋ณต ์ฝ”๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

const (์‚ฌ์šฉํ•  ์ปดํฌ๋„ŒํŠธ๋ช…) = styled.(ํƒœ๊ทธ๋ช…).attrs( {์ ์šฉํ•˜๋ ค๋Š” ์†์„ฑ} )``

const Father = styled.div`
  display: flex;
`;

const Input = styled.input.attrs({ required: true })`
  background-color: tomato;
`;

function App() {
  return (
    <Father as="header">
      <Input />
      <Input />
      <Input />
      <Input />
      <Input />
    </Father>
  );
}

๐Ÿ‘‰๐Ÿปย  required: true ์†์„ฑ์„ ์ผ์ผํžˆ ๋ถ€์—ฌํ•˜์ง€ ์•Š์•„๋„ ๋จ!

Animations & Pseudo Selectors

๐Ÿ’ก ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ ์šฉํ•˜๊ธฐ

import styled, { keyframes } from "styled-components";
const rotationAnimation = keyframes`
  0% {
    transform:rotate(0deg);
    border-radius:0px;
  }
  50% {
    border-radius:100px;
  }
  100%{
    transform:rotate(360deg);
    border-radius:0px;
  }
`;

const Box = styled.div`
  height: 200px;
  width: 200px;
  background-color: lightblue;
  display: flex;
  justify-content: center;
  align-items: center;
  animation: ${rotationAnimation} 1s linear infinite;
  span {
    font-size: 36px;
    &:hover {
      font-size: 48px;
    }
    &:active {
      opacity: 0;
    }
  }
`;

๐Ÿ‘‰๐Ÿปย  animation: ${keyframes๋กœ ์ •์˜ํ•œ ์Šคํƒ€์ผ ์ปดํฌ๋„ŒํŠธ๋ช…} ์œผ๋กœ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

function App() {
  return (
    <Wrapper>
      <Box>
        <span>๐Ÿฌ</span>
      </Box>
    </Wrapper>

โœ… Box๋ผ๋Š” ์Šคํƒ€์ผ ์ปดํฌ๋„ŒํŠธ ๋‚ด์˜ ์Šคํƒ€์ผ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์•„๋‹Œ ์š”์†Œ๋„ ์„ ํƒ์ž๋กœ ์ง€์ •ํ•˜์—ฌ ์Šคํƒ€์ผ๋ง์ด ๊ฐ€๋Šฅํ•จ!

  • &: : ์ž๊ธฐ ์ž์‹ ์„ ์ง€์ •ํ•˜๋Š” ์„ ํƒ์ž.
  • (ํƒœ๊ทธ๋ช…) : ํ•ด๋‹น ์Šคํƒ€์ผ ์ปดํฌ๋„ŒํŠธ ๋‚ด์˜ ํƒœ๊ทธ๋ฅผ ์ง€์ •ํ•˜๋Š” ์„ ํƒ์ž.
  • ${์Šคํƒ€์ผ ์ปดํฌ๋„ŒํŠธ๋ช…} : ํ•ด๋‹น ์Šคํƒ€์ผ ์ปดํฌ๋„ŒํŠธ ๋‚ด์˜ ์Šคํƒ€์ผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ง€์ •ํ•˜๋Š” ์„ ํƒ์ž.

์ถœ๋ ฅ ํ™”๋ฉด

Theme

๐Ÿ’ก ๋‹คํฌ ๋ชจ๋“œ, ๋ผ์ดํŠธ ๋ชจ๋“œ ํ…Œ๋งˆ ๋ณ€ํ™˜ ๋“ฑ์— ์‚ฌ์šฉํ•˜๋Š” theme. ๊ฐ์ฒด ํ˜•์‹์œผ๋กœ index.js์— import ํ•˜์—ฌ ๋ชจ๋“  ํŽ˜์ด์ง€์—์„œ ์Šคํƒ€์ผ์„ ๊ฐ€์ ธ๋‹ค ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ถ•์ œ ์‚ฌ์ดํŠธ ๋งŒ๋“ค ๋•Œ ์ฒ˜์Œ ์‚ฌ์šฉํ•ด ๋ดค๋Š”๋ฐ, ํƒ€์ดํฌ๋ผ๋“ ์ง€ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ํ…Œ๋งˆ ์ƒ‰์ด๋ผ๋“ ์ง€ ์ค‘๋ณต๋˜๋Š” ์Šคํƒ€์ผ๋“ค์„ ๋ฏธ๋ฆฌ ์ง€์ •ํ•ด๋†“๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ฐ€์ ธ๋‹ค ์“ธ ์ˆ˜ ์žˆ์–ด ๋งค์šฐ ํŽธ๋ฆฌํ–ˆ์Œ! ๐Ÿฅน

index.js

import React from "react";
import ReactDOM from "react-dom";
import { ThemeProvider } from "styled-components";
import App from "./App";

const darkTheme = {
  textColor: "whitesmoke",
  backgroundColor: "#111",
};

const lightTheme = {
  textColor: "#111",
  backgroundColor: "whitesmoke",
};

ReactDOM.render(
  <React.StrictMode>
    <ThemeProvider theme={darkTheme}>
      <App />
    </ThemeProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

โœ… themeProvider์— props๋กœ theme ๋„˜๊ฒจ์ฃผ๊ธฐ!

์ ์šฉ

const Title = styled.h1`
  color: ${(props) => props.theme.textColor};
`;

const Wrapper = styled.div`
  display: flex;
  height: 100vh;
  width: 100vw;
  justify-content: center;
  align-items: center;
  background-color: ${(props) => props.theme.backgroundColor};

๐Ÿ‘‰๐Ÿปย  ๋‹คํฌ ๋ชจ๋“œ, ๋ผ์ดํŠธ ๋ชจ๋“œ๊ฐ€ props๋กœ ๋„˜๊ฒจ์ค€ theme์— ๋”ฐ๋ผ ๊ตฌ๋ถ„๋˜๊ฒŒ ๋œ๋‹ค.

Nomad Coders React JS ๋งˆ์Šคํ„ฐ ํด๋ž˜์Šค #2

profile
๋‚˜์˜ ์กฐ๊ฐ๋ฐฐ

0๊ฐœ์˜ ๋Œ“๊ธ€