CDD / CSS-in-JS

유슬기·2023년 2월 20일
0

프론트엔드

목록 보기
45/64

CDD(Component Driven Development)

디자인과 개발 단계에서부터 재사용할 수 있는 UI 컴포넌트를 미리 디자인하고 개발 → 레고처럼 조립해 나갈 수 있는 부품 단위로 UI 컴포넌트를 만들어 나가는 개발 방법

예를 들어, 기존에 사용 중이던 버튼을 다른 화면에도 똑같이 사용해야 할 때, 새로 만들 필요 없이 애초에 재사용이 가능하도록 만들어둔다면 여러 프로젝트 혹은 여러 팀 간에 공유하여 부품을 조립하듯 효율적으로 재사용을 할 수 있다.

CSS-in-JS

구조화된 CSS가 필요하게 된 이유

  1. 프로젝트의 규모나 복잡도 커짐 & 함께 작업해야 할 팀원 수 많아짐 → CSS를 작성하는 일관된 패턴이 없음
  2. 다양한 디바이스들의 등장으로 웹사이트들이 다양한 디스플레이를 커버해야 함 → CSS가 더 복잡해짐

CSS 전처리기(CSS Preprocessor)

CSS 전처리기란, CSS가 구조적으로 작성될 수 있게 도움을 주는 도구로, 대표적으로 SASS 등이 있다.
허나, CSS 전처리기 자체만으로는 웹 서버가 인지하지 못하기 때문에 각 CSS 전처리기에 맞는 컴파일러를 사용해야 한다.

SASS와 같은 전처리기를 사용하면, 특정 속성의 값을 변수로 선언하여 필요한 곳에 선언된 변수를 적용할 수도 있고, 반복되는 코드를 한 번의 선언으로 여러 곳에서 재사용할 수도 있다.

허나, SASS가 CSS의 구조화를 해결해 주는 것의 장점보다 컴파일된 CSS의 용량이 어마어마하게 커지는 등의 문제가 더 많이 발생된다는 것을 발견하게 되었다.

CSS 방법론

위와 같은 CSS 전처리기의 문제를 보완하기 위해 BEM, OOCSS, SMACSS와 같은 CSS 방법론이 대두되었다.
각각의 장단점이 있으나, 세 방법론 모두 같은 아래와 같은 지향점을 가지고 있다.

  • 코드의 재사용
  • 코드의 간결화(유지 보수 용이)
  • 코드의 확장성
  • 코드의 예측성(클래스 명으로 의미 예측)

하지만 이러한 방법론들에서도 클래스명 선택자가 장황해지고, 이런 긴 클래스명 때문에 마크업이 불필요하게 커지며, 재사용하려고 할 때마다 모든 UI 컴포넌트를 명시적으로 확장해야만 하는 등의 문제점이 발생했다.
또한, 언어 로직 상에 진정한 캡슐화의 개념이 없어 클래스명에 의존해야 하는 문제도 있었다.

  • 캡슐화(encapsulation) : 객체의 속성과 행위를 하나로 묶고 실제 구현 내용 일부를 외부에 감추어 은닉하는 개념

CSS-in-JS의 등장

애플리케이션으로 개발 방향이 진화하면서 컴포넌트 단위의 개발은 캡슐화의 중요성을 불러왔다.
하지만 CSS는 컴포넌트 기반의 방식을 위해 만들어진 적이 한 번도 없었다. 결국 CSS 또한 컴포넌트 영역으로 불러들이기 위해 CSS-in-JS가 탄생해 이 문제를 해결하게 된다.

CSS-in-JS에는 대표적으로 Styled-Component가 있다.
Styled-Component는 기능적 혹은 상태를 가진 컴포넌트들로부터 UI를 완전히 분리해 사용할 수 있는 단순한 패턴을 제공한다.

각 CSS 방법론의 특징과 장단점


Styled-Component

CSS 코드를 다룰 때 다음과 같은 불편함을 느껴본 적이 있는가?

  • class, id 이름을 짓느라 고민한 적이 있다.
  • CSS 파일 안에서 내가 원하는 부분을 찾기 힘들었다.
  • CSS 파일이 너무 길어져서 파일을 쪼개서 관리해본 적이 있다.
  • 스타일 속성이 겹쳐서 내가 원하는 결과가 나오지 않은 적이 있다.

이런 불편함을 CSS를 컴포넌트화 시킴으로써 해결해주는 라이브러리가 있다. 바로 React 환경에서 사용 가능한 Styled Components 라는 라이브러리다.

Styled Components는 CSS-in-JS 라는 개념이 대두되면서 나온 라이브러리로, 기존에 HTML, CSS, JS 파일로 쪼개서 개발하던 방법에서 React 등의 라이브러리의 등장으로 컴포넌트 단위 개발이 주류가 되었지만, CSS는 그렇지 못했다는 점에서 출발한 개념이다.

