Next.js는 js파일에 CSS 파일을 import 할 수 있게 한다. 왜냐하면 Next.js는 import의 컨셉을 javascript를 넘어서(?) 확장했기 때문이다.

Adding a Global Stylesheet

만약 application에 stylesheet를 추가하려면 pages/_app.js 에 CSS 파일을 import해라

예를 들어 아래와 같이 styles.css라는 stylesheet가 있다고 가정하자.

body {
  font-family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', 'Helvetica',
    'Arial', sans-serif;
  padding: 20px 20px 60px;
  max-width: 680px;
  margin: 0 auto;
}

먼저 pages/_app.js파일이 없다면 새로 생성하고 styles.css파일을 import해라

import '../styles.css'

// This default export is required in a new `pages/_app.js` file.
export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

이 스타일은(styles.css) 모든 페이지와 컴포넌트에 적용될 것이다. stylesheets의 전역적인 특성때문에 충돌을 피하기 위해서는 무조건 pages/_app.js에 CSS 파일들을 넣어라.

개발환경에서는 스타일파일들을 수정할 때마다 hot reloaded가 된다.

운영환경에서는 모든 CSS파일들은 하나의 .css에 minified된다.

import styles from node_modules

9.5.4 Next.js 이후로 CSS 파일이 node_modules에 imported 되는건 금지된다.

bootstrap이나 nprogress같은 전역적인 stylesheets 같은 것들에 경우에도 반드시 pages/_app.js 파일에 import 해야한다.

// pages/_app.js
import 'bootstrap/dist/css/bootstrap.css'

export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

만약 3party 라이브러리에 CSS가 import될 필요가 있다면 아래처럼 컴포넌트에도 할 수 있다.

// components/ExampleDialog.js
import { useState } from 'react'
import { Dialog } from '@reach/dialog'
import '@reach/dialog/styles.css'

function ExampleDialog(props) {
  const [showDialog, setShowDialog] = useState(false)
  const open = () => setShowDialog(true)
  const close = () => setShowDialog(false)

  return (
    <div>
      <button onClick={open}>Open Dialog</button>
      <Dialog isOpen={showDialog} onDismiss={close}>
        <button className="close-button" onClick={close}>
          <VisuallyHidden>Close</VisuallyHidden>
          <span aria-hidden>×</span>
        </button>
        <p>Hello there. I am a dialog</p>
      </Dialog>
    </div>
  )
}

Adding Component-Level CSS

Next.js는 [name].module.css파일명 형식의 CSS Modules도 지원한다.

CSS Modules은 독특한 클래스명을 자동으로 생성하면서 지역적으로 CSS를 scope한다. 따라서 동일한 classname을 서로 다른 파일에 클래스명 충돌 걱정없이 사용할 수 있다.

이런방식은 CSS를 component-level에 포함해주는 이상적인 형태로 만든다. CSS Module파일은 application 어디에도 import될 수 있다.

예를 들어 Button컴포넌트를 생각해보자.

먼저 components/Button.module.css를 생성한다.

/*
You do not need to worry about .error {} colliding with any other `.css` or
`.module.css` files!
*/
.error {
  color: white;
  background-color: red;
}

그리고나서 components/Button.js를 생성한다 그리고 CSS파일을 import한다.

import styles from './Button.module.css'

export function Button() {
  return (
    <button
      type="button"
      // Note how the "error" class is accessed as a property on the imported
      // `styles` object.
      className={styles.error}
    >
      Destroy
    </button>
  )
}

CSS Modules은 optional한 기능이고 오직 .module.css라는 확장명을 사용한 파일에만 적용된다. <link> stylesheets나 global CSS파일들은 계속 지원된다.

운영환경에서는 모든 CSS Module파일들은 자동적으로 minified된채 여러개의 .css파일들로 코드스플릿된다. 이런 .css파일들은 application이 빨리 실행되도록 해주는데 app이 paint되기에 최소한의 양의 CSS만 로드되도록 해주기 때문이다.

Sass Support

Next.js는 .scss.sass들도 모두 import할 수 있게 해준다. 또한 .module.scss 또는 .module.sass의 명칭으로 CSS Module의 component-level Sass도 사용가능하다.

Next.js의 Built-in Sass 지원기능을 사용하기 전에 sass를 설치해라.

npm install sass

Sass는 위에 설명한 기본 CSS지원과 동일한 이점과 제한이 있다.

Note: Sass는 2개의 syntax를 지원한다. .scss는 SCSS 문법을 사용하길 요구한다. 반면에 .sass는 들여쓰는 SASS문법을 사용하길 요구한다.
만약 특별히 사용에 대한 기준이 없다면, .scss를 사용해라. 이건 CSS의 상위집합개념이고 SASS에서 사용하는 어떤 들여쓰기 문법도 요구하지 않는다.

Customizing Sass Options

만약 Sass 컴파이리러를 설정하려면 sassOptionsnext.config.js에 활용해라.

const path = require('path')

module.exports = {
  sassOptions: {
    includePaths: [path.join(__dirname, 'styles')],
  },
}

Less and Stylus Support

.less.styl파일을 import하려면 아래 플러그인이 필요한다.

  • @zeit/next-less
  • @zeit/next-stylus

만약 less 플러그인을 사용한다면 less설치하는 것을 잊지마라. 설치하지 않으면 아래같은 에러를 볼것이다.

Error: Cannot find module 'less'

CSS-in-JS

CSS-in-JS 또한 사용가능하다. 아래 예가 있다.

function HiThere() {
  return <p style={{ color: 'red' }}>hi there</p>
}

export default HiThere

독립된 단위에 CSS Scope를 지원하기위해 styled-jsx를 번들한다. 목적은 Web Components같은 "shadow CSS"를 지원하는 것이고 server-rendering에는 지원되지 않는다.

링크는 Styled Components같은 CSS-in-JS 솔루션의 예이다.

컴포넌트에 styled-jsx를 사용하는 예이다.

function HelloWorld() {
  return (
    <div>
      Hello world
      <p>scoped!</p>
      <style jsx>{`
        p {
          color: blue;
        }
        div {
          background: red;
        }
        @media (max-width: 600px) {
          div {
            background: blue;
          }
        }
      `}</style>
      <style global jsx>{`
        body {
          background: black;
        }
      `}</style>
    </div>
  )
}

export default HelloWorld

좀더 자세한 예는 styled-jsx 문서를 확인해라.

FAQ

만약 javascript가 동작하지 않아도 동작하는가?

그렇다. 만약 javascript가 동작하지 않아도 CSS는 운영환경에서 여전히 로드된다. 개발환경에서는 hot reload같은 Fast Refresh 개발경험을 위해서 자바스프립트를 활성화하는 것이 필요하다.

좀 더 깊은 정보를 얻으려면 Customizing PostCSS Config 섹션을 추천한다.

profile
🌃브로콜리한 개발자🌟

0개의 댓글