2021.1.26 (수) +3days
emotion.js란?
emotion.js는 CSS-in-JS의 종류 중 하나로 JavaScript 안에서 스타일을 작성할 수 있게 해준다.
emotion.js는 주로 Framework Agostic과 React 두 가지 방식으로 사용된다.
공식문서
https://emotion.sh/docs/introduction
Install
# Framework Agnostic
$ npm install @emotion/css
# React
$ npm install @emotion/react
import
emotion을 사용할 컴포넌트에 import 한다
/** @jsx jsx */
import { jsx, css } from '@emotion/react'
/** @jsx jsx */는 babel에게 React.createElement 대신 jsx를 jsx라는 함수로 변환하라는 뜻이다.
단순히 주석이라 생각하고 쓰지 않는다면 @emotion/react가 적용되지 않는다.
Error
위의 코드를 따라 치면 SyntaxError: ... pragma and pragmaFrag cannot be set when runtime is automatic.와 같은 에러가 뜬다. 이는 리액트가 런타임에서 해당 줄을 인식하지 못하기 때문에 발생하는 에러이다.
가장 쉬운 해결 방법은 공식 문서에 나온 것처럼 import문을 바꾸는 것이다.
/** @jsxImportSource @emotion/react */
import { jsx, css } from '@emotion/react'
그리고 Global Theme으로 설정한 변수를 바로 사용하기에는 @emotion/styled가 훨씬 편하다. 사용법은 styled-components와 똑같다.
import styled from '@emotion/styled'
기본구조
/** @jsxImportSource @emotion/react */
import { css, jsx } from '@emotion/react'
const divStyle = css`
background-color: hotpink;
font-size: 24px;
border-radius: 4px;
padding: 32px;
text-align: center;
&:hover {
color: white;
}
`
export default function App() {
return <div css={divStyle}>Hover to change color.</div>
}
기존에 styled-components를 써본 사람이면 익숙한 구조일 것이다.
import styled from 'styled-components'
const DivStyle = styled.div`
background-color: hotpink;
font-size: 24px;
border-radius: 4px;
padding: 32px;
text-align: center;
&:hover {
color: white;
}
`
export default function App() {
return <DivStyle>Hover to change color.</DivStyle>
}
emotion이 더 편한점은 jsx 안에서 이게 어떤 태그인지 바로 알 수 있다는 점이다.
styled-components는 component 이름에 div, p 등을 써놓지 않으면 이게 어떤 태그인지 바로 알 수 없다. 만약 해당 js파일에 내용이 많아 일일히 찾아야 한다면 엄청 번거롭게 된다.
만약 styled-components처럼 사용하고 싶으면, @emotion/styled를 설치하면 된다.
$ npm install @emotion/styled @emotion/react
import styled from '@emotion/styled'
const DivStyle = styled.div`
background-color: hotpink;
font-size: 24px;
border-radius: 4px;
padding: 32px;
text-align: center;
&:hover {
color: white;
}
`
export default function App() {
return <DivStyle>Hover to change color.</DivStyle>
}
라벨링
emotion.js는 styled-components처럼 브라우저에서 열었을 때 className을 임의로 생성해준다.
재사용
스타일을 입힌 것을 component로 만들어서 어느 곳에서든 재사용이 가능하다.
/** @jsxImportSource @emotion/react */
const P = props => (
<p
css={{
margin: 0,
fontSize: 12,
lineHeight: '1.5',
fontFamily: 'sans-serif',
color: 'blue',
}}
{...props}
/>
)
const ArticleText = props => (
<P
css={{
fontSize: 20,
fontFamily: 'Georgia, serif',
color: 'darkgray',
}}
{...props}
/>
)
export default function App() {
return (
<div>
<P>Using P component</P>
<ArticleText>Using ArticleText component</ArticleText>
</div>
)
}
같은 CSS 속성이 있다면, 제일 최근 것으로 덮어씌워진다. (ex. ArticleText의 fontSize, fontFamily, color로 대체)
만약 component로 사용하여, CSS 속성을 inline으로 쓴다면 따로 css를 써줄 필요도 없으며, 속성명을 camelCase로 작성해야 한다. (ex. fontSize, fontFamily, backgroundColor 등)
Nested Selectors
emotion.js에서 Nested도 사용가능하다.
/** @jsxImportSource @emotion/react */
import { jsx, css } from '@emotion/react'
const paragraph = css`
color: turquoise;
a {
border-bottom: 1px solid red;
cursor: pointer;
}
`
render(
<p css={paragraph}>
Some text.
<a>A link with a bottom border.</a>
</p>
)
Media Queries
반응형은 일반적으로 사용하는 미디어 쿼리와 사용법이 동일하다.
/** @jsxImportSource @emotion/react */
import { jsx, css } from '@emotion/react'
render(
<p
css={css`
font-size: 30px;
@media (min-width: 420px) {
font-size: 50px;
}
`}
>
Some text!
</p>
)
이 외에도, 미리 breakpoint를 선언하여 재사용 가능하게 만드는 법과 facepaint 패키지를 설치하여 더 쉽게 breakpoints를 만들 수도 있다.
emotion 강의를 진행하고 관련 내용을 검색해 다시 한번 스터디 했다.
출근 시간 전 할당된 시간내에 강의를 진행하고 블로그 포스팅 하려고 하니 시간이 굉장히 빠듯하다.
강의는 강의대로 진행하고 정리는 따로 해야하나 고민이 된다.
참고
https://www.howdy-mj.me/css/emotion.js-intro/
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다
댓글