nuxt logo

문서 번역(비공식)

스타일링

Nuxt 애플리케이션을 스타일링하는 방법을 배웁니다.

Nuxt는 스타일링에 있어 매우 유연합니다. 직접 스타일을 작성하거나 로컬 및 외부 스타일시트를 참조할 수 있습니다. CSS 전처리기, CSS 프레임워크, UI 라이브러리 및 Nuxt 모듈을 사용하여 애플리케이션을 스타일링할 수 있습니다.

로컬 스타일시트

로컬 스타일시트를 작성하는 경우 자연스러운 위치는 assets/ 디렉토리입니다.

컴포넌트 내에서 가져오기

페이지, 레이아웃 및 컴포넌트에서 스타일시트를 직접 가져올 수 있습니다. JavaScript import 또는 CSS @import을 사용할 수 있습니다.

pages/index.vue
<script>
// 서버 사이드 호환성을 위해 정적 import 사용
import '~/assets/css/first.css'

// 주의: 동적 import는 서버 사이드 호환되지 않음
import('~/assets/css/first.css')
</script>

<style>
@import url("~/assets/css/second.css");
</style>

스타일시트는 Nuxt에 의해 렌더링된 HTML에 인라인됩니다.

CSS 속성

Nuxt 구성에서 css 속성을 사용할 수도 있습니다. 스타일시트를 위한 자연스러운 위치는 assets/ 디렉토리입니다. 그런 다음 해당 경로를 참조하면 Nuxt가 애플리케이션의 모든 페이지에 포함시킵니다.

nuxt.config.ts
export default defineNuxtConfig({
  css: ['~/assets/css/main.css']
})

스타일시트는 Nuxt에 의해 렌더링된 HTML에 인라인되며, 전역적으로 주입되어 모든 페이지에 존재합니다.

폰트 작업

로컬 폰트 파일을 ~/public/ 디렉토리에 배치하세요. 예를 들어 ~/public/fonts에 배치할 수 있습니다. 그런 다음 스타일시트에서 url()을 사용하여 참조할 수 있습니다.

assets/css/main.css
@font-face {
  font-family: 'FarAwayGalaxy';
  src: url('/fonts/FarAwayGalaxy.woff') format('woff');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

그런 다음 스타일시트, 페이지 또는 컴포넌트에서 폰트를 이름으로 참조하세요:

<style>
h1 {
  font-family: 'FarAwayGalaxy', sans-serif;
}
</style>

NPM을 통한 스타일시트 배포

npm을 통해 배포되는 스타일시트를 참조할 수도 있습니다. 인기 있는 animate.css 라이브러리를 예로 들어보겠습니다.

npm install animate.css

그런 다음 페이지, 레이아웃 및 컴포넌트에서 직접 참조할 수 있습니다:

app.vue
<script>
import 'animate.css'
</script>

<style>
@import url("animate.css");
</style>

패키지는 Nuxt 구성의 css 속성에 문자열로 참조될 수도 있습니다.

nuxt.config.ts
export default defineNuxtConfig({
  css: ['animate.css']
})

외부 스타일시트

애플리케이션의 nuxt.config 파일의 head 섹션에 링크 요소를 추가하여 외부 스타일시트를 포함할 수 있습니다. 이 결과를 다양한 방법으로 달성할 수 있습니다. 로컬 스타일시트도 이렇게 포함할 수 있습니다.

Nuxt 구성의 app.head 속성을 사용하여 head를 조작할 수 있습니다:

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      link: [{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }]
    }
  }
})

동적으로 스타일시트 추가하기

useHead 컴포저블을 사용하여 코드에서 head에 값을 동적으로 설정할 수 있습니다.

이것도 참고 api > composables > use-head
useHead({
  link: [{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }]
})

Nuxt는 내부적으로 unhead를 사용하며, 전체 문서를 참조할 수 있습니다.

Nitro 플러그인으로 렌더링된 헤드 수정하기

더 고급 제어가 필요한 경우, 후크를 사용하여 렌더링된 HTML을 가로채고 프로그래밍 방식으로 헤드를 수정할 수 있습니다.

~/server/plugins/my-plugin.ts에 다음과 같은 플러그인을 만드세요:

server/plugins/my-plugin.ts
export default defineNitroPlugin((nitro) => {
  nitro.hooks.hook('render:html', (html) => {
    html.head.push('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css">')
  })
})

외부 스타일시트는 렌더링 차단 리소스입니다: 브라우저가 페이지를 렌더링하기 전에 로드되고 처리되어야 합니다. 불필요하게 큰 스타일을 포함하는 웹 페이지는 렌더링 시간이 더 오래 걸립니다. web.dev에서 더 많은 정보를 읽을 수 있습니다.

전처리기 사용하기

SCSS, Sass, Less 또는 Stylus와 같은 전처리기를 사용하려면 먼저 설치하세요.

npm install -D sass

