CSS 파일을 만들지 않고 JavaScript 이용하여 스타일을 적용시킬 수 있는 Styled Components 라이브러리 사용법에 대해 정리하고자 합니다.
디바이스가 다양해지고 프로젝트의 규모나 복잡도가 점점 커지고 함께 작업해야 할 팀원 수도 많아짐에 따라 CSS를 효율적으로 구조화하기 위한 노력이 있었습니다.
이러한 문제점을 해결하기 위해서 SASS라는 전처리기가 등장하게 되었고 CSS의 구조화가 가능해졌습니다. 그러나 스타일이 겹치는 문제를 해결하기 위해 계속해서 계층구조를 만들게 되면 CSS 파일의 용량이 너무 커진다는 단점이 있습니다.
CSS 전처리기의 문제점을 해결하기위해 코드의 재사용, 간결화, 확장성, 예측성을 고려한 방법론들이 등장하게 되었고 이런 방법론들을 기반으로 팀원들 간에 CSS 작성 규칙을 정해서 프로그래밍하기 시작했습니다.
하지만 이러한 방법론들에서도 문제점이 발생하기 시작합니다. 클래스명 선택자가 장황해지고, 이런 긴 클래스명 때문에 마크업이 불필요하게 커지며, 재사용하려고 할 때마다 모든 UI 컴포넌트를 명시적으로 확장해야만 했습니다.
CSS in JS는 CSS를 컴포넌트 안으로 캡슐화하는 기법으로 스타일 속성의 중복과 CSS 파일의 크기가 방대해지는 것을 방지할 수 있습니다.
기존에는 HTML과 CSS, JavaScript는 각자 별도의 파일에 두는 것이 일반적이 었지만, 하지만 React나 Vue, Angular와 같은 모던 자바스크립트 라이브러리가 인기를 끌면서 웹개발의 패러다임이 바뀌고 있습니다.
최근에는 웹 애플리케이션을 여러 개의 재활용이 가능한 빌딩 블록으로 분리하여 개발하는 컴포넌트 기반 개발 방법이 주류가 되고 있습니다.
React의 경우에 JSX는 JavaScript가 HTML을 포함하는 구조를 가지기 때문에 라이브러리를 이용하여 컴포넌트에 적용시킬 CSS를 추가한다면, JSX 파일에 모든 HTML, CSS, JavaScript 코드를 포함 시킬 수 있습니다.
npm install styled-components
styled는 HTML 엘리먼트나 React 컴포넌트에 원하는 스타일을 적용하기 위해서 사용됩니다.
import styled from "styled-components";
import styled from "styled-components";
// div 요소에 대한 스타일 정의
styled.div`
width : 100px;
height : 200px;
`;
// button 요소에 대한 스타일 정의
styled.button`
width : 50px;
height : 50px;
`;
HTML 요소 뿐만 아니라 리액트 컴포넌트를 스타일링 할 수 있습니다.
import React from "react";
import styled from "styled-components";
import Button from "./Button";
// <Button> 컴포넌트에 대한 스타일 정의
styled(Button)`
`;
styled 함수는 최종적으로 해당 스타일이 적용된 HTML 엘리먼트나 React 컴포넌트를 리턴합니다.
import React from "react";
import styled from "styled-components";
export default function App() {
const StyledButton = styled.button`
width: 100px;
height: 100px;
padding: 6px 12px;
border-radius: 8px;
font-size: 1rem;
border: 1px solid lightgray;
color: gray;
background: cyan;
`;
return (
<div>
<StyledButton> button </StyledButton>
</div>
);
}
아래와 같이 자식 컴포넌트로 props를 전달해 스타일링을 적용 시킬 수 있습니다.
import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
padding: 6px 12px;
border-radius: 8px;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
color: ${(props) => props.color || "gray"};
background: ${(props) => props.background || "white"};
`;
// props.color가 있을 경우 전달 받은 color를 표시하고 없을 경우 "gray" 적용
// props.background가 있을 경우 전달 받은 background를 표시하고 없을 경우 "white" 적용
function Button({ children, color, background }) {
return (
<StyledButton color={color} background={background} Î>
{children}
</StyledButton>
);
}
export default function App() {
return <Button color="red">button</Button>;
}
Button 컴포넌트로 전달한 color="red"가 잘 적용되는 것을 확인할 수 있습니다.
prop에 따라 바꾸고 싶은 CSS 속성이 위와 같이 하나가 아니라 여러 개일 경우가 있습니다. 이럴 경우, Styled Components에서 제공하는 css 함수를 사용해서 여러 개의 CSS 속성을 묶어서 정의할 수 있습니다.
예를 들어, primary prop이 넘어온 경우, 글자색을 흰색, 배경색과 경계색은 남색으로 변경하고 싶다면 다음과 같이 예제 코드를 수정할 수 있습니다. 이번에는 자바스크립트의 && 연산자를 사용해서, primary prop이 존재하는 경우에만 css로 정의된 스타일이 적용되도록 하였습니다.
import React from "react";
import styled, { css } from "styled-components";
const StyledButton = styled.button`
padding: 6px 12px;
border-radius: 8px;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
${(props) =>
props.primary &&
css`
color: white;
background: navy;
border-color: navy;
`}
`;
function Button({ children, ...props }) {
return <StyledButton {...props}>{children}</StyledButton>;
}
export default function App() {
return <Button primary="1">button</Button>;
}
Button에 primary props가 있을 경우에 정의한 스타일이 잘 적용되는 것을 확인 할 수 있습니다.
hover를 적용하기 위해서는 아래와 같이 코드를 작성합니다.
import React from "react";
import styled, { css } from "styled-components";
const StyledButton = styled.button`
padding: 6px 12px;
border-radius: 8px;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
:hover {
padding: 6px 12px;
border-radius: 8px;
font-size: 1rem;
line-height: 1.5;
border: 1px solid white;
}
`;
생성한 요소에 자식, 후손 요소의 스타일링 또한 가능합니다. ">"는 자식 요소의 스타일링에 사용하고 사용하지 않을 경우는 후손 요소의 스타일링을 지정할 수 있습니다.
아래의 코드처럼 Div 컴포넌트의 자식 요소와 후손 요소의 클래스 이름에 따라 배경색이 변경시킬 수 있습니다.
import React from "react";
import styled from "styled-components";
const ColorDiv = styled.div`
width: 35px;
height: 15px;
padding: 6px 12px;
border-radius: 8px;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
`;
const Div = styled.div`
display: flex;
justify-content: center;
align-items: center;
width: 150px;
height: 30px;
padding: 6px 12px;
border-radius: 8px;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
> .red {
background: red;
}
> .yellow {
background: yellow;
}
.blue {
background: blue;
}
`;
export default function App() {
return (
<>
<Btn color>버튼</Btn>
<Div>
<ColorDiv className="red"> </ColorDiv>
<ColorDiv className="yellow"> </ColorDiv>
<ColorDiv className="blue"></ColorDiv>
</Div>
</>
);
}
`;
전역 CSS를 설정하기 위해서는 createGlobalStyle를 사용합니다. 아래의 코드는 버튼들의 스타일을 일괄적으로 적용하는 코드입니다.
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
button {
padding : 5px;
margin : 2px;
border-radius : 5px;
}
`
createGlobalStyle으로 생성한 컴포넌트를 App.js에서 최상단 컴포넌트로 배치시키면 전역적으로 스타일이 설정 됩니다.
// app.js
function App() {
return (
<>
<GlobalStyle />
<Button>전역 스타일 적용하기</Button>
</>
);
}
Reference : https://www.daleseo.com/react-styled-components/