안녕하세요 ! 오늘은 CSS 라이브러리중에 하나인 Styled-Components를 알아보겠습니다 ! ╰(°▽°)╯ 와아아
CSS 라이브러리는 Styled-Components 이외에도 Sass,PostCss그리고 tailWind,부트스트랩 등 정말 많이 있는데여!
뭐가 좋고 나쁘다고 할거없이 장단점이 있고 개인적인 코딩스타일
에 따라 맞는 라이브러리를 쓰시면 될거같습니다!
개인적으로 저는 Styled-components
가 좋아서 포스팅중입니다 ╰(°▽°)╯
Styled-Compoenents는 css를 편하게 코딩할수있게 도와주는 라이브러리입니다!
클래스 충돌방지이외에도 유지보수에 도움되는 여러가지 기능을 가지고있어서 개발자들이 좋아해여
스타일드컴포넌트는 CSS in JS
입니다.
즉,CSS코드를 자바스크립트안에서 작성
해야합니다.
맨날 확장자에 index.css ,, 이러면서 파일만드는게 귀찮잖아여
한 js파일안에서 깔끔하게 css까지 작성할 수 있는 장점도 있고
코드 상속 , props , nesting
등 다양한 기능을 가지고 있습니다!
하지만 그렇게되면 브라우저가 렌더링을 할떄 js코드를 쭉 다운받는데 js안에서 쓴 css코드+ 스타일드컴포넌트 문법자체도 재컴파일
해야해서 렌더링시간이 조금 더 오래걸리겠죠?
장점
- 스타일드 컴포넌트의 다양한 기능으로 유지보수가 좋아지고 코드양을 줄일 수 있다.
- 한 파일안에서 css까지 작성해서 폴더구조가 깔끔하다.
단점
- 한 파일안에 css코드와 js코드가 다 있기떄문에 가독성이 떨어질수도 있다.
- 렌더링할떄 재컴파일문제로 렌더링시간이 길어져 성능에 좋지않다.(미미합니다)
이제 본격적으로 styled-components를 써보겠습니다.╰(°▽°)╯
우선 styled-components는 CRA가 기본적으로 가지고있지않아서 따로 설치를 해야합니다!
npm install --save styled-components
npm i --save-dev @types/styled-components //타입스크립트시면 이것도 설치해주세요!
그리고 자동완성을 원하시면 익스텐션 vscode-styled-components
까지 설치해주세요!
- 기본 골격
- 상속
- css
- nesting
- attrs
- as
- Animation
import React from "react";
import "./App.css";
import styled from "styled-components";
const Hello = styled.div`
width: 100px; //css를 여기다가 작성합니다!
height: 100px;
background-color: red;
`;
function App() {
return <Hello className="App"></Hello>;
}
export default App;
결과
대문자
여야합니다!styled
꼭 import
하세요!기본 골격
const [컴포넌트이름] = styled.[태그]
내가 만약 컴포넌트이름은 Box 태그는 div로된걸 만들고 있다면?
const Box= styled.div`
//css 입력하는 곳
`
이런식으로 쓰시면됩니다!
a태그를 만들고 있다면
const Box= styled.a`
//css 입력하는 곳
`
컴포넌트이름을 내마음대로 정할수있어서 html골격을 봤을떄 좀 더 가독성이 생길꺼같아여
상속은 어떤걸 열심히 스타일링했는데 그걸 그대로 가져와서 뭔가를 추가해주고싶을떄 많이써요!
즉 , 공통적으로 스타일링할게 있을떄 많이씁니다!
import React from "react";
import "./App.css";
import styled from "styled-components";
const Box = styled.div`
width: 100px;
height: 100px;
background-color: red;
`;
const CircleBox = styled(Box)`
border-radius: 50%;
background-color: blue;
`;
function App() {
return (
<div className="App">
<Box></Box>
<CircleBox></CircleBox>
</div>
);
}
export default App;
결과
상속하는법
const [컴포넌트이름] = styled(상속받을 태그이름)``
import React from "react";
import "./App.css";
import styled from "styled-components";
const Button = styled.button<{ border: string }>`
width: 100px;
height: 50px;
border: 3px solid ${(props) => props.border || "green"};
`;
function App() {
return (
<div className="App">
<Button border={""}>클릭</Button>
<Button border={"red"}>클릭</Button>
<Button border={"blue"}>클릭</Button>
<Button border={"black"}>클릭</Button>
</div>
);
}
export default App;
결과
스타일드 컴포넌트의 장점중 하나는 유연하게 이미만든 컴포넌트들을 바꿀 수 있다는것이예영
props로 값을 전달하고
동적으로 css 스타일링을 할 수 있답니다!
border을 넣지않았다면 테두리를 녹색으로 만들었어요!
${props=>props.전달한변수이름}
props는 한줄의 코드를 조건부로 사용할 수 있다면
여러줄의 코드를 조건부로 할려면 어떻게해야할까여?
styled-component에 내장되어있는 css를 import해옵니다!
import React from "react";
import "./App.css";
import styled, { css } from "styled-components";
const Button = styled.button<{ border: string; huge?: boolean }>`
width: 100px; //styled.button< {프롭스명 : 타입지정}
height: 50px;
border: 3px solid ${(props) => props.border || "green"};
${(props) =>
props.huge && //만약 huge가 있다면 실행해줘
css`
width: 8rem;
height: 10rem;
font-size: 2em;
`}
`;
function App() {
return (
<div className="App">
<Button border={""}>클릭</Button>
<Button border={"red"}>클릭</Button>
<Button border={"blue"}>클릭</Button>
<Button border={"black"}>클릭</Button>
<Button border={"pink"} huge>
클릭!!
</Button>
</div>
);
}
export default App;
결과
pink버튼만 커졌죠?
완전 유용합니다 ! ╰(°▽°)╯
태그 컴포넌트를 만들떄마다 계속 const 컴포넌트이름 styled 하기 번거롭잖아여 그렇기때문에
주요태그만 컴포넌트화시키고 나머지는 nesting문법으로 태그를 접근합니다!
예시를 한번 보겠습니다!
import React from "react";
import "./App.css";
import styled from "styled-components";
const Box = styled.div`
width: 300px;
height: 100px;
& > div { //Box 컴포넌트 바로 아래 div에 접근
font-size: 32px;
color: pink;
}
& > p { //Box 컴포넌트 바로 아래 p에 접근
font-size: 16px;
color: green;
}
`;
function App() {
return (
<div className="App">
<Box>
<div>안녕하세요!</div>
<p>오늘 저녁 뭐먹을까요? 배고픈데,,</p>
</Box>
</div>
);
}
export default App;
결과
이렇게 하위태그를 &
문법으로 접근할 수 있답니다.
그러면 중심이되는 태그만 컴포넌트화시키고 나머지는 nesting
문법으로 접근하면 좀 더 좋겠죠?!
input 같은경우 attribute 정말 많잖아여?
그거 하나씩 쓰기 힘들떄 스타일드 컴포넌트에 추가해주면 정말 편하게 할 수 있어요!
attrs를 써서 한번 간단하게 예시코드를 짜볼게요!
import React from "react";
import "./App.css";
import styled from "styled-components";
const InputCheckbox = styled.input.attrs({
type: "checkbox",
checked: true,
})`
width: 100px;
height: 100px;
`;
const InputBox = styled.input.attrs({
required: true,
placeholder: "여기에 글을 써주세요!",
})`
height: 50px;
padding: 5px;
border: 1px solid black;
margin: 5px;
`;
function App() {
return (
<div className="App">
<InputCheckbox></InputCheckbox>
<InputBox></InputBox>
<InputBox></InputBox>
<InputBox></InputBox>
</div>
);
}
export default App;
결과
attrs에 미리 적어두면 html쪽에 정말 깔끔해지는거같아여!
유지보수면에서도 정말 좋아서 잘쓰면 좋을꺼같네여 !! ╰(°▽°)╯
const 컴포넌트이름=styled.input.attrs({내가 쓰고 싶은 속성값})
어떤걸 div태그로 만들었는데
딱 한곳에서 css는 똑같지만 링크 태그로 바꾸고싶다면 어떻게할까여?
그땐 as 문법을 쓰면됩니다!
import React from "react";
import "./App.css";
import styled from "styled-components";
const Box = styled.div`
width: 300px;
height: 100px;
& > div {
font-size: 32px;
color: pink;
}
& > p {
font-size: 16px;
color: green;
}
`;
function App() {
return (
<div className="App">
<Box>
<div>안녕하세요!</div>
<p>오늘 저녁 뭐먹을까요? 배고픈데,,</p>
</Box>
<Box as="a" href="#"> //여기가 바꼇어여!
링크로 바꼇당
</Box>
</div>
);
}
export default App;
결과
마지막으로 Animation입니다!
스타일드 컴포넌트에서 Animation으로 쓰는방법은 Pure css
랑은 조금 다른데여
한번 적용을 해보겠습니다! ^____^
import React from "react";
import "./App.css";
import styled, { keyframes } from "styled-components";
const MovingBox = keyframes`
0%{//Keyframes에 animation css를 적어줍니다!
transform: translateX(-300px);
}
50%{
background-color: blue;
border-radius: 50%;
transform: translateX(300px);
}
100%{
background-color: red;
transform: translateX(-300px);
}
`;
const Box = styled.div`
margin: 0 auto;
width: 100px;
height: 100px;
background-color: red;
animation: ${MovingBox} 3s infinite;
`;//그 애니메이션 컴포넌트를 이곳에 적어주고
//그후엔 Pure CSS와 똑같습니다!!
const Main = styled.div``;
function App() {
return (
<Main className="App">
<Box></Box>
</Main>
);
}
export default App;
결과
간단하게 스타일드컴포넌트로 animation을 구현해보았습니다!
- GlobalStyle
- ThemeProvider
globalStyle은 협업 , 개인 프로젝트시작 전에 공통으로 적용
해야할 코드를 쓰고 싶을떄 씁니다!
css를 한번 초기화 시켜겠습니다!
//GlobalStyle.tsx
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
`;
export default GlobalStyle;
- src폴더아래에 GlobalStyle.tsx파일을 만듭니다.
- createGlobalStyle을 import 해옵니다
- GlobalStyle을 index.tsx에 적용합니다
적용 후
저희 다크모드 많이 쓰잖아여 !
아마 context api를 사용해서 바꿔줬을꺼예여
하지만 스타일드컴포넌트를 쓴다면 context api를 쓰지 않고도 정말 간단하게 다크모드를 구현할 수있습니다!
천천히 기본설정을 해볼게여 ╰(°▽°)╯
설정 순서
- styled.d.ts 파일만들기 //이곳에서 DefaultTheme의 타입을 지정해요
- theme.ts 파일 만들기 // 이곳에서 theme을 설정해여
- index.tsx에 themeProvider를 추가해줘요!
이제 하나씩 해볼게여!
//styled.d.ts
import "styled-components";
declare module "styled-components" {
export interface DefaultTheme {
textColor: string;
bgColor: string;
} // DefaultTheme에서 여러분이
//쓸 변수를 지정해주셔야해여
//저는 텍스트와 배경만 지정하겠습니다!
}
타입스크립트에서 제공하지않은 타입
을 저희가 수동
으로 추가해주고싶으면 styled.d.ts
파일에서 추가를 해주면돼요!
저는 DefaultTheme를 추가하겠씁니다!
//theme.ts
import { DefaultTheme } from "styled-components";
export const darkTheme: DefaultTheme = {
bgColor: "#2f3640",
textColor: "#f5f6fa",
};
export const lightTheme: DefaultTheme = {
bgColor: "#f5f6fa",
textColor: "#2f3640",
};//아까 추가한 DefaultTheme 타입을 가져왔습니다!
//다크모드 구현을 위해 darkTheme, lightTheme을 만들어줬습니다!
마지막으로 ThemeProvider을 index.tsx에 추가해줄게요!
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import GlobalStyle from "./GlobalStyle";
import { ThemeProvider } from "styled-components";
import { darkTheme, lightTheme } from "./theme";
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<React.StrictMode>
<ThemeProvider theme={darkTheme}>
<GlobalStyle />
<App />
</ThemeProvider>
</React.StrictMode>
);
theme={제가 지정한 theme}
만약 어떤 버튼을 눌렀을떄 다크모드에서 라이트모드로 바꾸고싶다면?
theme안에 darkTheme을 lightTheme으로 바꾸면 되겠죠?! ╰(°▽°)╯
환경설정은 다 끝냈으니 적용을 해볼게요!
import React from "react";
import "./App.css";
import styled from "styled-components";
const Box = styled.div``;
const Main = styled.div`
background-color: ${(props) => props.theme.bgColor};
color: ${(props) => props.theme.textColor};
height: 100vh;
`;
function App() {
return (
<Main className="App">
<Box>
<div>안녕하세요!</div>
<p>오늘 저녁 뭐먹을까요? 배고픈데,,</p>
</Box>
<Box as="a" href="#">
링크로 바꼇당
</Box>
<p>안녕</p>
</Main>
);
}
export default App;
결과
lightTheme으로 바꾼다면?
결과
이렇게 간단하게 다크모드를 구현할 수 있답니다!
오늘 css 라이브러리중에 스타일드 컴포넌트를 알아보았습니다!
한번배워두면 정말 좋은 라이브러리니까 배워두면 좋을꺼같아여!!
요즘 트랜드가 큰 규모의 프로젝트에서는 Sass+PostCSS vs styled-component구도인데 50대50 같아여
자기 스타일에 맞는 라이브러리 한개만 쭉 쓰는것도 좋지만 협업할때 다른 개발자분들이랑 합을 맞추려면 두개다 쓸줄아는게 좋을꺼같아요!