[React] Styled-Components ํ™œ์šฉ
728x90

React์—์„œ์˜ CSS

๋ฆฌ์•กํŠธ์—์„œ CSS๋ฅผ ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

CSS ํŒŒ์ผ์„ import ํ•˜๊ฑฐ๋‚˜ module๋กœ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๊ณ , SASS ๊ฐ™์€ ์ „์ฒ˜๋ฆฌ๊ธฐ๋‚˜ tailwind ๋“ฑ์˜ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ด์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

๊ทธ์ค‘์—์„œ ์˜ค๋Š˜์€ Styled-components์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•ด๋ณด๋ ค ํ•œ๋‹ค.

Styled-components์— ๋Œ€ํ•ด์„œ ๋ชฐ๋ž๋˜ ๋ถ€๋ถ„์ด ๋งŽ์•˜๊ณ ,

๋ฌด์—‡๋ณด๋‹ค ์‚ฌ์šฉํ•ด๋ณด๋‹ˆ ์ƒ๊ฐ๋ณด๋‹ค ๋” ํŽธํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค!

 

 

Styled-components

Styled-components๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์•ˆ์— CSS๋ฅผ ์ž‘์„ฑํ•˜๋Š” CSS-in-JS ๋ฐฉ์‹์ด๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด์šฉํ•ด์„œ CSS ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋‚ด์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊พธ๋ฐ€ ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฐ CSS-in-JS ๋ฐฉ์‹์˜ ํŒจํ‚ค์ง€๊ฐ€ Styled-components ๋ฟ์ธ ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ,

์˜ˆ์ „๋ถ€ํ„ฐ ํ˜„์žฌ๊นŒ์ง€ ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด ์‚ฌ์šฉ ์ค‘์ธ ํŒจํ‚ค์ง€๋‹ค.

์‹ค์ œ๋กœ ๊ธ€๋กœ๋ฒŒํ•œ ๊ธฐ์—…๋“ค์ด ๋งŽ์ด ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ธฐ๋„ ํ•˜๋‹ค. (๊ณต์‹ ์‚ฌ์ดํŠธ์— ๋”ฐ๋ฅด๋ฉด!..)

์•„๋ž˜๋Š” Styled-components์˜ ๊ณต์‹ ์‚ฌ์ดํŠธ๋‹ค. ๊ณต์‹๋ฌธ์„œ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ ๋ฐฉ๋ฒ• ์ฐธ๊ณ  ๊ฐ€๋Šฅ!


https://styled-components.com/

 

styled-components

Visual primitives for the component age. Use the best bits of ES6 and CSS to style your apps without stress ๐Ÿ’…๐Ÿพ

styled-components.com

 

 

 

์„ค์น˜

npm์ด๋‚˜ yarn์„ ํ†ตํ•ด์„œ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•œ๋‹ค.

npm install --save styled-components
yarn add styled-components

 

 

 

์œ ์šฉํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ

vscode๋ฅผ ์—๋””ํ„ฐ๋กœ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๊ผญ ๊น”์ž.. ๐Ÿฅบ

์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ์กด์žฌ๋ฅผ ์•Œ์•˜๋‹ค๋ฉด ์ง„์ž‘๋ถ€ํ„ฐ styled-components๋ฅผ ์ค„๊ธฐ์ฐจ๊ฒŒ ์ผ์„ ๊ฒƒ ๊ฐ™๋‹ค.

์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๊น”์ง€ ์•Š๋Š”๋‹ค๋ฉด, ์™ผ์ชฝ๊ณผ ๊ฐ™์ด ์ž๋™ ์™„์„ฑ๋„.. ๋ฌด์—‡๋„ ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฉฐ ํ•œ ๋•€ ํ•œ ๋•€ css๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ์Šฌํ”ˆ ์ผ์ด ๋ฐœ์ƒํ•œ๋‹ค.

ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•˜์ž๋งˆ์ž! ์˜ค๋ฅธ์ชฝ๊ณผ ๊ฐ™์ด css ํŒŒ์ผ์—์„œ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ css๋ฅผ ์œ ๋ คํ•˜๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๋‹ค.

 

 

ํŽธ-์•ˆ...

๋‹ค๋งŒ css ํŒŒ์ผ์—์„œ ์ž‘์„ฑํ•  ๋•Œ์™€ emmet ๋‹จ์ถ•ํ‚ค ๊ธฐ์ค€์€ ์ข€ ๋‹ค๋ฅธ ๊ฒƒ ๊ฐ™์•„ ์•„์‰ฝ๋‹ค. ((ํ˜น์‹œ ๋งž์ถœ ์ˆ˜ ์žˆ๋‹ค๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”..))

 

 

 

 

 

Styled-components ์‚ฌ์šฉํ•˜๊ธฐ

Styled-components์˜ ๊ธฐ๋ณธ์ ์ธ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์€, ๊พธ๋ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋จผ์ € ๋งŒ๋“  ๋’ค ๊ทธ ์•ˆ์— CSS๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

๋จผ์ € ์ƒ๋‹จ์— styled ํ‚ค์›Œ๋“œ๋ฅผ import ํ•˜๊ณ ,

import styled from 'styled-components';

