[css-in-js] styled-components 특징, 장단점, 오류 해결

2023. 1. 19. 15:42프론트엔드

반응형

 

 

 

Styled components

컴포넌트 기반으로 CSS를 작성할 수 있게 도와주는 라이브러리

 

특징

  • Automatic critical CSS
    • style component는 화면에 컴포넌트가 렌더링 되었는지 추적해 컴포넌트에 대한 스타일을 자동 삽입한다. 코드를 적절히 분배해 놓으면 최소한의 코드만으로 화면이 띄워질 수 있다.
  • No class name bugs
    • styled-component는 스스로 className을 생성하기 때문에 className의 중복이나 오타로 인한 버그를 줄여준다.
  • Easier deletion of CSS
    • Styled Component는 모든 스타일 속성이 특정 컴포넌트와 연결되어 있기 때문에 만약 컴포넌트를 더 이상 사용하지 않아 삭제할 경우 이에 대한 스타일 속성도 함께 삭제된다.
  • Simple dynamic styling
    • className을 일일이 수동으로 관리할 필요 없이 React의 props나 전역 속성을 기반으로 컴포넌트에 스타일 속성을 부여하기 때문에 간단하고 직관적이다.
  • Painless maintenance
    • 컴포넌트에 스타일을 상속하는 속성을 찾아 다른 CSS 파일들을 검색하지 않아도 되기 때문에 코드의 크기가 커지더라도 유지보수가 어렵지 않다.
  • Automatic vendor prefixing
    • 개별 컴포넌트마다 기존의 CSS를 이용하여 스타일 속성을 정의하면 될 뿐이다. 이외의 것들은 Styled Component가 알아서 처리해 준다.

 

설치

npm install styled-components

 

적용

import styled from 'styled-components';

// Create a Title component that'll render an <h1> tag with some styles
const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

// Create a Wrapper component that'll render a <section> tag with some styles
const Wrapper = styled.section`
  padding: 4em;
  background: papayawhip;
`;

// Use Title and Wrapper like any other React component – except they're styled!
render(
  <Wrapper>
    <Title>
      Hello World!
    </Title>
  </Wrapper>
);

 

응용

1. 조건부 스타일링 with props

const Button = styled.button`
  /* Adapt the colors based on primary prop */
  background: ${props => props.primary ? "palevioletred" : "white"};
  color: ${props => props.primary ? "white" : "palevioletred"};
`;

render(
  <div>
    <Button>Normal</Button>
    <Button primary>Primary</Button>
  </div>
);

삼항연산자와 변수 사용은 가능하지만, if문과 for문은 사용할 수 없다.

 

styled 대신 css를 사용해 조건부 설정도 가능하다.

import styled, { css } from "styled-components";

const sizes = {
  large: {
    height: '3rem',
    fontSize: '1.25rem'
  },
  medium: {
    height: '2.25rem',
    fontSize: '1rem'
  },
  small: {
    height: '1.75rem',
    fontSize: '0.875rem'
  }
};

const sizeStyles = css`
  ${({ size }) => css`
    height: ${sizes[size].height};
    font-size: ${sizes[size].fontSize};
  `}
`;

const StyledButton = styled.button`
  ${sizeStyles}
  }
`;

 

