✨ css-in-js에 대해 알아보고, 이를 대표하는 styled-components에 알아보자
inline
으로 style
관련 코드를 주입하지 않더라도 리액트에서는
css
파일을 생성한 후 그 안에서 css를 사용해서 컴포넌트를 꾸밀 수 있습니다.
나름 괜찮은 방식처럼 보이지만, 불편한 점이 존재합니다.
컴포넌트를 만들고 컴포넌트를 꾸미기 위해 css
파일을 만들어서 import
하고
HTML tag
마다 classname
을 넣고 css
코드를 작성하는 것을 반복해야 된다.
그래서 이보다 간편하게 컴포넌트를 꾸밀 수 있는 css-in-js
방식을 알아볼 겁니다.
css-in-js
방식이란, 자바스크립트 코드로
css
코드를 작성하여 컴포넌트를 꾸미는 방식입니다.
순수한 css
코드를 자바스크립트를 이용해서 css
코드를 만들어내는 것입니다.
css-in-js를 사용하는 장점!
기존에 css 파일을 작성하고, import하는 방식에서는 style을 작성할 때
조건문 등의 로직을 적용할 수 없었습니다.
하지만, css-in-js를 사용함으로 style을 적용할 때 조건문,
변수 등 다양한 로직을 이용할 수 있습니다.
✨ styled-components는 리액트에서 css-in-js 방식으로 컴포넌트를 꾸미게 할 수 있는 패키지 입니다.
styled-components
외에도 다양한 패키지가 있지만,
styled-components
예전부터 꾸준히 많은 개발자들에게 선택받은 패키지입니다.
패키지란?
React에 없는 기능이지만 우리가 추가로 가져와서 사용할 수 있는 써드파티 프로그램입니다.
패키지들은 누군가에 의해 만들어진 것으로 npm에 모여 있습니다.
우리가 사용하고자 하는 패키지를 npm install 또는 yarn add를 통해서 설치해 사용할 수 있습니다.
앞으로 개발하는데 유용한 여러 패키지를 알고 사용하는 것은 큰 도움이 됩니다,
✨ styled-components를 직접 설치하고 사용해보자.
우선 styled-components
를 조금 편하게 작성하기 위한 플러그인
vscode-styled-components
를 설치해고,
yarn add styled-components
를 vscode
터미널에 작성하고 패키지를 설치해주세요.
그럼 이제 기본 적인 사용법을 알아보자면
SC
의 기본적인 원리는 꾸미고 싶은 컴포넌트를 SC
의 방식으로 만들고,
그 안의 스타일 코드를 작성하는 방식으로 진행합니다.
// src/App.js
import React from "react";
// styled-components에서 styled 라는 키워드를 import 합니다.
import styled from "styled-components";
// styled키워드를 사용해서 styled-components 방식대로 컴포넌트를 만듭니다.
const StBox = styled.div`
// 그리고 이 안에 스타일 코드를 작성합니다. 스타일 코드는 우리가 알고 있는 css와 동일합니다.
width: 100px;
height: 100px;
border: 1px solid red;
margin: 20px;
`;
const App = () => {
// 그리고 우리가 만든 styled-components를 JSX에서 html 태그를 사용하듯이 사용합니다.
return <StBox>박스</StBox>;
};
export default App;
가장 핵심이 되는 코드는 const StBox = styled.div``;
이 부분입니다.
이 방식대로 styled-components
를 만드는 것인데,
`` 은 따옴표 가 아니라 백틱이라는 문자입니다.
그리고 styled. 뒤에는 html 태그가 오게되고,
아래 처럼 원하는 html 태그를 사용해 styled-components를 만들 수 있습니다.
div -> styled.div
span -> styled.span
button -> styled.button
classname
을 사용해서 구현하기는 조금 까다로운 조건부 스타일링을
styled-components
를 이용하면 간편하게 할 수 있습니다.
만약 스타일 코드를 작성할 때 ,
if문
을 사용할 수 있다면?
switch문
을 사용할 수 있다면?
삼항연산자를 사용할 수 있다면?
css-in-js
방식의 강점이 바로 스타일 코드를 js코드 작성하듯이
스타일 코드를 작성할 수 있는 것입니다.
// src/App.js
import React from "react";
import styled from "styled-components";
// 1. styled-components를 만들었습니다.
const StBox = styled.div`
width: 100px;
height: 100px;
border: 1px solid ${(props) => props.borderColor}; // 4.부모 컴포넌트에서 보낸 props를 받아 사용합니다.
margin: 20px;
`;
const App = () => {
return (
<div>
{/* 2. 그리고 위에서 만든 styled-components를 사용했습니다. */}
{/* 3. 그리고 props를 통해 borderColor라는 값을 전달했습니다. */}
<StBox borderColor="red">빨간 박스</StBox>
<StBox borderColor="green">초록 박스</StBox>
<StBox borderColor="blue">파랑 박스</StBox>
</div>
);
};
export default App;
위에 코드를 보면 const StBox
하나를 가지고,
아래 StBox
의 3가지에 모두 적용이 되는 형태인데 왜 적용이 될까요?
const StBox = styled.div`
border: 1px solid ${(props) => props.borderColor};
`;
이 부분을 자세히 보면 borderColor
의 값을 props
로 받아서
위의 코드의 props
에 red green blue
를 전달해주는 형태입니다.
더 자세히 알아보자면
첫째, ${ }
를 열어줘서 (템플릿 리터럴) 표현을 해줘야 하는데
둘째, 비어있는 화살표 함수를 열어 줍니다. ${()=>{}}
셋째, 함수의 인자에서 props
를 받아오고, props
안에는 부모 컴포넌트에서 보낸
borderColor
가 존재하는데 그걸 return
을 합니다.
이렇게 되었을 때 (props) => {return props.borderColor}
의 값이
=== 'red'
가 되고 결국 우리 눈에는 복잡해보이지만,
브라우저는 border:1px solid red
라는 코드로 인식해 스타일링 된 것입니다.
그럼 이제 다른 예시도 살펴보겠습니다.
아래는 switch
와 map
을 사용한 예시입니다.
// src/App.js
import React from "react";
import styled from "styled-components";
const StContainer = styled.div`
display: flex;
`;
const StBox = styled.div`
width: 100px;
height: 100px;
border: 1px solid ${(props) => props.borderColor};
margin: 20px;
`;
// 박스의 색을 배열에 담습니다.
const boxList = ["red", "green", "blue"];
// 색을 넣으면, 이름을 반환해주는 함수를 만듭니다.
const getBoxName = (color) => {
switch (color) {
case "red":
return "빨간 박스";
case "green":
return "초록 박스";
case "blue":
return "파란 박스";
default:
return "검정 박스";
}
};
const App = () => {
return (
<StContainer>
{/* map을 이용해서 StBox를 반복하여 화면에 그립니다. */}
{boxList.map((box) => (
<StBox borderColor={box}>{getBoxName(box)}</StBox>
))}
</StContainer>
);
};
export default App;
✨ 전 영역에서 사용 가능한 전역 스타일링 입니다.
styled components
는 컴포넌트 내에서만 활용할 수 있었는데,
하지만 우리는 프로젝트를 아우르는, 공통적으로 들어가야 할 스타일을 적용해야 합니다.
그럴 경우 전역적으로 globally
스타일을 지정한다 라고 표현합니다.
그럴 때 사용하는게 전역 스타일링입니다.
import styled from "styled-components";
function TestPage(props) {
return (
<Wrapper>
<Title>{props.title}</Title>
<Contents>{props.contents}</Contents>
</Wrapper>
);
}
const Title = styled.h1`
font-family: "Helvetica", "Arial", sans-serif;
line-height: 1.5;
font-size: 1.5rem;
margin: 0;
margin-bottom: 8px;
`;
const Contents = styled.p`
margin: 0;
font-family: "Helvetica", "Arial", sans-serif;
line-height: 1.5;
font-size: 1rem;
`;
const Wrapper = styled.div`
border: 1px solid black;
border-radius: 8px;
padding: 20px;
margin: 16px auto;
max-width: 400px;
`;
export default TestPage;
위의 경우는 각 태그가 <Title /> <Contents /> <Wrapper />
에서 새로 스타일링 되었습니다.
만약 규모가 좀 큰 프로젝트라고 하면 공통적으로 적용되는 스타일링 부분을 빼줄 필요가 있습니다.
우리의 경우는 글꼴과 line-height
를 공통 요소라 가정하고 GlobalStyle
을 적용해보겠습니다.
// GlobalStyle.jsx
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
body {
font-family: "Helvetica", "Arial", sans-serif;
line-height: 1.5;
}
`;
export default GlobalStyle;
// ----------------------------------------------------
// BlogPost.jsx
function BlogPost({ title, contents }) {
return (
<>
<p>{title}</p>
<p>{contents}</p>
</>
);
}
export default App;
// ----------------------------------------------------
// App.jsx
import GlobalStyle from "./GlobalStyle";
import BlogPost from "./BlogPost";
function App() {
const title = '전역 스타일링 제목입니다.';
const contents = '전역 스타일링 내용입니다.';
return (
<>
<GlobalStyle />
<BlogPost title={title} contents={contents} />
</>
);
}
export default App;
✨ 크로스 브라우징 이슈를 해결하기 위한 css reset 기법
브라우저는 기본적으로 default style
을 제공합니다.
margin
이나 글자의 크기 같은 경우인데 예시를 보면
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
Default Style을 테스트 해 봅니다.
<h1>이건 h1 태그에요</h1>
<p>이건 p 태그에요</p>
</body>
</html>
다양한 웹브라어주들은 저마다 다른 default style
을 제공하고 있어서
이를 초기화하고 정하는대로만 표현하는 것이 중요하다.
는 reset.css
를 검색해서 복사한 다음에
reset.css
로 저장을 했다면
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./reset.css" />
</head>
<body>
<span>Default Style을 테스트 해 봅니다.</span>
<h1>이건 h1 태그에요</h1>
<p>이건 p 태그에요</p>
</body>
</html>
위처럼 링크태그 부분을 보면 적용했을 때
태그가 가지는 기본 여백을 reset.css
를 통해 지워짐을 확인할 수 있다.