리액트

리액트와 CSS

hpehpeyy 2025. 2. 13. 15:47

Inline Styles

지금까지 다루었던 CSS 적용 방법을 다시 확인해보겠습니다. 일반적으로 다음과 같은 CSS 기술법은 Inline styles(인라인 스타일)이라 부릅니다. 자바스크립트 객체 형태로 CSS 속성과 값을 지정하고 태그의 style에 설정함으로써 스타일을 적용할 수 있습니다.

 

- 직접 기술

return(
    <div style={{width: "100%", padding: "16px"}}>
    	<p style={{color: "blue", textAlig누: "center"}}>Hello world!!</p>
    <div>
)

 

- 사전 정의 후 지정

const containerStyle = {
    width: "100%",
    padding: "16px",
};
const textStyle = {
    color: "blue",
    textAlign: "center",
};

return(
	<div style={containerStyle}>
        <p style={textStyle}Hello World!!</p>
    </div>
)

 

인라인 스타일을 사용할 때는 다음에 주의해야 합니다.

1. 속성명은 캐멀 케이스로 한다.

 (예) text-aling -> textAlign

 

2. 값은 문자열 또는 수치

 (예) color: "blue", margin: 0

 

3. 복잡해지기 쉬우므로 과도하게 사용하지 않는다.

 

인라인 스타일만 사용해 애플리케이션을 만드는 것이 불가능하지는 않지만 대단히 어렵기 때문에 기본적으로는 뒤에서 설명할 스타일링 방법을 몇 가지 사용합니다.


CSS Modules

먼저 CSS Modules에 관해 설명합니다. 기존의 웹 개발과 마찬가지로 .css나 .scss 파일을 정의하는 방법이며 디자이너와 함께 협업하는 환경에서 효과를 얻을 수 있는 선택지입니다.

 

한 가지 다른 점은 리액트 개발의 경우 컴포넌트별로 CSS 파일을 제공하는 경우가 많다는 것을 들 수 있습니다.

 

사전 준비

실제 코드에서 확인해봅시다. 먼저 CssModules.jsx라는 이름의 컴포넌트를 만듭니다.

 

- 사전 준비(CssModules.jsx)

export const CssModules = () => {
    return(
        <div>
            <p>CSS Modules입니다.</p>
            <button>버튼</button>
        </div>
    );
};

 

이 상태에서는 특별한 스타일이 적용되지 않으므로 아래와 같이 표시됩니다.

 

다음으로 필요한 모듈을 추가합니다. 여기에서는 .scss 형식으로 작성할 것이므로 거기에 필요한 node-sass를 NPM에서 설치합니다.

 

- npm에서 설치

npm install sass

 

CSS Modules 사용

컴포넌트와 대응하는 형태로 CSS 파일을 만듭니다. 예제에서는 .scss로 작성하지만 .css로 작성해도 문제없습니다. 이때 파일명.module.scss라는 명칭을 사용해야 합니다. 다음과 같이 세 개의 클래스를 가진 SCSS 파일을 정의합니다.

 

- SCSS 파일 정의(CssModules.module.scss)

.container{
    border: solid 1px #aaa;
    border-radius: 20px;;
    padding: 8px;
    display: flex;
    justify-content: space-around;
    align-items: center;
}
.title{
    margin: 0;
    color: #aaa;
}
.button{
    background-color: #ddd;
    border: none;
    padding: 8px;
    border-radius: 8px;
    &:hover{
        background-color: #aaa;
        color: #fff;
        cursor: pointer;
    }
}

 

정의한 스타일은 색과 여백을 조정하고 텍스트와 버튼을 가로로 배열합니다. 그리고 scss 표기법을 사용할 수 있으므로 &:hover로 버튼에 마우스 커서를 올렸을 때 색과 포인터가 바뀌도록 설정합니다. 이 클래스들을 사용하는 컴포넌트는 다음과 같습니다.

 

- 클래스를 사용하는 컴포넌트(CssModules.jsx)

