11.3
CSS-in-JS
CSS-in-JS는 JavaScript 코드 내에서 CSS 스타일을 작성하고 관리할 수 있게 해주는 방법입니다. CSS-in-JS 방식을 사용하면 스타일을 컴포넌트와 함께 결합하여 동적인 스타일 적용과 스코프 범위를 컴포넌트 단위로 제한할 수 있습니다.
Next.js에서 CSS-in-JS를 사용하기 위해서는 아래와 같은 설정이 필요합니다.
useServerInsertedHTML() 훅을 사용하여 규칙을 사용하는 모든 콘텐츠 앞에 규칙을 삽입styled-jsxstyled-jsx는 Next.js에 기본적으로 포함된 CSS-in-JS 라이브러리로, React 컴포넌트에 CSS 스타일을 컴포넌트 단위로 작성하고 스코프를 제한할 수 있도록 해줍니다. styled-jsx를 사용하면 각 컴포넌트에 스타일이 캡슐화되어 다른 컴포넌트와의 스타일 충돌을 방지할 수 있습니다. 또한 간단한 문법으로 CSS를 작성할 수 있으며, Next.js의 SSR(서버 사이드 렌더링)과도 잘 통합됩니다.
styled-jsx를 적용하기 위해서는 먼저 아래 코드와 같이 새로운 style registry를 생성해야 합니다.
// app/registry.tsx
'use client';
import React, { useState } from 'react';
import { useServerInsertedHTML } from 'next/navigation';
import { StyleRegistry, createStyleRegistry } from 'styled-jsx';
function StyledJsxRegistry({ children }: { children: React.ReactNode }) {
// Only create stylesheet once with lazy initial state
const [jsxStyleRegistry] = useState(() => createStyleRegistry());
useServerInsertedHTML(() => {
const styles = jsxStyleRegistry.styles();
jsxStyleRegistry.flush();
return <>{styles}</>;
});
return (
<StyleRegistry registry={jsxStyleRegistry}>{children}</StyleRegistry>
);
}
export default StyledJsxRegistry;
그리고 아래 코드와 같이 생성한 style registry로 RootLayout의 children을 감싸주면 됩니다.
// app/layout.tsx
import StyledJsxRegistry from './registry';
interface RootLayoutProps {
children: React.ReactNode;
}
function RootLayout(props: RootLayoutProps) {
const { children } = props;
return (
<html>
<body>
<StyledJsxRegistry>{children}</StyledJsxRegistry>
</body>
</html>
);
}
export default RootLayout;
styled-componentsstyled-components는 가장 대표적인 CSS-in-JS 라이브러리 중 하나입니다. Next.js에서 styled-components를 사용하기 위해서는, 먼저 아래와 같이 next.config.js 파일에서 styled-components를 활성화해야 합니다.
// next.config.js
module.exports = {
compiler: {
styledComponents: true,
},
};
그런 다음 아래와 같이 styled-components API를 사용하여 렌더링 중에 생성된 모든 CSS 스타일 규칙을 수집하는 전역 레지스트리 컴포넌트를 만듭니다. 이 전역 레지스트리 컴포넌트는 useState() 훅의 초기값으로 함수를 넘기는 lazy initial state라는 방법을 사용하여 stylesheet가 한 번만 생성되도록 합니다. 그리고 useServerInsertedHTML() 훅을 사용하여 레지스트리에 수집된 스타일을 Root Layout의 <head> HTML 태그에 삽입해줍니다.
// lib/registry.tsx
'use client';
import React, { useState } from 'react';
import { useServerInsertedHTML } from 'next/navigation';
import { ServerStyleSheet, StyleSheetManager } from 'styled-components';
function StyledComponentsRegistry({ children }: { children: React.ReactNode }) {
// lazy initial state를 사용하여 stylesheet를 한 번만 생성함
// x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet());
useServerInsertedHTML(() => {
const styles = styledComponentsStyleSheet.getStyleElement();
styledComponentsStyleSheet.instance.clearTag();
return <>{styles}</>;
});
if (typeof window !== 'undefined') return <>{children}</>;
return (
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
{children}
</StyleSheetManager>
);
}
export default StyledComponentsRegistry;
이후 아래 코드와 같이 Root Layout의 children을 StyledComponentsRegistry 컴포넌트로 감싸주면 됩니다.
// app/layout.tsx
import StyledComponentsRegistry from './lib/registry';
interface RootLayoutProps {
children: React.ReactNode;
}
function RootLayout(props: RootLayoutProps) {
const { children } = props;
return (
<html>
<body>
<StyledComponentsRegistry>
{children}
</StyledComponentsRegistry>
</body>
</html>
);
}
export default RootLayout;
마지막 업데이트: 2025년 10월 24일 02시 45분
이 문서의 저작권은 이인제(소플)에 있습니다. 무단 전재와 무단 복제를 금합니다.
On this page