여러 자료들(블로그, 클론코딩)에서 하는 말이
모두 다르다. 그래서 어떤 방식이 더 나은지 잘 모르겠다.
CSS module 방식도 있고, tailwind 도 있고, styled component 도 있다. 이 것 말고도 많은데, 주로 사용하는 것은 그래도 이정도니까...
전반적으로 요즘은 styled component VS tailwind 정도로 압축되어가고 있는 것 같다.
css in js VS utility-first css 방식의 차이라서,
1. 렌더링 성능을 좀더 우선시 하는 사람이면, tailwind (순수한 css로 봐야 하기 때문에 렌더링 이후에 다시 js로 적용하는 방식에 비해서 속도가 빠르다.)
2. 개발자의 유지보수를 좀 더 우선시 하는 사람이면 Styled component (emotion 포함시키도록 하자. 얘도 영향 받았다고 공식문서에 써있다.)
Styled Components 의 작업방식
import styled from "styled-components";
const Father = styled.div`
display: flex;
`;
const BoxOne = styled.div`
background-color: teal;
width: 100px;
height: 100px;
`;
const BoxTwo = styled.div`
background-color: tomato;
width: 100px;
height: 100px;
`;
const Text = styled.span`
color: white;
`;
function App() {
return (
<Father>
<BoxOne>
<Text>Hello</Text>
</BoxOne>
<BoxTwo />
</Father>
);
}
export default App;
위와 같이 작업이 가능하다. Styled Components라는 말 그대로 Style을 다루는 컴포넌트를 만드는 것이다.
위 코드를 보면, 약간 비효율적으로 보이는 게 width, height 값, 그리고 background-color값을 먹이는 것에 대한 것에 대해 문제가 생긴다. 이 부분에 대해 계속 개선해보자.
그리고 immet 자동 완성 도구가 자꾸 JavaScript로 해줘서 Camel 형태로 된다는 점이 조금 짜증나긴 한다. 뭔가 방법이 있으려나...?
import styled from "styled-components";
const Father = styled.div`
display: flex;
`;
const Box = styled.div`
background-color: ${props => props.bgColor};
width: 100px;
height: 100px;
`;
const Text = styled.span`
color: ${props => props.fontColor};
`;
function App() {
return (
<Father>
<Box bgColor="teal">
<Text fontColor="white">Hello</Text>
</Box>
<Box bgColor="tomato" />
</Father>
);
}
export default App;
개선하면 위와 같이 개선이 가능하다.
결국, 리액트의 Component는 Props에 대한 이해에서 모든 걸 출발한다.
Props를 이용해서 Style에 데이터를 넘겨주는 것이다.
이 걸 좀 더 효율적으로 사용하는 방법을 찾아보면,
결국 컴포넌트의 합성 및 추출 을 이용하는 방법이 있다. 그래서 아래와 같이 작업하게 된다.
import styled from "styled-components";
const Father = styled.div`
display: flex;
`;
const Box = styled.div`
background-color: ${props => props.bgColor};
width: 100px;
height: 100px;
`;
const Circle = styled(Box)`
border-radius: 50px;
`;
const Text = styled.span`
color: ${props => props.fontColor};
`;
function App() {
return (
<Father>
<Box bgColor="teal">
<Text fontColor="white">Hello</Text>
</Box>
<Circle bgColor="tomato" />
</Father>
);
}
export default App;
속성을 넣는 방법
const Input = styled.input.attrs({ required: true, maxLength: 10 })`
background-color: tomato;
`;
function App() {
return (
<Father>
<Input />
<Input />
<Input />
<Input />
</Father>
);
}
위와 같이 input.attrs 에 매개변수로 객체를 넣어서 해결한다.
렌더 결과
스타일드 컴포넌트 자체가 스타일도 컴포넌트로 관리하자라는 것이다.
이 부분에 좀 더 집중해보자.
const roationAnimation = keyframes`
0% {
transform: rotate(0deg);
border-radius: 0px;
}
50% {
border-radius: 100px;
}
100% {
transform: rotate(360deg);
border-radius: 0px;
}
`;
const Box = styled.div`
height: 200px;
width: 200px;
background-color: tomato;
display: flex;
justify-content: center;
align-items: center;
animation: ${roationAnimation} 1s linear infinite;
span { /* Box 컴포넌트 내부 span 태그 조작 */
font-size: 36px;
&:hover {
/* & = span*/
font-size: 98px;
}
&:active {
opacity: 0;
}
`;
function App() {
return (
<Wrapper>
<Box>
<span>😃</span>
</Box>
</Wrapper>
);
}
위와 같은 방식의 조작도 가능하다.
keyframe 룰을 변수로 저장해두고 그걸 컴포넌트에 넣는다. (중요하진 않다. 스킵하자)
Box 컴포넌트 내부에서 span 태그를 조작가능해지게 된다. 이 부분이 매우 쿨한데, span 부분 또한 컴포넌트로 분리해보자. 이 게 좀 더 컴포넌트 단위로 세분화할 수 있게 된다.
const Emoji = styled.span`
font-size: 36px;
`;
const Box = styled.div`
height: 200px;
width: 200px;
background-color: tomato;
display: flex;
justify-content: center;
align-items: center;
animation: ${roationAnimation} 1s linear infinite;
${Emoji} { /* 스타일 컴포넌트 자체를 조작 : 가장 쿨한 부분. */
font-size: 36px;
&:hover {
/* & = span*/
font-size: 98px;
}
&:active {
opacity: 0;
}
`;
function App() {
return (
<Wrapper>
<Box>
<Emoji>😃</Emoji>
</Box>
<Emoji>💗</Emoji>
</Wrapper>
);
}
그러면 위와 같이 조작이 가능해진다.
Box > Emoji 이런식으로 종속되게 구조화할 수 있게 되는 것이다.
당연히 Emoji (Text) 컴포넌트는 따로 사용도 가능하고, Box 내부에 사용될 때는 다른 방식으로 제어하는 것도 가능해진다.
태그만 바꾸어주는 방식
아래와 같이 태그만 바꾸어줄 수도 있다.
<Box bgColor="green">
<Emoji>😃</Emoji>
</Box>
<Box as="a" bgColor="green">
당연한 이야기지만, 컴포넌트 이기 때문에 export해서 가져다 사용하면 된다.
이 효용성 때문에 좀 더 JavaScript 개발자가 다루기 더 유용함.
이에 효율성이 좀 더 증가하는 듯.
// index.js
import React from "react";
import ReactDOM from "react-dom/client";
import { ThemeProvider } from "styled-components"; // ThemeProvider를 import 해줌
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
const darkTheme = { // added
textColor: "whitesmoke",
backgroundColor: "#111",
};
const lightTheme = { // added
textColor: "#111",
backgroundColor: "whitesmoke",
};
root.render(
<React.StrictMode>
<ThemeProvider theme={darkTheme}> // App을 감싸준다.
<App />
</ThemeProvider>
</React.StrictMode>
);
위와 같이 하고나면,
// App.js
import styled from "styled-components";
const Title = styled.h1`
color: ${props => props.theme.textColor}; // props로 theme에 접근이 바로 가능해진다. Cool !!
`;
const Wrapper = styled.div`
display: flex;
width: 100vh;
height: 100vh;
justify-content: center;
align-items: center;
background-color: ${props => props.theme.backgroundColor}; // added
`;
function App() {
return (
<Wrapper>
<Title>goodJob</Title>
</Wrapper>
);
}
export default App;
참고자료
1. 노마드코더
2. 드림코딩엘리
2.
https://react.vlpt.us/styling/03-styled-components.html
'HTML&CSS' 카테고리의 다른 글
[HTML / CSS] a태그(Link) 내에 있는 text를 세로 중앙 정렬하기 (0) | 2022.12.15 |
---|---|
[HTML / CSS] Styled-component 에서 css reset 방법 (0) | 2022.12.12 |
[성능최적화] 차세대 이미지 적용하기 (webp) (0) | 2022.05.25 |
[css] padding, margin 작성 순서 (0) | 2021.10.01 |
[CSS] CSS 수정 시 캐쉬 충돌 방지 하는 방법 (쿼리 스트링) [펌] (0) | 2021.05.25 |
[HTML] Form TAG에서 name의 의미 (0) | 2021.04.30 |
[CSS] PostCSS 장점 (0) | 2021.04.09 |
댓글