현인
Next.js 튜토리얼 - 2장 CSS 스타일링 본문
이번 장에서는 Next.js 어플리케이션의 다양한 CSS 스타일링 방법을 다뤄볼 예정이다.
2장에서 다룰 내용
- 글로벌 CSS 파일 추가 방법
- CSS 모듈과 Tailwind 스타일링 방법의 차이
- clsx 유틸리티 패키지를 활용한 조건부 클래스 네임 추가 방법
글로벌 스타일링
/app/ui 디렉토리를 보면 global.css 파일을 찾을 수 있다. 이 파일을 활용하여 어플리케이션의 모든 경로에 CSS 규칙을 추가할 수 있다. 예를 들어, CSS 재설정 규칙이나 페이지 전역에 대한 HTML 요소 스타일링 등이 있다.
global.css 파일은 어플리케이션에 모든 컴포넌트에서 불러 올 수 있지만, 가장 상위 컴포넌트에서 불러오는 것이 좋다. Next.js의 경우에는 루트 레이아웃에 해당한다.
/app/layout.tsx 파일로 이동 해서 글로벌 스타일링을 불러온다.
**// '/app/layout.tsx'
import '@/app/ui/global.css'; //글로벌 스타일링 추가**
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
개발 서버가 실행 중인 경우 변경 사항을 저장하면 자동으로 변경사항이 반영된다. 브라우저에 반영된 모습을 보자. 아래와 같이 보일 것이다.
CSS 규칙을 하나도 설정하지 않았는데 어떻게 스타일링이 된 것일까?
global.css 파일의 내부를 살펴보면 @tailwind 규칙이 몇 가지 정의되어 있다.
@tailwind base;
@tailwind components;
@tailwind utilities;
Tailwind
Tailwind는 유틸리티 클래스를 빠르게 작성할 수 있도록 하여 개발 프로세스를 가속화 할 수 있는 CSS 프레임워크이다. TSX 마크업에 직접 추가해보자.
TailWind에서는 클래스 이름을 추가하여 요소의 스타일을 지정한다. 예를 들어 <h1> 태그에 text-blue-500 클래스를 추가하면 텍스트가 파란색으로 바뀐다.
<h1 className="text-blue-500">I'm blue!</h1>
CSS 스타일은 전역적으로 공유되지만, 각 클래스는 각 요소에 개별적으로 적용된다. 즉, 요소를 추가하거나 삭제해도 별도의 스타일시트 유지 관리하므로 스타일 충돌이나 어플리케이션 확장에 따라 증가하는 CSS 번들 크기에 대해 걱정할 필요가 없다.
create-next-app 을 통해 Next.js 프로젝트를 시작할 때 Tailwind를 사용할지 묻는 스텝이 있다. yes 를 선택하면 Next.js가 자동으로 필요한 패키지를 설치하고 Tailwind config 파일을 생성한다.
/app/page.tsx 파일을 보면, Tailwind 클래스들을 사용하고 있는 것을 확인할 수 있다.
import AcmeLogo from '@/app/ui/acme-logo';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';
export default function Page() {
return (
// These are Tailwind classes:
<main className="flex min-h-screen flex-col p-6">
<div className="flex h-20 shrink-0 items-end rounded-lg bg-blue-500 p-4 md:h-52">
// ...
)
}
Tailwind를 처음 사용해보는 사람이더라도 걱정할 필요가 없는 것이, 이번 튜토리얼에서는 이미 클래스들을 적용하여 스타일링을 해두었다.
직접 사용해보긴 해야하니까 간단한 예제를 제공한다. 아래 코드를 /app/page.tsx 파일 내 <p> 태그 위 줄에 추가 해보자.
<div
className="relative w-0 h-0 border-l-[15px] border-r-[15px] border-b-[26px] border-l-transparent border-r-transparent border-b-black"
/>
아래와 같이 검은 삼각형 컴포넌트가 생기는지 브라우저에서 확인해보자.
하지만 개발자마다 익숙한 스타일링 방법이 있을 것이다. CSS 규칙을 직접 작성하거나 JSX와 스타일링은 별도로 유지하는 것을 선호한다면 CSS modules를 사용할 수 있다.
CSS Modules
CSS Modules를 사용하면 자동으로 고유한 클래스 이름을 만들어서 컴포넌트에 CSS 범위를 지정할 수 있으므로 스타일 충돌에 대해 걱정할 필요없다.
이번 튜토리얼에서는 Tailwind를 사용하겠지만, CSS 모듈을 적용하는 방법에 대해서도 알아보자.
/app/ui 내부에 'home.module.css 파일을 만들고 다음과 같이 CSS 규칙을 정의해보자
.shape {
height: 0;
width: 0;
border-bottom: 30px solid black;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
}
그런 다음 /app/page.tsx파일 내부에서 스타일을 가져온 다음 <p> 태그 위에 추가했었던 <div>의 Tailwind 클래스 이름을 styles.shape 로 다음과 같이 바꿔보자.
import AcmeLogo from "@/app/ui/acme-logo";
import { ArrowRightIcon } from "@heroicons/react/24/outline";
import Link from "next/link";
// CSS modules 스타일 파일 가져오기
import styles from "@/app/ui/home.module.css";
export default function Page() {
return (
<main className="flex min-h-screen flex-col p-6">
<div className="flex h-20 shrink-0 items-end rounded-lg bg-blue-500 p-4 md:h-52">
{/* <AcmeLogo /> */}
</div>
<div className="mt-4 flex grow flex-col gap-4 md:flex-row">
<div className="flex flex-col justify-center gap-6 rounded-lg bg-gray-50 px-6 py-10 md:w-2/5 md:px-20">
{/* CSS modules로 정의한 클래스로 변경 */}
<div className={styles.shape} />
<p className={`text-xl text-gray-800 md:text-3xl md:leading-normal`}>
// ...
);
}
변경 사항을 저장하면, 이전과 같은 모양이 보일 것이다.
Tailwind와 CSS 모듈은 Next.js 애플리케이션을 스타일링하는 가장 일반적인 두 가지 방법이다. 둘 중 어떤 스타일링 방법을 사용할지는 선호도 문제다. 심지어 같은 애플리케이션에서 둘 다 사용할 수도 있다.
필자도 Tailwind와 CSS modules를 모두 사용해 본 입장으로서 Tailwind가 확실히 개발 생산성이 높다고 느꼈지만, 인라인 스타일링의 특성상 코드 구조를 빠르게 파악하기 어려워지는 단점도 존재했다. 이런 부분 때문에 CSS modules를 선호하는 사람들도 많았다.
clsx 라이브러리 활용 조건부 스타일링
개발을 하다보면 조건에 따라 달라지는 스타일 구현이 필요한 경우가 있었을 것이다.
clsx는 클래스 네임을 선택할 수 있게 해주는 라이브러리다. 자세한 활용은 clsx 공식문서를 참고하면 되고, 일단 기본적인 사용 방법을 살펴보겠다.
아래와 같은 조건이 주어졌을 때, clsx 라이브러리를 활용하여 구현해보자.
- ‘pending’ 혹은 ‘paid’ 두 가지 상태를 가지는 status 라는props 를 받는InvoiceStatus 컴포넌트를 만들 것이다.
- ‘paid’ 상태일 경우 초록색, ‘pending’ 상태일 경우 회색으로 칠해져야 한다.
import clsx from 'clsx';
export default function InvoiceStatus({ status }: { status: string }) {
return (
<span
className={clsx(
'inline-flex items-center rounded-full px-2 py-1 text-sm',
{
'bg-gray-100 text-gray-500': status === 'pending',
'bg-green-500 text-white': status === 'paid',
},
)}
>
// ...
)}
위와 같이 만들 수 있다.
그 외 스타일링 방법
Next.js 어플리케이션에서는 위에서 다룬 스타일링 방법말고도 다른 스타일링 방법도 사용할 수 있다.
- Sass
- styled-jsx
- styled-component
- emotion
Next.js CSS 문서에서 보다 많은 정보를 확인할 수 있다.
마치며
CSS 스타일링의 경우 React를 활용할 때와 큰 차이점은 없다. 아무래도 React 기반의 프레임워크이기 때문이지 않을까 싶다.
학습 자료
'기술 학습 > NextJS' 카테고리의 다른 글
[Next.js] 동적 렌더링 최적화하기 (1) | 2024.11.25 |
---|---|
Next.js 튜토리얼 - 5장 페이지 네비게이팅 (2) | 2024.11.15 |
Next.js 튜토리얼 - 4장 레이아웃 및 페이지 만들기 (1) | 2024.11.15 |
Next.js 튜토리얼 - 3장 폰트 및 이미지 최적화 (4) | 2024.11.08 |
Next.js 튜토리얼 - 1장 시작하기 (5) | 2024.11.06 |