2. 스타일링 확장 ( SCSS @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;
`;

render(
  <div>
    <Button>Normal Button</Button>
    <TomatoButton>Tomato Button</TomatoButton>
  </div>
);

 

 

as 속성을 이용하여 이미 만들어둔 css의 태그 변경도 가능하다.

const Button = styled.button`
  display: inline-block;
  color: palevioletred;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
  display: block;
`;

const TomatoButton = styled(Button)`
  color: tomato;
  border-color: tomato;
`;

render(
  <div>
    <Button>Normal Button</Button>
    <Button as="a" href="#">Link with Button styles</Button>
    <TomatoButton as="a" href="#">Link with Tomato Button styles</TomatoButton>
  </div>
);

 

써드파티 컴포넌트도 호환이 가능하다. ex) Link

const StyledLink = styled(Link)`
  color: palevioletred;
  font-weight: bold;
`;

 

 

3. 중첩스코프, 부모참조선택자 등 모두 가능

const Thing = styled.div.attrs((/* props */) => ({ tabIndex: 0 }))`
  color: blue;

  &:hover {
    color: red; // <Thing> when hovered
  }

  & ~ & {
    background: tomato; // <Thing> as a sibling of <Thing>, but maybe not directly next to it
  }

  & + & {
    background: lime; // <Thing> next to <Thing>
  }

  &.something {
    background: orange; // <Thing> tagged with an additional CSS class ".something"
  }

  .something-else & {
    border: 1px solid; // <Thing> inside another element labeled ".something-else"
  }
`

 

4. DOM element의 속성 설정

const Input = styled.input.attrs(props => ({
  type: "text",
  size: props.size || "1em",
}))`
  border: 2px solid palevioletred;
  margin: ${props => props.size};
  padding: ${props => props.size};
`;

// Input's attrs will be applied first, and then this attrs obj
const PasswordInput = styled(Input).attrs({
  type: "password",
})`
  // similarly, border will override Input's border
  border: 2px solid aqua;
`;

 

 

5. ThemeProvider

SCSS에서 variable을 따로 선언하여 관리하던 것과 흡사하다.

최상단 컴포넌트에 themeProvider를 적용하면 따로 상태관리할 필요 없이 전역에서 적용이 가능하다.

 

 

6. GlobalStyle

전체 리셋 css 등 전역 스타일을 적용할 수 있다.

/* GlobalStyle.js */
 
import { createGlobalStyle, css } from "styled-components";
import reset from "styled-reset";
import customReset from "./customReset.scss";

const GlobalStyle = createGlobalStyle`
    ${reset};
    ${customReset}; // 커스텀 리셋파일 모듈 불러오기

    html {
      font-size: 62.5%; //1rem = 10px;
    }

    ${({ theme }) => {
      return css`
        body {
          font-family: ${theme.fonts.family.base};
          font-weight: ${theme.fonts.weight.normal};
          font-size: ${theme.fonts.size.base};
        }
      `;
    }}
`;

export default GlobalStyle;

 

 

오류

 

Warning: Prop `className` did not match.

 

해결

// next.config.js
module.exports = {
  compiler: {
    // Enables the styled-components SWC transform
    styledComponents: true
  }
}

This also makes it so next-swc (speedy web compiler) works to reduce build times.

this experimental value prevents mismatched classes created by styled-components as it is processed by the server and then the client.

 

 

 

더보기

https://react.vlpt.us/styling/03-styled-components.html

 

3. styled-components · GitBook

03. styled-components 이번에 배워볼 기술은 CSS in JS 라는 기술입니다. 이 문구가 뜻하는 그대로, 이 기술은 JS 안에 CSS 를 작성하는 것을 의미하는데요, 우리는 이번 튜토리얼에서 해당 기술을 사용하

react.vlpt.us

https://velog.io/@sonic/%ED%9A%8C%EA%B3%A0-Styled-Components%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%A9%B0#s-dot-%EB%84%A4%EC%9D%B4%EB%B0%8D

 

[회고] Styled-Components를 사용하며

CSS in JS : 자바스크립트를 이용해서 CSS 작성하는 방식Props 전달 : Style 컴포넌트를 만들어 전달받은 props를 이용해 선택적으로 CSS를 사용할 수 있음스타일 컴포넌트를 사용하면서 가장 신경이 쓰

velog.io

https://nextjs.org/docs/advanced-features/compiler#styled-components

 

Advanced Features: Next.js Compiler | Next.js

Learn about the Next.js Compiler, written in Rust, which transforms and minifies your Next.js application.

nextjs.org

https://dkje.github.io/2020/10/13/StyledComponents/

 

[React] Styled Components 사용기 - 어? 쓰흡... 하아.... | Dev X

이 글은 styled components에 대해 공부하며 정리하는 목적으로 작성 되었습니다. 잘못된 정보는 지적해주시면 바로 정정하겠습니다!

dkje.github.io

https://nykim.work/107

 

[ReactJS] 4. styled-components 💅🏾

이 글은 NomadCoders의 와 의 내용 일부를 정리한 글입니다. 🙇🏻‍♀️ 멋진 강의 감사합니다 🙇🏻‍♀️ 개인 스터디 글로, 맞지 않는 내용이나 더 나은 방법을 공유해 주신다면 복받으실 거예

nykim.work

 

 

반응형