리액트에서는 CSS-in-JS을 통해 스타일을 작업을 진행한다.
그중에서는 styled-components, emotion이 가장 유명하고 많이 사용된다.
그래서 우리 모던 애자일 4기 프론트에서는 어떤 라이브러리를 사용할지 선택하기 위해 각각 어떠한 특징과 장점, 단점이 있는지 알아보는 시간을 가지기로 했다.
CSS 파일이 아닌 JavaScript로 작성된 컴포넌트에 바로 삽입하는 스타일 기법이다.
기존에 웹사이트를 개발할 때는 HTML, CSS, JavaScript는 각자 별도의 파일에 두는 것이 best practice로 여겼다. 하지만 React나 Vue, Angular와 같은 모던 자바스크립트 라이브러리가 인기를 끌면서 바뀌고 있다.
여러 개의 컴포넌트로 분리하고, 각 컴포넌트에 HTML. CSS JavaScript를 몽땅 때려 박는 패턴이 많이 사용되고 있다. React는 JSX를 사용해서 이미 JavaScript를 포함하고 있는 형태를 취하고 있는데 여기에 CSS-in-JS 라이브러리만 사용하면 CSS도 손쉽게 JavaScript에 삽입을 할 수 있다.
일단 둘 다 sass 문법을 사용하기에 스타일 문법에는 차이가 없다.
$ npm i styled-components
설치 후에 package.json
에 styled-components
가 추가 된다.
"dependencies": {
"react": "18.0.0",
"react-dom": "18.0.0",
"styled-components": "5.3.5"
},
먼저 styled-components 패키지에 styled()
함수를 임포트한다. styled는 Styled Components의 근간이 되는 가장 중요한 아이이다. HTML 엘리먼트나 React 컴포넌트에 원하는 스타일을 적용하기 위해서 사용된다.
import styled from "styled-components";
styled.button`
// <button> HTML 엘리먼트에 대한 스타일 정의
`;
import styled from "styled-components";
import Button from "./Button";
styled(Button)`
// <Button> React 컴포넌트에 스타일 정의
`;
$ npm i @emotion/react
Styled Components에서 styled()
함수가 중요 했다면 Emotion은 css()
함수이다.
현재는 Styled Components도 css() 함수를 사용할 수 있고, Emotion도 styled() 함수를 제공한다.
Emotion이 css()
함수는 위에서 설치한 @emotion/react
패키지에서 불러올 수 있는데 css()
함수는 CSS 스타일 선언 내용을 인자로 받는데 객체형으로 넘겨도 되고, 문자형으로 넘겨도 된다. 그리고 css()
함수가 반환 결과를 해당 스타일을 적용하고 싶은 HTML 요소나 React 컴포넌트의 css라는 prop에 넘겨주면 된다.
객체형 스타일을 css()
함수의 인자로 넘기면 아래와 같은 모습이 된다.
/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
function MyComponent() {
return (
<div
css={css({
backgroundColor: "yellow",
})}>
노란색 영역
</div>);
}
문자형 스타일을 css()
함수의 인자로 넘기면 아래와 같은 모습이다.
/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
function MyComponent() {
return (
<div
css={css`
background-color: yellow;
`}>
노란색 영역
</div>);
}
Emotion 문서에는 가급적 스타일 객체로 선언해서 css()
함수에 넘기라고 권장한다.
이 방법을 사용하면 css()
함수를 호출을 생략하고 css
prop에 바로 객체로 넘길 수 있으며, 타입스크립크를 사용하면 타입 체킹을 통해 오타를 줄일 수 있다.
<div style={{color: “red”}} />
기존 style 속성은 HTML 인라인 스타일로 주입이 된다. 스타일 우선순위를 다루기 어렵고 스타일 재활용도 힘들다. <div css={css
color: red} >
emotion jsx에서 제공해주는 css 속성을 활용하면 이를 클래스로 변환해준다. 기존이라인으로 사용할 수 없었던 media query, pseudo selector, nested selector등을 사용할 수 있다.<div css={[style, themes[theme], sizes[size]]} />
const themes = {
primary: css`
color: red;
`,
secondary: css`
color: blue;
`
}
const sizes = {
small: css`
fontSize: 0.75rem;
`,
medium: css`
fontSize: 1rem;
`
}
위와 같이 css 변수를 조립하여 컴포넌트 스타일링을 진행할 수 있다.type ThemeType = keyof typeof themes;
type SizeType = keyof typeof size;
typescript로 자동 타입 지정까지 할 수 있다.