스타일시트를 작성하기에 자연스러운 위치는 assets 디렉토리입니다. 그런 다음 전처리기의 구문을 사용하여 app.vue(또는 레이아웃 파일)에서 소스 파일을 가져올 수 있습니다.

pages/app.vue
<style lang="scss">
@use "~/assets/scss/main.scss";
</style>

또는 Nuxt 구성의 css 속성을 사용할 수 있습니다.

nuxt.config.ts
export default defineNuxtConfig({
  css: ['~/assets/scss/main.scss']
})

두 경우 모두, 컴파일된 스타일시트는 Nuxt에 의해 렌더링된 HTML에 인라인됩니다.

전처리된 파일에 코드 주입이 필요한 경우, 색상 변수와 같은 Sass 부분 파일을 Vite 전처리기 옵션을 사용하여 주입할 수 있습니다.

assets 디렉토리에 일부 부분 파일을 만드세요:

$primary: #49240F;
$secondary: #E4A79D;

그런 다음 nuxt.config에서:

export default defineNuxtConfig({
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: '@use "~/assets/_colors.scss" as *;'
        }
      }
    }
  }
})

Nuxt는 기본적으로 Vite를 사용합니다. 대신 webpack을 사용하려면 각 전처리기 로더 문서를 참조하세요.

전처리기 워커 (실험적)

Vite는 전처리기 사용을 가속화할 수 있는 실험적 옵션을 제공합니다.

nuxt.config에서 이를 활성화할 수 있습니다:


export default defineNuxtConfig({
  vite: {
    css: {
      preprocessorMaxWorkers: true // CPU 수 - 1
    }
  }
})

이것은 실험적 옵션이며 Vite 문서를 참조하고 피드백을 제공해야 합니다.

단일 파일 컴포넌트 (SFC) 스타일링

Vue와 SFC의 가장 좋은 점 중 하나는 스타일링을 자연스럽게 처리하는 것입니다. 컴포넌트 파일의 스타일 블록에 직접 CSS 또는 전처리기 코드를 작성할 수 있으므로 CSS-in-JS와 같은 것을 사용하지 않고도 훌륭한 개발자 경험을 얻을 수 있습니다. 그러나 CSS-in-JS를 사용하고 싶다면 pinceau와 같은 서드파티 라이브러리와 모듈을 찾을 수 있습니다.

SFC에서 컴포넌트를 스타일링하는 것에 대한 포괄적인 참조는 Vue 문서를 참조하세요.

클래스 및 스타일 바인딩

Vue SFC 기능을 활용하여 클래스 및 스타일 속성으로 컴포넌트를 스타일링할 수 있습니다.

<script setup lang="ts">
const isActive = ref(true)
const hasError = ref(false)
const classObject = reactive({
  active: true,
  'text-danger': false
})
</script>

<template>
  <div class="static" :class="{ active: isActive, 'text-danger': hasError }"></div>
  <div :class="classObject"></div>
</template>

더 많은 정보는 Vue 문서를 참조하세요.

v-bind를 사용한 동적 스타일

v-bind 함수를 사용하여 스타일 블록 내에서 JavaScript 변수 및 표현식을 참조할 수 있습니다. 바인딩은 동적이므로 변수 값이 변경되면 스타일이 업데이트됩니다.

<script setup lang="ts">
const color = ref("red")
</script>

<template>
  <div class="text">hello</div>
</template>

<style>
.text {
  color: v-bind(color);
}
</style>

스코프 스타일

스코프 속성을 사용하면 컴포넌트를 독립적으로 스타일링할 수 있습니다. 이 속성으로 선언된 스타일은 해당 컴포넌트에만 적용됩니다.

<template>
  <div class="example">hi</div>
</template>

<style scoped>
.example {
  color: red;
}
</style>

CSS 모듈

CSS 모듈을 module 속성과 함께 사용할 수 있습니다. 주입된 $style 변수를 사용하여 접근합니다.

<template>
  <p :class="$style.red">This should be red</p>
</template>

<style module>
.red {
  color: red;
}
</style>

전처리기 지원

SFC 스타일 블록은 전처리기 구문을 지원합니다. Vite는 .scss, .sass, .less, .styl 및 .stylus 파일에 대한 내장 지원을 제공하며, 구성 없이 사용할 수 있습니다. 먼저 설치하기만 하면 되고, lang 속성을 사용하여 SFC에서 직접 사용할 수 있습니다.

<style lang="scss">
  /* 여기에서 scss 작성 */
</style>

Vite CSS 문서@vitejs/plugin-vue 문서를 참조하세요. webpack 사용자는 vue 로더 문서를 참조하세요.

PostCSS 사용하기

Nuxt는 내장된 postcss를 제공합니다. nuxt.config 파일에서 구성할 수 있습니다.

nuxt.config.ts
export default defineNuxtConfig({
  postcss: {
    plugins: {
      'postcss-nested': {},
      'postcss-custom-media': {}
    }
  }
})

