[React] Styled Components
1. Styled Components 개요
1.1 Css-in-Js
Css-in-Js란 JavaScript로 CSS코드를 작성하는 방식을 말한다.
- 이 방식을 사용하기 위해 styled-components 컴포넌트를 설치해줘야한다.
- styled-components는 리액트에서 CSS-in-JS 방식으로 컴포넌트를 꾸밀수 있게 도와주는 패키지이다.
아래와 같이 입력하여 yarn 에서 styled-components 설치해주도록하자.
yarn add styled-components
1.2 styled-components
styled-components를 사용하기 위해 꾸미고자 하는 컴포넌트를 SC의 방식대로 먼저 만들고, 그 안에 스타일 코드를 작성하면된다.
styled.
뒤에는 html의 태그가 온다.- div →
styled.div
- button →
styled.button
- div →
// src/App.js
import styled from "styled-components"; // (1) import하기
const App = () => {
// (3) 만든 CS를 JSX에서 html 태그를 사용하듯이 사용
return <StBox>박스</StBox>;
};
// (2) styled 키워드를 사용해서 SC 방식대로 컴포넌트를 만들기
const StBox = styled.div`
width: 100px;
height: 100px;
border: 1px solid red;
margin: 20px;
`;
export default App;
2. 조건부 스타일링
2.1 조건부 스타일링 구현
Styled Components을 사용하면 props를 통해서 부모 컴포넌트로부터 값을 전달받고, 조건문을 이용해서 조건부 스타일링을 할 수 있다.
styled-component에서만 사용되는 props라는 뜻으로 $
를 접두사로 붙혀주자.
import styled from "styled-components";
const App = () => {
return (
<div>
{/* (1) props를 통해 borderColor라는 값을 전달 */}
<StBox $borderColor="red">빨간 박스</StBox>
<StBox $borderColor="green">초록 박스</StBox>
<StBox $borderColor="blue">파랑 박스</StBox>
</div>
);
};
export default App;
const StBox = styled.div`
width: 100px;
height: 100px;
border: 1px solid ${(props) => props.$borderColor}; // (2) 부모 컴포넌트에서 보낸 props를 받아 사용
margin: 20px;
`;
부모 컴포넌트에서 보낸 props를 받아 사용하는 방법을 자세히 살펴보자.
const StBox = styled.div`
border: 1px solid ${(props) => props.borderColor};
`;
- 자바스크립트 코드를 사용하기 위해
${ }
사용 - 비어있는 화살표 함수 열어주기
${( )=>{ }}
- 함수의 인자에서 props를 받아오고, props안에는 부모 컴포넌트에서 보낸 borderColor가 있는데 그것을 return하기
2.2 조건부 스타일링 실습 - button
Props를 사용하는 Button 컴포넌트
function App() {
return (
<div>
<Button $primary>Primary Button</Button>
</div>
);
}
const Button = styled.button`
background-color: ${(props) => (props.$primary ? "blue" : "gray")};
color: white;
&:hover {
background-color: ${(props) => (props.$primary ? "darkblue" : "darkgray")};
}
`;
2.3 조건부 스타일링 실습 - NavLink
NavLink를 사용하여 현재 활성화된 링크에 대해 스타일을 다르게 적용할 수 있다. styled-components와 함께 사용하면, 네비게이션 링크의 활성 상태를 쉽게 스타일링할 수 있다.
아래처럼 $margin prop
을 사용하여 선택적으로 마진을 추가할 수 있다.
import { NavLink } from "react-router-dom";
import styled from "styled-components";
const App = () => {
return (
<nav>
<StNavItem to="/home" $margin>
Home
</StNavItem>
<StNavItem to="/about">About</StNavItem>
<StNavItem to="/contact">Contact</StNavItem>
</nav>
);
};
const StNavItem = styled(NavLink)`
&.active {
font-weight: bold;
color: blue;
}
${({ $margin }) =>
$margin &&
`
margin-right: 12px;
`}
`;
export default App;
3. CSS를 JS 파일에 직접 작성하기
Styled Components를 사용하면 CSS를 JavaScript 파일에 직접 작성할 수 있다.
다크 모드와 라이트 모드에 따라 동적으로 스타일을 변경해보자
import { ThemeContext } from "context/ThemeContext";
import { useContext } from "react";
import styled, { css } from "styled-components";
const Theme = () => {
const { isDark, setIsDark } = useContext(ThemeContext);
const handleToggleThemeButton = () => {
setIsDark((prev) => !prev);
};
return (
<ThemeLayout $isDark={isDark}>
<button onClick={handleToggleThemeButton}>
{isDark ? "라이트모드" : "다크모드"}
</button>
</ThemeLayout>
);
};
export default Theme;
const ThemeLayout = styled.main`
${(props) =>
props.$isDark
? css`
background-color: black;
`
: css`
background-color: white;
`}
`;
4. Global Styles
Global Styles(전역 스타일링)이란?
컴포넌트 내에서만 활용할 수 있는 styled components와 달리 공통적으로 들어가야 할 스타일을 적용할 때 사용하는 방법이 전역 스타일링이다.
아래는 컴포넌트 단위 스타일링이다.
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;
컴포넌트 단위 스타일링을 font와 line-height를 공통 요소라 가정하고 GlobalStyles을 적용해보자.
// GlobalStyle.jsx
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
body {
font-family: "Helvetica", "Arial", sans-serif;
line-height: 1.5;
}
`;
export default GlobalStyle;
// 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;
댓글남기기