CSS-in-JS 라이브러리를 사용하면 CSS도 쉽게 Javascript 안에 넣어줄 수 있으므로, HTML + JS + CSS까지 묶어서 하나의 JS파일 안에서 컴포넌트 단위로 개발할 수 있게 된다. 이런 CSS-in-JS 라이브러리 중에서 현재 가장 인기 있는 라이브러리가 바로 Styled Components 이다.

Styled-Component 사용하기

  1. 설치
    npm install --save styled-components
  • Styled Components는 package.json에 다음 코드를 추가하도록 권장하고 있다. 아래의 코드를 추가하면 여러 버전의 Styled Components가 설치되어 발생하는 문제를 줄여준다.

    {
      "resolutions": {
        "styled-components": "^5"
      }
    }
  1. Styled Components를 사용할 JS 파일로 불러오기
    import styled from "styled-components"
    여기까지 했다면, Styled-Component를 사용할 준비가 완료된 것이다.

Styled-Components 문법

  1. 컴포넌트 만들기

    import styled from "styled-components";
    
    // 컴포넌트를 선언한 후 styled.태그종류를 할당하고, 백틱 안에 기존에 CSS를 작성하던 문법과 똑같이 스타일 속성을 작성
    const BlueButton = styled.button`
      background-color: blue;
      color: white;
    `;
    
    export default function App() {
      // React 컴포넌트를 사용하듯이 사용하면 된다
      return <BlueButton>Blue Button</BlueButton>;
    }
  2. 컴포넌트를 재활용해 새로운 컴포넌트 만들기

    import styled from "styled-components";
    
    const BlueButton = styled.button`
      background-color: blue;
      color: white;
    `;
    
    //만들어진 컴포넌트를 재활용해 컴포넌트를 만들기
    const BigBlueButton = styled(BlueButton)`
      padding: 10px;
      margin-top: 10px;
    `;
    
    //재활용한 컴포넌트를 또 재활용할 수 있음
    const BigRedButton = styled(BigBlueButton)`
      background-color: red;
    `;
    
    export default function App() {
      return (
        <>
          <BlueButton>Blue Button</BlueButton>
          <br />
          <BigBlueButton>Big Blue Button</BigBlueButton>
          <br />
          <BigRedButton>Big Red Button</BigRedButton>
        </>
      );
    }
  3. Props 활용
    Styled Component로 만든 컴포넌트도 React 컴포넌트처럼 props를 내려줄 수 있다. 내려준 props 값에 따라서 컴포넌트를 렌더링하는 것도 가능하다.

    const 컴포넌트이름 = styled.태그종류`
        CSS속성: ${ (props) => {함수 코드} }
    `;
  • 조건부 렌더링하기

    const Button1 = styled.button`
      background: ${(props) => (props.skyblue ? "skyblue" : "white")};
    `;
    
    export default function App() {
      return (
        <>
          <Button1>Button1</Button1> // 배경 색 white로 지정됨
          <Button1 skyblue>Button1</Button1> // 배경 색 skyblue로 지정됨
        </>
      );
    }
  • Props 값으로 렌더링하기

    //받아온 prop 값을 그대로 이용해 렌더링할 수 있음
    const Button1 = styled.button`
      background: ${(props) => (props.color ? props.color : "white")};
    `;
    //삼항연산자가 아닌 JS 코드라면 무엇이든 사용 가능. 아래와 같은 형식으로도 활용할 수 있음
    const Button2 = styled.button`
      background: ${(props) => props.color || "white"};
    `;
    
    export default function App() {
      return (
        <>
          <GlobalStyle />
          <Button1>Button1</Button1>
          <Button1 color="orange">Button1</Button1>
          <Button1 color="tomato">Button1</Button1>
          <br />
          <Button2>Button2</Button2>
          <Button2 color="pink">Button2</Button2>
          <Button2 color="turquoise">Button2</Button2>
        </>
      );
    }
  • 전역 스타일 설정하기

  1. 우선 전역 스타일을 설정하기 위해 Styled Components에서 createGlobalStyle 함수를 불러온다.
    import { createGlobalStyle } from "styled-components";
  2. createGlobalStyle 함수를 사용해 CSS 파일에서 작성하듯 설정해주고 싶은 스타일을 작성한다.
    const GlobalStyle = createGlobalStyle`
      button {
      padding : 5px;
      margin : 2px;
      border-radius : 5px;
      }
    `
  3. <GlobalStyle> 컴포넌트를 최상위 컴포넌트에서 사용해주면 전역에 <GlobalStyle> 컴포넌트의 스타일이 적용된다.
    function App() {
      return (
        <>
          <GlobalStyle />
          <Button>전역 스타일 적용하기</Button>
        </>
      );
    }

styled Components 실습

style.css 파일에 적용되어 있는 스타일을 styled Components의 컴포넌트로 바꿔보자.

profile
아무것도 모르는 코린이

0개의 댓글