Programming/nextjs

Next.js 간단한 첫 블로그를 만들어 보자(3): Assets, Metadata, CSS(2)

조용장 2022. 4. 10. 18:06

오늘은 CSS부분을 다루면서 마무리 디자인 관련해서는 마무리 하겠습니다.

https://nextjs.org/learn/basics/assets-metadata-css/css-styling

 

Learn | Next.js

Production grade React applications that scale. The world’s leading companies use Next.js by Vercel to build pre-rendered applications, static websites, and more.

nextjs.org

nextjs의 첫 앱을 만드는 방법이며 영어로 된 문서를 한글로 작성해보며 작성하고 있습니다. 틀린 부분도 있겠지만.. 지적해주시면 수정해 놓겠습니다~

 

CSS 스타일링

이제 CSS에 대해 이야기 해보겠습니다.

보시다시키 index page에는 이미 몇가지 스타일이 있습니다. pages/index.js 파일을 살펴보면 아래와 같은 코드가 표시되어있는것을 볼수있습니다.

<style jsx>{`
  …
`}</style>

이 페이지는 styled-jsx 라는 라이브러리를 사용하고 있습니다 . 이것은 "CSS-in-JS" 라이브러리입니다. 이 라이브러리를 사용하면 React 구성 요소 내에서 CSS를 작성할 수 있으며 CSS 스타일의 범위가 지정됩니다 (다른 구성 요소는 영향을 받지 않음).

Next.js에는 styled-jsx 에 대한 지원이 내장되어 있지만 styled-components 또는 emotion 과 같은 다른 인기 있는 CSS-in-JS 라이브러리를 사용할 수도 있습니다 .

 

CSS 작성 및 가져오기

Next.js에는 .css 및 .scss 파일을 가져올 수 있는 CSS 및 Sass에 대한 지원이 내장되어 있습니다.

Tailwind CSS와 같은 인기 있는 CSS 라이브러리 사용도 지원됩니다.

 

레이아웃 컴포넌트

먼저 모든 페이지에서 공유할 Layout component를 만들어 보겠습니다.

  • 최상위 폴더에 'components' 폴더를 만듭니다.
  • components폴더 안에 layout.js 파일을 만들고 아래와 같이 파일안에 작성합니다.
export default function Layout({ children }) {
  return <div>{children}</div>
}

 

그런 다음 pages/posts/first-post.js를 열고 Layout component에 대한 import를 추가하고 가장 바깥쪽 구성 요소로 만듭니다.

import Head from 'next/head'
import Link from 'next/link'
import Layout from '../../components/layout'

export default function FirstPost() {
  return (
    <Layout>
      <Head>
        <title>First Post</title>
      </Head>
      <h1>First Post</h1>
      <h2>
        <Link href="/">
          <a>Back to home</a>
        </Link>
      </h2>
    </Layout>
  )
}

 

CSS 추가하기

이제 Layout component에 몇 가지 스타일을 추가해 보겠습니다. CSS 모듈을 사용하여 React 구성 요소에서 CSS 파일을 가져옵니다.

components폴더에 layout.module.css 파일을 생성하고 아래 내용을 파일 안에 작성합니다.

.container {
  max-width: 36rem;
  padding: 0 1rem;
  margin: 3rem auto 6rem;
}

중요: CSS 모듈을 사용하려면 CSS 파일 이름이 .module.css로 끝나야 합니다.

components/layout.js 내에서 이 컨테이너 클래스를 사용하려면 다음을 수행해야 합니다.

  • import에 sytles를 추가하고 css와 같은 이름을 지정합니다.
  • style.container를 className으로 사용
import styles from './layout.module.css'

export default function Layout({ children }) {
  return <div className={styles.container}>{children}</div>
}

지금 http://localhost:3000/posts/first-post 로 이동하면 텍스트가 중앙 컨테이너 안에 있는 것을 볼 수 있습니다.

고유한 클래스 이름을 자동으로 생성

이제 브라우저의 devtools에서 HTML을 살펴보면 Layout 구성 요소에 의해 렌더링된 div에 layout_container__...와 같은 클래스 이름이 있음을 알 수 있습니다.

이것이 CSS 모듈이 하는 일입니다. 고유한 클래스 이름을 자동으로 생성합니다 . CSS 모듈을 사용하는 한 클래스 이름 충돌에 대해 걱정할 필요가 없습니다.

또한 Next.js의 코드 분할 기능은 CSS 모듈에서도 작동합니다. 각 페이지에 대해 최소한의 CSS 로드를 보장합니다. 이로 인해 번들 크기가 더 작아집니다.

CSS 모듈은 빌드 시 JavaScript 번들에서 추출되고 Next.js에 의해 자동으로 로드되는 .css 파일을 생성합니다.

 

전역 스타일

CSS 모듈은 구성 요소 수준 스타일에 유용합니다. 그러나 모든 페이지에서 일부 CSS를 로드하려면 Next.js도 이를 지원합니다.

전역 CSS 파일을 로드하려면 아래 내용을 추가한 pages/_app.js 파일을 만듭니다.

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

