
Javascript의
CSS-in-JS라이브러리 중 하나로, 스타일을 자바스크립트 파일 내에서 정의하고 관리할 수 있게 해주는 도구이다. 이를 통해 컴포넌트 기반의 웹 애플리케이션에서 스타일을 효율적으로 다룰 수 있다.
Tagged Template Literals을 사용해 스타일을 정의한다.
이를 통해 자바스크립트 파일 안에서 CSS를 작성하고 변수와 조건문을 활용하여 동적인 스타일 생성이 가능하다.
import { css } from '@emotion/react';
const container = css`
color: black;
font-size: 20px;
`;
스타일을 자바스크립트 객체로 표현한다.
이를 통해 컴포넌트 스코프 내에서 스타일 충돌을 방지하고, 재사용 가능한 스타일을 만들 수 있다.
styled 함수를 통해 컴포넌트에 대한 스타일을 직접 정의하고, 이 스타일이 컴포넌트와 결합된다.
import styled from '@emotion/styled';
const Container = styled.div`
color: black;
`;
스타일을 자동으로 최적화하여 불필요한 렌더링을 방지하고 높은 퍼포먼스를 유지할 수 있도록 지원한다.
서버 사이드 렌더링을 지원하며, 서버와 클라이언트 간의 일관된 스타일을 유지할 수 있다.
🌐 공식 홈페이지: https://emotion.sh/docs/introduction
공식 홈페이지에 들어가면 3개의 방식이 있다.
1. Framework Agnostic
프레임워크의 API나 규칙에 의존하지 않고 일반적인 방식으로 코드를 작성할 때 설치
npm i @emotion/css
< 사용 예시 >
import { css } from '@emotion/css'
const color = 'white'
render(
<div
className={css`
padding: 32px;
background-color: hotpink;
font-size: 24px;
border-radius: 4px;
&:hover {
color: ${color};
}
`}
>
Hover to change color.
</div>
)
npm i @emotion/react
< 사용 예시 >
import { css } from '@emotion/react'
const color = 'white'
render(
<div
css={css`
padding: 32px;
background-color: hotpink;
font-size: 24px;
border-radius: 4px;
&:hover {
color: ${color};
}
`}
>
Hover to change color.
</div>
)
npm i @emotion/styled @emotion/react
< 사용 예시 >
import styled from '@emotion/styled'
const Button = styled.button`
padding: 32px;
background-color: hotpink;
font-size: 24px;
border-radius: 4px;
color: black;
font-weight: bold;
&:hover {
color: white;
}
`
render(<Button>This my button component.</Button>)
Emotion 사용법을 익히기위해 간단히 Google API를 통해 책을 검색하는 사이트를 만들어보려고 한다.
🔹참고 : https://emotion.sh/docs/globals
Global Style을 설정하는 것은 간단하다.
Global과 css를 import해주고
<Global styles={css``} /> 이러한 양식 안에 우리가 원래 사용하던 CSS 방식을 사용하면 된다.
import { Global, css } from "@emotion/react";
const Layout = () => {
return (
<>
<Global
styles={css`
body {
background-color: #F2F4F3;
color: #0A0908;
transition-duration: .2s;
transition-property: background-color, color;
}
a {
color: #0A0908;
text-decoration: none;
}
ul {
list-style: none;
padding: 0;
}
`}
/>
<Outlet />
</>
)
}
Global Style 적용 했을 때에는 분명 제대로 잘 적용이 되었는데
Footer에 적용해보니 스타일이 적용되지 않았다.
<button
css={css`
background-color: #F2F4F3;
color: #0A0908;
border: 1px solid #0A0908;
padding: .6rem, 1.5rem;
margin-left: 15px;
border-radius: 3px;
cursor: pointer;
&:hover {
transform: translate(-2px);
}
`}>
Dark Mode
</button>
맞게 잘 작성한 것 같은데 왜 그런지 찾아보다가 개발자 도구로 코드를 확인해보니

이런 문구들이 추가되어있었다.
이러한 현상은 리액트가 런타임 도중 해당 줄을 이해하지 못해서 발생한다고 한다.
두가지 해결 방법이 있는데
/** @jsxImportSource @emotion/react */
나는 1번째 방법을 사용하여 해결하였다.

왜 처음에 Global 스타일을 지정할때는 에러가 발생하지 않았을까❓
<Global />은 Emotion의 Global 스타일을 전역으로 적용하는 컴포넌트인데 이것은 JSX 문법을 사용하지만 특정 리액트 컴포넌트를 가져오는것은 아니기 때문에 오류가 발생하지 않는다.
🔹참고 : https://emotion.sh/docs/theming
theme.js에
export const themLight = {
text: "#221F1B",
background: "#DED6CE"
}
export const themDark = {
text: "#F2F4F3",
background: "#5E503F"
}
이렇게 각 테마에 맞는 색을 지정해준 뒤
App.js로 돌아와 테마를 적용할 부분을 <ThemeProvider />을 이용해 감싸주면 된다.
function App() {
const [isDark, setIsDark] = useState(false);
return (
<BrowserRouter>
<ThemeProvider theme={isDark ? themDark : themLight}>
{...}
</ThemeProvider>
</BrowserRouter>
);
}
그리고 useTheme() hook을 이용하여 theme의 속성들을 알맞은 자리에 넣어주면 끝이다.
const Layout = ({ isDark, setIsDark }) => {
const theme = useTheme();
return (
<>
<Global
styles={css`
body {
background-color: ${theme.background};
color: ${theme.text};
/>
)
}
footer만 보자면 이렇게 잘 적용된걸 볼 수 있다.


🌐 완성 사이트: https://find-book-one.vercel.app/
🌳 Git: https://github.com/yunbiyomi/find-book