현대 앱이 컴포넌트를 기반으로 발전해가면서 CSS 스타일링 방법론 또한 '컴포넌트를 기반'으로 재구성되고 있다. 이러한 발전 속에서 등장한 패러다임이 'CSS-in-JS'이며 그 중 가장 인기있는 라이브러리가 'sytled-components'이다.
npm install --save styled-components
styled-components
라이브러리에서 import 해온 styled
객체를 이용한다.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;
`;
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"};
`;
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
)을 정해준다. 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;
}
`;
reset
설치, createGlobalStyle
에 전역 스타일을 넣고, ThemeProvider
를 통해 자주 사용하는 폰트, 색상 등을 지정해 원하는 곳에 가져다 쓸 수 있다.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}
`;
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);
`;
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};
`;
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>
);