[React #9] styled-components로 효과적인 스타일링
현대 앱이 컴포넌트를 기반으로 발전해가면서 CSS 스타일링 방법론 또한 '컴포넌트를 기반'으로 재구성되고 있다. 이러한 발전 속에서 등장한 패러다임이 'CSS-in-JS'이며 그 중 가장 인기있는 라이브러리가 'sytled-components'이다.
CSS in JS의 등장
- 모든 기술은 문제를 해결하기 위해 등장했다. 'styled-components' 또한 이전 기술의 문제점을 보완하기 위해 등장했다.
- pure CSS의 문제점을 보완하기 위해 CSS preprocessor(전처리기)로 SASS, Scss가 등장했지만 여전히 문제점이 있다.
-CSS 클래스명을 붙이기 어렵다.
-정해진 가이드가 없으면 구조가 복잡해진다.
-방대한 스타일 정보로 인한 스크롤 지옥
-CSS 클래스로 조건부 스타일링의 한계
-동적인 변화를 표현하기에 한계 - css-in-js는 2018년 이후 폭발적으로 성장해왔고, styled-components는 npm 다운로드 수 기준으로 가장 인기있는 css-in-js 라이브러리다.
CSS-in-JS의 장점
- 클래스명을 해시값으로 자동 생성하고, 클래스명 오염을 방지한다.
- JavaScript에서 CSS 문법을 온전하게 사용할 수 있다.
- JavaScript의 동적인 값들을 온전하게 사용할 수 있다.
- 컴포넌트 단위로 추상화하여 적용하기 알맞다.
=> 컴포넌트와 스타일이 하나의 파일로 결합되어 모듈화가 수월해진다.
styled-components
- 설치
npm install --save styled-components
- styled-components는 '고유한 클래스 명을 자동으로 생성'해 서로 다른 스타일이 전역에서 중복 적용될 우려를 줄여주고,
- 렌더링 되는 컴포넌트에 맞는 스타일 컴포넌트를 자동으로 내보내주는 등 컴포넌트의 스타일 작성과 관리를 효율적으로 할 수 있다는 장점이 있다.
시작하기
styled-components
라이브러리에서 import 해온styled
객체를 이용한다.- html 태그 이름 뒤 Tagged Template 문법을 활용해 CSS 속성을 정의한다. (Template Literals(``)의 확장)
import styled from 'styled-components';
render(
<Wrapper>
<Title>
Hello World!
</Title>
</Wrapper>
);
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: blue;
`;
styled-components 사용하기
Adapting based on props
import styled from 'styled-components';
render(
<div>
<Button>Normal</Button>
<Button width="100">Primary</Button>
</div>
);
const Button = styled.button`
background: ${props => props.width < 200 ? "blue" : "white"};
color : ${props => props.primary ? "white" : "blue"};
`;
- props를 기반으로 삼항 연산자를 붙여 스타일의 변화를 줄 수 있다.
Extending Styles
import styled from 'styled-components';
render(
<div>
<Button>Normal</Button>
<TomatoAnchorButton>Tomato Button</TomatoAnchorButton>
</div>
);
const Button = styled.div`
color: blue;
font-size: 14px;
margin: 5px;
padding: 16px 0;
border: 2px solid blue;
`;
const TomatoAnchorButton = styled(Button.withComponent("a"))`
color: tomato;
border-color: tomato;
`;
- 중복 요소가 없는 일반적인
Button
속성을 정의하고, 이 속성을 바탕으로 확장된 속성(TomatoAnchorButton
)을 정해준다. - 이때 중복되는 속성은 새로운 속성으로 덮어진다.
Nesting
import styled from 'styled-components';
render(
<>
<Thing>Hello world!</Thing>
<Thing>How ya doing?</Thing>
<Thing className = "something">
<span className="contents">The sun is shining</span>
</Thing>
<div>Pretty nice day today.</div>
<Thing>Don't you think?</Thing>
<div className="something-else">
<Thing>Splendid</Thing>
</div>
</>
);
const Thing = styled.div`
color: blue;
&:hover {
color: red;
}
&.something
.something-else & {
border: 1px solid;
}
`;
Global Style & ThemeProvider
- 전역 스타일을 적용할 때 쓴다.
reset
설치,createGlobalStyle
에 전역 스타일을 넣고,ThemeProvider
를 통해 자주 사용하는 폰트, 색상 등을 지정해 원하는 곳에 가져다 쓸 수 있다.- styled-reset 설치
npm install --save styled-components styled-reset
import { createGlobalStyle } from 'styled-components';
import reset from 'styled-reset';
const GlobalStyle = createGlobalStyle`
${reset}
// 전역스타일
`;
export default GlobalStyle;
index.js
에 import 해준다.
import React from "react";
import ReactDOM from "react-dom";
import GlobalStyle from './styles/GlobalStyle';
import { ThemeProvider } from "styled-components";
import Routes from "./Routes";
import theme from "./styles/theme";
ReactDOM.render(
<>
<GlobalStyle />
<ThemeProvider theme={theme}>
<Routes />
</ThemeProvider>
</>,
document.getElementById("root")
);
// theme.js
const theme = {
background: "#FFFEFC",
white: "#FFFFFF",
vermilion: "#ff7425",
orange: "#FF9900",
opacityOrange: "rgba(242,153,74,0.5)",
yellow: "#FFD66C",
grey: "rgba(196,196,196,0.3)",
middleGrey: "rgba(65,65,65,0.4)",
deepGrey: "#828282",
lightOrange: "rgba(255,195,170,0.3)",
fontColor: "#2D2B2B",
fontTitle: "'Alata', sans-serif;",
fontContent: "'Noto Sans KR', sans-serif;",
};
export default theme;
// theme 사용
const Container = styled.div`
background-color: ${props => props.theme.background}
`;
Mixin
- CSS를 import해서 속성을 정의하고 원하는 요소에 쓸 수 있다.
import { css } from "styled-components"
const Navigation = styled.nav`
position: fixed;
left: 0;
top: 0;
right: 0;
${Sticky}
`;
const Sticky = css`
position: fixed !important;
background-color: white;
border-bottom: 1px solid rgba(0, 0, 0, 0.11);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.11);
transition: all 0.6s ease-in-out;
color: black;
`;
//
const RingVariant = (radius, stroke = "10") => css`
position: absolute;
border-radius: 50%;
height: ${radius * 2}px;
width: ${radius * 2}px;
border: ${stroke}px solid rgba(0, 0, 0, 0.5);
`;
Attaching additional props
render(
<div>
<Input placeholder="A small text input" />
<br />
<Input placeholder="A bigger text input" size="2em" />
</div>
);
//attr()의 매개변수에 객체로 속성 부여
const Input = styled.input.attrs(props => ({
// we can define static props
type: "password",
// or we can define dynamic ones
size: props.size || "1em",
}))`
color: palevioletred;
font-size: 1em;
border: 2px solid palevioletred;
border-radius: 3px;
/* here we use the dynamically computed prop */
margin: ${props => props.size};
padding: ${props => props.size};
`;
Animation
- 애니메이션 및 스타일 효과를 줄 때는
keyframes
를 사용한다.
// Create the keyframes
const rotate = keyframes`
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
`;
// Here we create a component that will rotate everything we pass in over two seconds
const Rotate = styled.div`
display: inline-block;
animation: ${rotate} 2s linear infinite;
padding: 2rem 1rem;
font-size: 1.2rem;
`;
render(
<Rotate>< 💅🏾 ></Rotate>
);
Author And Source
이 문제에 관하여([React #9] styled-components로 효과적인 스타일링), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@kykim_dev/React-9-styled-components로-효과적인-스타일링저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)