SFC에서 적절한 구문 강조를 위해 postcss lang 속성을 사용할 수 있습니다.

<style lang="postcss">
  /* 여기에서 postcss 작성 */
</style>

기본적으로 Nuxt는 다음과 같은 플러그인을 미리 구성하여 제공합니다:

여러 스타일을 위한 레이아웃 활용

애플리케이션의 다른 부분을 완전히 다르게 스타일링해야 하는 경우, 레이아웃을 사용할 수 있습니다. 다른 레이아웃에 대해 다른 스타일을 사용하세요.

<template>
  <div class="default-layout">
    <h1>기본 레이아웃</h1>
    <slot />
  </div>
</template>

<style>
.default-layout {
  color: red;
}
</style>
이것도 참고 guide > directory-structure > layouts

서드파티 라이브러리 및 모듈

Nuxt는 스타일링에 대해 의견을 제시하지 않으며 다양한 옵션을 제공합니다. UnoCSSTailwind CSS와 같은 인기 있는 라이브러리를 사용할 수 있습니다.

커뮤니티와 Nuxt 팀은 통합을 쉽게 하기 위해 많은 Nuxt 모듈을 개발했습니다. 웹사이트의 모듈 섹션에서 이를 발견할 수 있습니다. 시작하는 데 도움이 되는 몇 가지 모듈은 다음과 같습니다:

  • UnoCSS: 즉시 사용 가능한 원자 CSS 엔진
  • Tailwind CSS: 유틸리티 우선 CSS 프레임워크
  • Fontaine: 폰트 메트릭 대체
  • Pinceau: 적응형 스타일링 프레임워크
  • Nuxt UI: 현대 웹 앱을 위한 UI 라이브러리
  • Panda CSS: 빌드 시 원자 CSS를 생성하는 CSS-in-JS 엔진

Nuxt 모듈은 기본적으로 좋은 개발자 경험을 제공하지만, 좋아하는 도구에 모듈이 없다고 해서 Nuxt에서 사용할 수 없는 것은 아닙니다! 프로젝트에 맞게 직접 구성할 수 있습니다. 도구에 따라 Nuxt 플러그인 및/또는 자체 모듈 만들기가 필요할 수 있습니다. 그렇게 한다면 커뮤니티와 공유하세요!

웹폰트 쉽게 로드하기

Nuxt Google Fonts 모듈을 사용하여 Google Fonts를 로드할 수 있습니다.

UnoCSS를 사용하는 경우, Google Fonts 및 기타 일반 제공업체에서 폰트를 편리하게 로드할 수 있는 웹 폰트 프리셋이 함께 제공됩니다.

고급

전환

Nuxt는 Vue와 동일한 <Transition> 요소를 제공하며, 실험적인 View Transitions API를 지원합니다.

이것도 참고 getting-started > transitions

폰트 고급 최적화

Fontaine를 사용하여 CLS를 줄이는 것을 권장합니다. 더 고급 기능이 필요한 경우, Nuxt 모듈을 만들어 빌드 프로세스나 Nuxt 런타임을 확장하는 것을 고려하세요.

애플리케이션 스타일링을 더 쉽고 효율적으로 만들기 위해 웹 생태계 전반의 다양한 도구와 기술을 활용하는 것을 항상 기억하세요. 네이티브 CSS, 전처리기, postcss, UI 라이브러리 또는 모듈을 사용하든, Nuxt는 여러분을 지원합니다. 스타일링을 즐기세요!

LCP 고급 최적화

글로벌 CSS 파일 다운로드를 가속화하기 위해 다음을 수행할 수 있습니다:

  • 파일이 사용자에게 물리적으로 더 가까운 CDN 사용
  • 자산을 압축, 이상적으로는 Brotli 사용
  • HTTP2/HTTP3를 통한 전송
  • 동일한 도메인에 자산 호스팅 (다른 서브도메인 사용하지 않기)

Cloudflare, Netlify 또는 Vercel과 같은 현대 플랫폼을 사용하면 대부분의 작업이 자동으로 수행됩니다. web.dev에서 LCP 최적화 가이드를 찾을 수 있습니다.

모든 CSS가 Nuxt에 의해 인라인된 경우, 렌더링된 HTML에서 외부 CSS 파일이 참조되지 않도록 (실험적으로) 완전히 중지할 수 있습니다. 모듈이나 Nuxt 구성 파일에 후크를 배치하여 이를 달성할 수 있습니다.

nuxt.config.ts
export default defineNuxtConfig({
  hooks: {
    'build:manifest': (manifest) => {
      // 앱 엔트리, css 목록 찾기
      const css = Object.values(manifest).find(options => options.isEntry)?.css
      if (css) {
        // 배열의 끝에서 시작하여 시작으로 이동
        for (let i = css.length - 1; i >= 0; i--) {
          // 'entry'로 시작하면 목록에서 제거
          if (css[i].startsWith('entry')) css.splice(i, 1)
        }
      }
    },
  },
})