이 App component는 다른 모든 페이지에서 공통적으로 사용되는 최상위 component입니다. 예를 들어, 이 App component를 사용하여 페이지 사이를 탐색할 때 상태를 유지할 수 있습니다.

 

개발 서버 다시 시작

중요: pages/_app.js를 추가할 때 개발 서버를 다시 시작해야 합니다. Ctrl + c를 눌러 서버를 중지하고 다음을 실행합니다

npm run dev

전역 CSS 추가

Next.js에서는 pages/_app.js에서 가져와서 전역 CSS 파일을 추가할 수 있습니다. 다른 페이지에서는 전역 CSS를 가져올 수 없습니다.

전역 CSS를 pages/_app.js 외부로 가져올 수 없는 이유는 전역 CSS가 페이지의 모든 요소에 영향을 미치기 때문입니다.

홈페이지에서 /posts/first-post 페이지로 이동하는 경우 홈페이지의 전역 스타일이 의도하지 않게 /posts/first-post에 영향을 미칩니다.

전역 CSS 파일을 아무 곳에나 배치하고 모든 이름을 사용할 수 있습니다. 따라서 다음을 수행해 보겠습니다.

  • 최상위에 styles 폴더를 만들고 폴더 안에 global.css를 만듭니다.
  • styles/global.css에 다음 내용을 추가합니다. 일부 스타일을 재설정하고 태그 색상을 변경합니다.
html,
body {
  padding: 0;
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu,
    Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
  line-height: 1.6;
  font-size: 18px;
}

* {
  box-sizing: border-box;
}