import classes from "./CssModules.module.scss";

export const CssModules = () => {
    return(
        <div className={classes.container}>
            <p className={classes.title}>CSS Modules입니다.</p>
            <button className={classes.button}>버튼</button>
        </div>
    );
};

 

임의의 이름으로 CSS를 import하고 각 태그의 classsName 속성에 정의한 클래스를 지정하면 다음과 같은 스타일을 적용할 수 있습니다.

 

이렇게 기존의 웹 개발과 비교적 유사한 느낌으로 CSS를 적용할 수 있는 것이 CSS Modules의 장점입니다. 그리고 CSS 클래스명의 스코프는 컴포넌트 안으로 한정됩니다. 예를 들어 다른  컴포넌트에서 container라는 같은 이름으로 클래스명을 정의해도 충돌하지 않으므로(리액트가 고유한 클래스명을 출력하도록 접두사를 부여함) 이름을 정하기 위해 신경 쓰지 않아도 됩니다.


Styled JSX

Styled JSX를 적극적으로 채용하는 팀은 그리 많지 않으나 리액트 프레임워크로 유명한 Next.js에 표준으로 내장되어 있는 라이브러리이므로 함께 소개 합니다. CSS-in-JS라는 컴포넌트 파일에 CSS를 기술하는 라이브러리입니다.

 

사전 준비

StyledJsx.jsx라는 이름의 컴포넌트를 만듭니다.

 

- 사전 준비(StyledJsx.jsx)

export const StyledJsx = () =>{
    return(
        <div>
            <p>Styled JSX입니다.</p>
            <button>버튼</button>
        </div>
    );
};

 

다음으로 필요한 모듈을 추가합니다. styled JSX를 사용하기 위해 필요한 styled-jsx를 NPM에서 설치합니다.

 

- npm에서 설치

npm install styled-jsx

 

Styled JSX 사용

styled JSX에서는 컴포넌트 안에 CSS를 기술합니다. 앞에서와 같은 CSS를 Styled JSX에 적용한 코드는 다음과 같습니다.

 

- css를 Styled JSX에 적용한 코드(StyledJsx.jsx)

.container{
    border: solid 1px #aaa;
    border-radius: 20px;;
    padding: 8px;
    display: flex;
    justify-content: space-around;
    align-items: center;
}
.title{
    margin: 0;
    color: #aaa;
}
.button{
    background-color: #ddd;
    border: none;
    padding: 8px;
    border-radius: 8px;
    &:hover{
        background-color: #aaa;
        color: #fff;
        cursor: pointer;
    }
}

 

다음과 같이 스타일이 적용된 것을 확인합니다.

 

Styled JSX는 컴포넌트 안에서 style 태그를 사용해 CSS를 기술합니다.

style 태그 사용 방법
<style jsx>{`

    /*여기에 CSS를 기술한다.*/
`}</style>

 

style 태그에는 jsx 표기를 사용해야 합니다. 그리고 JSX 표기법에서는 return 이후를 한 개의 태그로 감싸지 않으면 에러가 발생하므로 가장 바깥쪽을 프래그먼트(<></>)로 감쌉니다.

 

button 클래스에는 hover를 지정하지 않았습니다. Styled JSX 표기법에서는 디폴트로 SCSS 표기법은 사용할 수 없다는 점을 주의 바랍니다(사용할 때는 별도 라이브러리를 설치 및 설정해야 합니다).

 

이를 종합하면 Styled JSX는 순수한 리액트 프로젝트에 억지로 맞춰 사용하는 것보다는 Next.js에서 작성한 프로젝트에 CSS-in-JS 방식을 사용하는 경우 효과적이라고 볼 수 있습니다.


styled components

styled components는 큰 인기를 얻고 있는 라이브러리이며 이를 채용한 프로젝트도 많습니다. 스타일을 적용한 컴포넌트를 정의할 수  있다는 점이 큰 특징입니다. styled components도 CSS-in-JS라 불리는 컴포넌트 파일에 CSS를 기술한 라이브러리입니다.

 