styled.div ์ฒ˜๋Ÿผ styled. ํƒœ๊ทธ๋ช…๊ณผ ๊ฐ™์ด ๋งŒ๋“ค๊ณ ์ž ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์˜ htmlํƒœ๊ทธ๋ฅผ ์ง€์ •ํ•ด์ค€๋‹ค. ์–ด๋–ค html ํƒœ๊ทธ๋˜ ๋‹ค ๊ฐ€๋Šฅํ•˜๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋ฐฑํ‹ฑ(``) ์•ˆ์— CSS๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.

const InputArea = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  padding-bottom: 2rem;
`;

 

์ด๋ ‡๊ฒŒ ๋งŒ๋“  ์ปดํฌ๋„ŒํŠธ๋ฅผ JSX์—์„œ html ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๋“ฏ ์จ์ฃผ๋ฉด ์™„๋ฃŒ!

<InputArea>
	<InputWrapper>
		<Label htmlFor="title">์ œ๋ชฉ</Label>
		<Input type="text" value={title} placeholder="์ œ๋ชฉ" onChange={(e) => {setTitle(e.target.value);}} />
    </InputWrapper>
</InputArea>

 

 

 

 

Styled-components ํ™œ์šฉ

์กฐ๊ฑด๋ถ€ ์Šคํƒ€์ผ๋ง ๊ฐ€๋Šฅ

CSS-in-JS์ด๊ธฐ ๋•Œ๋ฌธ์— if๋ฌธ, switch๋ฌธ, ์‚ผํ•ญ ์—ฐ์‚ฐ์ž ๋“ฑ๋“ฑ์„ ์ด์šฉํ•ด์„œ ์กฐ๊ฑด์— ๋”ฐ๋ผ ์Šคํƒ€์ผ๋ง์„ ํ•ด์ค„ ์ˆ˜๋„ ์žˆ๋‹ค.

const Box = styled.div`
  width: 100px;
  height: 100px;
  border: 1px solid ${(props) => props.borderColor};
`;

์•„๋ž˜์™€ ๊ฐ™์ด props๋ฅผ ์ง€์ •ํ•ด์„œ ์กฐ๊ฑด๋ถ€ ์Šคํƒ€์ผ๋ง์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

<Box borderColor="red">๋ฐ•์Šค</Box>

 

 

์ƒ์„ฑํ•œ styled-component ์ƒ์†๋ฐ›์•„ ์žฌ์‚ฌ์šฉ

withComponent('htmlํƒœ๊ทธ')๋ฅผ ํ†ตํ•ด์„œ ์ƒ์†๋ฐ›์œผ๋ฉด์„œ ์ƒˆ๋กœ์šด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
styled(์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„)๋งŒ ์ž‘์„ฑํ•˜๋ฉด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ์Šคํƒ€์ผ์„ ์ƒ์† ๊ฐ€๋Šฅ.

const Box = styled.div`
  width: 100px;
  height: 100px;
`;

const Button = styled(Box.withComponent('button'))`
  border: none;
  background-color: #aaa;
`;

 

 

SCSS์ฒ˜๋Ÿผ ์ค‘์ฒฉํ•ด์„œ ์ž‘์„ฑํ•˜๊ธฐ

& ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•ด์„œ ์ค‘์ฒฉํ•ด์„œ ์ž‘์„ฑ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.  ์•„๋ž˜ ์ฝ”๋“œ๋Š” Input ์ปดํฌ๋„ŒํŠธ์ด๋ฉด์„œ `text` ํด๋ž˜์Šค๋ฅผ ๊ฐ–๊ณ ์žˆ๋Š” ๊ฒฝ์šฐ์— ๋Œ€ํ•ด ์ž‘์„ฑํ–ˆ๋‹ค.

const Input = styled.input`
  width: 200px;
  height: 36px;
  border: 1px solid #ccc;
  border-radius: 4px;
  padding: 0 8px;
  font-size: 1rem;

  &.text {
    width: 340px;
  }
`;

 

 

 

์ „์—ญ ์Šคํƒ€์ผ๋ง

CSS ์ž‘์—…์„ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— normailize.css๋‚˜ reset.css๋ฅผ ์ ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์€๋ฐ,
createGlobalStyle๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์Šคํƒ€์ผ์„ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

import { createGlobalStyle } from "styled-components";

const GlobalStyle = createGlobalStyle`
  *, *::before, *::after {
      margin: 0;
    padding: 0;
    box-sizing: border-box;
  }

  body {
    line-height: 1.7;
  }
`;

export default GlobalStyle;

 

์ด๋ ‡๊ฒŒ ์ƒ์„ฑํ•œ ์ „์—ญ ์Šคํƒ€์ผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ตœ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์— ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋ชจ๋“  ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์— ์ ์šฉ๋œ๋‹ค.

import GlobalStyle from "./GlobalStyle";
import BlogPost from "./BlogPost";

function App() {
  return (
    <>
      <GlobalStyle />
      <Box>
          <Button>๋ฒ„ํŠผ</Button>
      </Box>
    </>
  );
}

export default App;

 

 

 

์ฐธ๊ณ 

https://hymndev.tistory.com/71
https://www.daleseo.com/styled-components-global-style/

728x90