a {
  color: #0070f3;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

img {
  max-width: 100%;
  display: block;
}

마지막으로 page/_app.js를 열고 다음과 같이 CSS 파일을 가져옵니다.

import '../styles/global.css'

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

이제 http://localhost:3000/posts/first-post 에 액세스하면 스타일이 적용된 것을 볼 수 있습니다.

세련되게 레이아웃 다듬기

지금까지는 CSS Modules 와 같은 개념을 설명하기 위해 최소한의 React 및 CSS 코드만 추가했습니다 . 데이터 가져오기에 대한 강의로 넘어가기 전에 페이지 스타일과 코드를 다듬어 보겠습니다.

 

components/layout.module.css 업데이트하기

먼저 components/layout.module.css를 열고 레이아웃 및 프로필 사진에 대해 다음과 같이 보다 세련된 스타일로 내용을 바꿉니다.

.container {
  max-width: 36rem;
  padding: 0 1rem;
  margin: 3rem auto 6rem;
}

.header {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.backToHome {
  margin: 3rem 0 0;
}

 

styles/utils.module.css 만들기

둘째, 여러 구성 요소에서 유용할 타이포그래피 및 기타를 위한 유틸리티 CSS 클래스 세트를 만들어 보겠습니다.

다음 내용이 포함된 styles/utils.module.css라는 새 CSS 파일을 추가해 보겠습니다.

.heading2Xl {
  font-size: 2.5rem;
  line-height: 1.2;
  font-weight: 800;
  letter-spacing: -0.05rem;
  margin: 1rem 0;
}

.headingXl {
  font-size: 2rem;
  line-height: 1.3;
  font-weight: 800;
  letter-spacing: -0.05rem;
  margin: 1rem 0;
}

.headingLg {
  font-size: 1.5rem;
  line-height: 1.4;
  margin: 1rem 0;
}

.headingMd {
  font-size: 1.2rem;
  line-height: 1.5;
}

.borderCircle {
  border-radius: 9999px;
}

.colorInherit {
  color: inherit;
}

.padding1px {
  padding-top: 1px;
}

.list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.listItem {
  margin: 0 0 1.25rem;
}

.lightText {
  color: #666;
}

 

components/layout.js 업데이트하기

셋째, components/layout.js를 열고 내용을 다음 코드로 교체하여 Your Name을 실제 이름으로 변경합니다.

import Head from 'next/head'
import Image from 'next/image'
import styles from './layout.module.css'
import utilStyles from '../styles/utils.module.css'
import Link from 'next/link'

const name = 'Your Name'
export const siteTitle = 'Next.js Sample Website'

export default function Layout({ children, home }) {
  return (
    <div className={styles.container}>
      <Head>
        <link rel="icon" href="/favicon.ico" />
        <meta
          name="description"
          content="Learn how to build a personal website using Next.js"
        />
        <meta
          property="og:image"
          content={`https://og-image.vercel.app/${encodeURI(
            siteTitle
          )}.png?theme=light&md=0&fontSize=75px&images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg`}
        />
        <meta name="og:title" content={siteTitle} />
        <meta name="twitter:card" content="summary_large_image" />
      </Head>
      <header className={styles.header}>
        {home ? (
          <>
            <Image
              priority
              src="/images/profile.jpg"
              className={utilStyles.borderCircle}
              height={144}
              width={144}
              alt={name}
            />
            <h1 className={utilStyles.heading2Xl}>{name}</h1>
          </>
        ) : (
          <>
            <Link href="/">
              <a>
                <Image
                  priority
                  src="/images/profile.jpg"
                  className={utilStyles.borderCircle}
                  height={108}
                  width={108}
                  alt={name}
                />
              </a>
            </Link>
            <h2 className={utilStyles.headingLg}>
              <Link href="/">
                <a className={utilStyles.colorInherit}>{name}</a>
              </Link>
            </h2>
          </>
        )}
      </header>
      <main>{children}</main>
      {!home && (
        <div className={styles.backToHome}>
          <Link href="/">
            <a>← Back to home</a>
          </Link>
        </div>
      )}
    </div>
  )
}

새로운 기능은 다음과 같습니다.

  • 페이지 콘텐츠를 설명하는 데 사용되는 meta tags(og:image 등)를 사용
  • 제목과 이미지의 크기를 조정하는 bool home 변수 사용
  • home이 false인 경우 하단의 "홈으로 돌아가기" 링크 생성
  • 우선 순위 속성이 미리 로드된 next/image가 있는 이미지를 추가

 

pages/index.js 업데이트

마지막으로 홈페이지를 업데이트 하겠습니다.

pages/index.js를 열고 아래 코드로 바꿉니다.

import Head from 'next/head'
import Layout, { siteTitle } from '../components/layout'
import utilStyles from '../styles/utils.module.css'

export default function Home() {
  return (
    <Layout home>
      <Head>
        <title>{siteTitle}</title>
      </Head>
      <section className={utilStyles.headingMd}>
        <p>[Your Self Introduction]</p>
        <p>
          (This is a sample website - you’ll be building a site like this on{' '}
          <a href="https://nextjs.org/learn">our Next.js tutorial</a>.)
        </p>
      </section>
    </Layout>
  )
}

그런 다음 [[Your Self Introduction]]를 자기자신의 소개로 바꾸십시오.

그러면 아래와 같이 작성자 프로필이 나옵니다.

 

이렇게 완성이 되면 다음 강의때 사용할 준비가 끝이 났습니다.!

이 수업을 마무리하기 전에 다음 페이지에서 Next.js의 CSS 지원과 관련된 몇 가지 유용한 기술에 대해 이야기하겠습니다.

 

스타일을 위한 팁

다음은 도움이 될 수 있는 몇 가지 스타일링 팁입니다.

 

classnames 라이브러리를 사용하여 클래스 전환

classnames는 클래스 이름을 쉽게 토글할 수 있는 간단한 라이브러리입니다.

npm install classnames 또는 yarn add classnames를 사용하여 설치할 수 있습니다.

자세한 내용 은 설명서 를 참조하세요. 기본 사용법은 다음과 같습니다.

  • 'success' 또는 'error'가 될 수 있는 유형을 허용하는 Alert component를 생성한다고 가정합니다.
  • 'success'이면 텍스트 색상을 녹색으로 지정합니다. 'error'인 경우 텍스트 색상을 빨간색으로 지정합니다.

먼저 다음과 같이 CSS 모듈(예: alert.module.css)을 작성할 수 있습니다.

.success {
  color: green;
}
.error {
  color: red;
}

다음과 같이 classnames 을 사용합니다.

import styles from './alert.module.css'
import cn from 'classnames'

export default function Alert({ children, type }) {
  return (
    <div
      className={cn({
        [styles.success]: type === 'success',
        [styles.error]: type === 'error'
      })}
    >
      {children}
    </div>
  )
}

 

PostCSS 구성 사용자 정의

기본적으로 구성 없이 Next.js는 PostCSS 를 사용하여 CSS를 컴파일합니다 .

PostCSS 구성을 사용자 지정하려면 postcss.config.js라는 최상위 파일을 생성할 수 있습니다. 이것은 Tailwind CSS와 같은 라이브러리를 사용하는 경우에 유용합니다.

Tailwind CSS를 추가하는 단계는 다음과 같습니다 . 먼저 패키지를 설치합니다.

npm install -D tailwindcss autoprefixer postcss

그런 다음 postcss.config.js를 만듭니다.

// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {}
  }
}

또한 tailwind.config.js에서 콘텐츠 옵션을 지정하여 콘텐츠 소스를 구성하는 것이 좋습니다.

// tailwind.config.js
module.exports = {
  content: [
    './pages/**/*.{js,ts,jsx,tsx}',
    './components/**/*.{js,ts,jsx,tsx}'
    // For the best performance and to avoid false positives,
    // be as specific as possible with your content configuration.
  ]
}

 

Sass 사용하기

기본적으로 Next.js를 사용하면 .scss 및 .sass 확장자를 모두 사용하여 Sass를 가져올 수 있습니다. CSS 모듈 및 .module.scss 또는 .module.sass 확장을 통해 구성 요소 수준 Sass를 사용할 수 있습니다.

Next.js의 내장 Sass 지원을 사용하려면 먼저 sass를 설치해야 합니다.

npm install -D sass

 

여기까지 Assets, Metadata, CSS까지 배워보았습니다.

다음 시간에는 데이터를 가져오는 것을 다루어보겠습니다.!