사전 준비

StyledComponents.jsx라는 이름의 컴포넌트를 만듭니다.

 

- 사전 준비(StyledComponents.jsx)

export const StyledComponents = () => {
    return(
        <div>
            <p>styled components입니다.</p>
            <button>버튼</button>
        </div>
    );
};

 

다음으로 필요한 모듈을 추가합니다. styled components를 사용할 때 필요한 styled-components를 NPM에서 설치합니다.

 

- npm에서 설치

npm install styled-components

 

styled components 사용

styled components는 컴포넌트 안에 CSS를 기술합니다. 단 지금까지와 달리 className에 클래스를 지정하는 것이 아니라 스타일을 적용한 컴포넌트를 정의합니다. 예를 들어 padding을 설정한 div 태그를 사용할 때는 다음과 같이 정의합니다.

 

- div 태그

import styled from "styled-components";

const StyledDiv = styled.div`
    padding: "8px";
`;

 

- StyledDiv 사용 예

<StyledDiv>
    <p>사용 예</p>
</StyledDiv>

 

styled. 뒤에 HTML에 존재하는 각 태그를 지정함으로써 해당 태그를 확장한 형태로 스타일을 적용할 수 있습니다. 그다음은 백틱(`)으로 감사서 Styled JSX와 마찬가지로 일반적인 CSS와 동일하게 기술합니다. 스타일 적용에 따른 차이를 확인해봅시다.

 

- 스타일 적용(StyledComponents.jsx)

import styled from "styled-components";

export const StyledComponents = () => {
    return(
        <SContainer>
            <STitle>styled components입니다.</STitle>
            <SButton>버튼</SButton>
        </SContainer>
    );
};

const SContainer = styled.div`
    border: solid 1px #aaa;
    border-radius: 20px;
    padding: 8px;
    display: flex;
    justify-content: space-around;
    align-items: center;
`;

const STitle = styled.p`
    margin: 0;
    color: #aaa;
`;

const SButton = styled.button`
    background-color: #ddd;
    border: none;
    padding: 8px;
    border-radius: 8px;
    &:hover{
        background-color: #aaa;
        color: #fff;
        cursor: pointer;
    }
`;

 

다음과 같이 스타일이 적용되는 것을 확인할 수 있습니다.

 

SContainer와 같은 이름은 대문자로 시작하기만 하면 보통의 컴포넌트와 마찬가지로 임의로 정할 수 있습니다. 맨 앞에 대문자 S(Styled의 S)를 부여한 이유는 나중에 코드를 봤을 때 styled components로 작성한 컴포넌트인지, 다른 외부 라이브러리나 컴포넌트인지를 알기 쉽게 하기 위해서입니다.

 

특별한 규칙이 있는 것은 아니지만 프로젝트에 따라 명명 규칙 등을 설정해서 팀 구성원이 통일하도록 하는 것도 좋을 것입니다. styled components는 SCSS 표기법을 그대로 이용하므로 기존 CSS 파일을 사용한 시스템에서 CSS-in-JS로 비교적 쉽게 이행할 수 있다는 것이 장점입니다.


Emotion

이어서 Emotion을 알아봅시다. Emotion도 styled components와 함께 인기가 많은 CSS-in-JS 라이브러리입니다. 이를 채용한 프로젝트 또한 많으며 매우 다양한 사용 방법을 제공하는 것이 특징입니다. 지금까지 배운 것과 비슷한 형태로 작성할 수 있습니다.

- Inline Styles

- Styled JSX

- styled components

 

사전 준비

먼저 Emotion.jsx라는 이름으로 컴포넌트를 만듭니다.

 

- 사전 준비(Emotion.jsx)

export const Emotion = () => {
    return (
        <div>
            <p>Emotion입니다.</p>
            <button>버튼</button>
        </div>
    );
};

 

다음으로 필요한 모듈을 추가합니다. 리액트에서 Emotion을 사용하려면 @emotion/react와 Emotion에서 styled components와 같은 표기법으로 작성할 수 있도록 해주는 @emotion/styled를 NPM에서 설치해야 합니다.

 

- npm에서 설치

npm install @emotion/react @emotion/styled

 

Emotion 사용

Emotion은 다양하게 사용할 수 있는 것이 특징입니다. 순서대로 스타일을 적용하면서 확인해보겠습니다. 또한 Emotion을 사용할 때는 다음과 같이 정해진 규칙으로 코드를 작성해야 합니다.

/** @jsxImportSource @emotion/react */
import { jsx } from "@emotion/react";

 

먼저 Styled JSX와 같이 컴포넌트 파일 안에 CSS를 작성하는 방법입니다. Emotion에서 제공하는 CSS를 사용한다는 점이 다릅니다. div 태그에 스타일을 적용해봅니다.

/** @jsxImportSource @emotion/react */
import {jsx, css} from "@emotion/react";

export const Emotion = () => {
    //scss와 동일하게 작성 가능
    const containerStyle = css`
        border: solid 1px #aaa;
        border-radius: 20px;
        padding: 8px;
        margin: 8px;
        display: flex;
        justify-content: space-around;
        align-items: center;
    `;
    
    return (
        <div css={containerStyle}>
            <p>Emotion입니다.</p>
            <button>버튼</button>
        </div>
    );
};

 

@emotion/react에서 css를 import하고, 스타일 변수를 정의할 때와 태그 안에서도 사용해 지정함으로써 CSS를 적용합니다. SCSS 표기법도 문제없이 사용할 수 있습니다.

 

다음은 Inline Styles와 같이 자바 스크립트 객체로 스타일을 정의하는 예입니다. p 태그에 적용해봅니다.

 

- 자바스크립트 객체로 스타일을 정의하는 방법(Emotion.jsx)

/** @jsxImportSource @emotion/react */
import {jsx, css} from "@emotion/react";

export const Emotion = () => {
    //scss와 동일하게 작성 가능
    const containerStyle = css`
        border: solid 1px #aaa;
        border-radius: 20px;
        padding: 8px;
        margin: 8px;
        display: flex;
        justify-content: space-around;
        align-items: center;
    `;
    //인라인 스타일 작성 방법
    const titleStyle = css({
        margin: 0,
        color: "#aaa"
    });

    return (
        <div css={containerStyle}>
            <p css={containerStyle}>Emotion입니다.</p>
            <button>버튼</button>
        </div>
    );
};

 

CSS를 사용하는 것은 동일하지만 ({})로 감싸고 그 안에 객체를 기술하는 방법입니다. 이 방법은 Inline Styles와 마찬가지로 캐멀 케이스나 문자열로 값을 쓸 때 주의해야 합니다.

 

마지막으로 styled components와 같은 작성 방법의 예입니다. 별도 패키지인 @emotion/styled를 사용합니다. button 태그에 적용해봅니다.

 

- styled components와 같은 작성 방법

/** @jsxImportSource @emotion/react */
import {jsx, css} from "@emotion/react";
import styled from "@emotion/styled";

export const Emotion = () => {
    //scss와 동일하게 작성 가능
    const containerStyle = css`
        border: solid 1px #aaa;
        border-radius: 20px;
        padding: 8px;
        margin: 8px;
        display: flex;
        justify-content: space-around;
        align-items: center;
    `;
    //인라인 스타일 작성 방법
    const titleStyle = css({
        margin: 0,
        color: "#aaa"
    });

    return (
        <div css={containerStyle}>
            <p css={containerStyle}>Emotion입니다.</p>
            <SButton>버튼</SButton>
        </div>
    );
};

//styled-components 작성 방법
const SButton = styled.button`
    background-color: #ddd;
    border: none;
    padding: 8px;
    border-radius: 8px;
    &:hover{
        background-color: #aaa;
        olor: #fff;
        ursor: pointer;
    }
`;

 

사용 방법은 styled components와 완전히 같습니다. 여기까지 구현한 것으로 다음과 같은 스타일이 적용되는 것을 확인할 수 있습니다.

 

이렇게 Emotion은 다양하게 사용할 수 있기 때문에 다양한 방법을 시도할 때 좋은 선택지가 될 수 있습니다. 그러나 규칙을 정하지 않은 상태로 운용하게 되면 각자가 선호하는 작성 방식을 이용하게 되어 유지보수성이 낮아지므로 주의해야 합니다.


Tailwind CSS

Tailwind CSS는 최근 매우 많은 인기를 얻고 있으며 전 세계적으롤 사용자가 많은 CSS 프레임워크입니다. Tailwind CSS는 유틸리티 우선(utility first) 프레임워크입니다. 즉, Tailwind CSS는 flex, text-center와 같이 className에 설정할 수 있는 클래스명의 부품만 제공하며 개발자는 각각을 조합해 사용하면 됩니다. 리액트뿐만 아니라 HTML이나 Vue 등에도 사용할 수 있습니다.

 

사전 준비

TailwindCss.jsx라는 이름의 컴포넌트를 만듭니다.

 

- 사전 준비(TailwindCss.jsx)

export const TailWindCss=()=>{
    return(
        <div>
            <p>Tailwind CSS입니다.</p>
            <button>버튼</button>
        </div>
    );
};

 

다음으로 필요한 모듈을 추가합니다. 리액트에서 Tailwind CSS를 사용하는 데 필요한 것은 NPM에서 설치하면 됩니다.

 

- npm에서 설치

npm install -D tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9
npm install @craco/craco

 

- package.json 수정

package.json을 수정해 CRACO를 사용해 기동하도록 변경합니다.

 

설정 파일 수정(CRACO 추가) (package.json)

  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
  },

 

- craco.config.js 작성

프로젝트 루트에 craco.config.js라는 이름의 파일을 만들고 다음 내용을 설정합니다.

 

설정 파일 추가(craco.config.js 작성)

module.exports={
    style: {
        postcss: {
            plugins: [
                require('tailwindcss'),
                require('autoprefixer'),
            ],
        },
    },
}

 

- tailwind.config.js 작성

다음 명령어를 프로젝트 루트 경로에서 실행합니다.

 

설정 파일 추가(tailwind.config.js작성)

npx tailwindcss init

 

생성된 파일(tailwind.config.js)

module.exports = {
  purge: [],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

 

위의 purge 옵션은 지정한 파일 안에서 사용하지 않는 스타일이 있는 경우 삭제하는 옵션입니다. 컴포넌트와 index.html을 지정합니다.

 

- index.html 지정(tailwind.config.js)

module.exports = {
  purge: ['./src/**/*.{js,jsx,ts,tsx}','./public/index.html'],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

 

- index.css 수정

Tailwind CSS를 사용하도록 index.css에 다음 3행을 추가합니다.

 

설정 파일 수정(index.css 작성) (index.css)

@tailwind base;
@tailwind components;
@tailwind utilities;

 

Tailwind CSS 사용

Tailwind CSS를 사용할 때는 각 태그의 className 속성에 직접 정의한 클래스명을 설정해서 Tailwind CSS가 제공하는 클래스명을 지정하기만 하면 됩니다.

 

- Tailwind CSS를 사용한 구현

export const TailWindCss=()=>{
    return(
        <div className="border border-gray-400 rounded-2xl p-2 m-2 flex justify-around items-center">
            <p className="m-0 text-gray-400">Tailwind CSS입니다.</p>
            <button className="bg-gray-300 border-0 p-2 rounded0md hover:bg-gray-400 hover:text-white">버튼</button>
        </div>
    );
};

 

'리액트' 카테고리의 다른 글

Link vs useNavigate()  (0) 2025.03.04
재렌더링 구조와 최적화  (0) 2025.02.13
리액트 기본  (2) 2025.02.03