ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • emotion 100% 활용하기
    concept/HTML, CSS, DOM 2023. 12. 13. 16:27

    이 전 포스팅에서 emotion과 styled-components의 차이점을 알아보았다.

    결론은 근소한 차이로 emotion의 승리!

     

    https://o-yeon.tistory.com/222

     

    styled-components VS emotion 과연 어떤 차이가 있을까?

    목차 emotion 라이브러리의 종류 알아보기 @emotion/react @emotion/css @emotion/styled emotion 과 styled-component 비교하기 다운로드 순위 비교 번들 사이즈 비교 패키지 의존성 비교 속도 비교 결론은 emotion의 승

    o-yeon.tistory.com

     

     

    그래서 이번 포스팅에서는 emotion을 100% 활용하는 방법에 대해서 알아보고자 한다.

     

    설치하기

    # with npm
    npm i @emotion/css
    npm i @emotion/react
    npm i @emotion/styled @emotion/react

     

    셋 중에 필요한 패키지를 다운로드 해 주자.

    설치가 완료되었다면 사용할 파일에서 import 를 해 준다.

    import styled from '@emotion/styled'

     

    타입스크립트 환경에서 emotion을 사용한다면 tsconfig.json에 해당 코드를 추가해 주어야 한다.

    "compilerOptions": {
        	"types": ["@emotion/react/types/css-prop"]
    }

     

     

    기본 사용 방법

    const Title = styled.h1`
      font-size: 1.5em;
      text-align: center;
      color: #BF4F74;
    `;
    
    const Wrapper = styled.section`
      padding: 4em;
      background: papayawhip;
    `;
    
    render(
      <Wrapper>
        <Title>
          Hello World!
        </Title>
      </Wrapper>
    );

     

    1. 먼저 스타일을 입힐 엘리먼트에 변수를 정한다. (대문자로 시작)

    2. styled 메서드에 원하는 HTML 태그를 붙여준다.

    3. 백틱 (``) 내부에서 기존 CSS 처럼 스타일을 작성하고 1번에서 정한 변수를 JSX에 태그 형태로 적어주면 된다.

     

    기존 CSS 처럼 스타일을 작성하기 때문에 러닝커브가 높지 않은 방법이다.

     

     

    Global CSS 적용 방법

    reset CSS나 폰트같은 global css를 적용하는 방법도 있다.

    styled-components에서는 createGlobalStyle 을 import 해서 쓰고, emotion에서는 Global, css 를 import 해서 사용할 수 있다.

     

    // src/styles/global
    
    import React from 'react';
    import { Global, css } from '@emotion/react';
    
    const style = css`
      html {
        font-size: 12px;
      }
    
      body {
        font-family: 'Noto Sans KR', sans-serif;
      }
    `;
    
    const GlobalStyle = () => {
      return <Global styles={style} />;
    };
    
    export default GlobalStyle;

     

     

    Theme 적용 방법

    Theme은 Style과 Image를 조합한 형태이다.

    테마 라고 보면 된다.

    import { ThemeProvider } from '@emotion/react'
    import styled from '@emotion/styled'
    
    const theme = {
      colors: {
        primary: 'hotpink'
      }
    }
    
    const SomeText = styled.div`
      color: ${props => props.theme.colors.primary};
    `
    
    render(
      <ThemeProvider theme={theme}>
        <SomeText>some text</SomeText>
      </ThemeProvider>
    )

     

    이렇게 ThemeProvider를 import 한 후, 속성으로 theme을 전달할 수 있다.

     

     

     

    Prop에 따라 동적 스타일링 하는 방법

    변수의 상태에 따라 동적으로 스타일링 할 경우에는 props 형태로 동적 스타일링을 하는 것이 유리하다.

    const BoxEach = styled.div`
        width: 200px;
        height:100px;
        margin: 50px;
        border-radius: 30px;
        background-color: ${(props) => props.boxColor? props.boxColor:"green"};
        display:flex;
        align-items:center;
        justify-content:center;
    `
    
    const Box = (props) => {
        return(<>
        	<BoxEach boxColor = {props.boxColor}>
            <BoxText>box</BoxText>
        </BoxEach>
        </>)
    }

     

     

    variant 를 이용해서 동적 스타일링 하는 방법

    const MultipleChoiceAnswer = ({ variant = 'default', totalCount, answeredCount, answerText }: Props) => {
      return (
      ... 중략
          <div css={percentageBar(variant, totalCount === 0 ? 1 : totalCount, answeredCount ?? 1)} />
      ... 중략
      );
    };
    
    const percentageBar = (variant: string, totalCount: number, answeredCount: number) => css`
      position: absolute;
    
      width: calc(100% / ${totalCount} * ${answeredCount});
      height: 48px;
    
      background-color: ${variant === 'default' ? colors.secondary_100 : colors.primary_100};
      border-radius: ${totalCount === answeredCount ? '8px' : '8px 0 0 8px'};
    `;

     

    이렇게 css 를 import 하면 variant를 활용해서 동적 스타일링이 가능하다.

     

     

     

    attribute를 활용하는 방법

    다음과 같이 HTML 태그에 attrs 메서드를 활용해 속성을 추가할 수 있다.

    const Input = styled.input.attrs({
      required: true
    })`
      border-radius: 5px;
    `;

     

    attrs 메서드를 활용하면 css 모듈 분리도 가능하다.

    const addCssType = css`
      background-color: white;
      border-radius: 10px;
      padding: 20px;
    `;
    
    const Input = styled.input.attrs({
      required: true
    })`
      border-radius: 5px;
      ${addCssType}
    `;

     

     

    @extend로 같은 스타일을 확장해서 새로운 스타일을 만드는 방법

    // The Button from the last section without the interpolations
    const Button = styled.button`
      color: palevioletred;
      font-size: 1em;
      margin: 1em;
      padding: 0.25em 1em;
      border: 2px solid palevioletred;
      border-radius: 3px;
    `;
    
    // A new component based on Button, but with some override styles
    const TomatoButton = styled(Button)`
      color: tomato;
      border-color: tomato;
    `;

     

    이렇게 Button 이라는 기본 컴포넌트를 만들고 해당 스타일을 그대로 가지며 컬러만 바뀐 TomatoButton 이라는 컴포넌트를 확장해서 사용할 수도 있다.

     

     

    반응형 작업은 styled-media-query 라는 라이브러리로도 가능하다고 하는데 추후 천천히 작성해 보도록 하겠다.

     

     

     

    댓글

Designed by Tistory.