Nuxt는 스타일링 측면에서 매우 유연합니다. 직접 스타일을 작성하거나, 로컬 및 외부 스타일시트를 참조할 수 있습니다. CSS 전처리기, CSS 프레임워크, UI 라이브러리 및 Nuxt 모듈을 사용해 애플리케이션을 스타일링할 수 있습니다.
로컬 스타일시트를 작성한다면, 자연스러운 위치는 app/assets/ 디렉터리입니다.
페이지, 레이아웃 및 컴포넌트에서 스타일시트를 직접 가져올 수 있습니다.
JavaScript import 또는 CSS @import 문을 사용할 수 있습니다.
<script>
// 서버 사이드 호환성을 위해 정적 import를 사용하세요
import '~/assets/css/first.css'
// 주의: 동적 import는 서버 사이드와 호환되지 않습니다
import('~/assets/css/first.css')
</script>
<style>
@import url("~/assets/css/second.css");
</style>
Nuxt 설정에서 css 속성을 사용할 수도 있습니다.
스타일시트의 자연스러운 위치는 app/assets/ 디렉터리입니다. 그런 다음 해당 경로를 참조하면 Nuxt가 애플리케이션의 모든 페이지에 이를 포함합니다.
export default defineNuxtConfig({
css: ['~/assets/css/main.css'],
})
로컬 폰트 파일은 public/ 디렉터리에, 예를 들어 public/fonts에 두세요. 그런 다음 스타일시트에서 url()을 사용해 참조할 수 있습니다.
@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을 통해 배포되는 스타일시트를 참조할 수도 있습니다. 예시로 인기 있는 animate.css 라이브러리를 사용해 보겠습니다.
npm install animate.css
yarn add animate.css
pnpm install animate.css
bun install animate.css
그런 다음 페이지, 레이아웃 및 컴포넌트에서 직접 참조할 수 있습니다:
<script>
import 'animate.css'
</script>
<style>
@import url("animate.css");
</style>
패키지는 Nuxt 설정의 css 속성에서 문자열로도 참조할 수 있습니다.
export default defineNuxtConfig({
css: ['animate.css'],
})
nuxt.config 파일의 head 섹션에 link 요소를 추가하여 애플리케이션에 외부 스타일시트를 포함할 수 있습니다. 이 결과는 여러 방법으로 달성할 수 있습니다. 로컬 스타일시트도 이 방식으로 포함할 수 있다는 점에 유의하세요.
Nuxt 설정의 app.head 속성을 사용해 head를 조작할 수 있습니다:
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에 값을 동적으로 설정할 수 있습니다.
useHead({
link: [{ rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css' }],
})
Nuxt는 내부적으로 unhead를 사용하며, 전체 문서를 참고할 수 있습니다.
더 고급 제어가 필요하다면, 훅을 사용해 렌더링된 html을 가로채고 head를 프로그래밍 방식으로 수정할 수 있습니다.
다음과 같이 ~/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
npm install -D less
npm install -D stylus
스타일시트를 작성하기에 자연스러운 위치는 app/assets 디렉터리입니다.
그런 다음 전처리기 문법을 사용해 app.vue(또는 레이아웃 파일)에서 소스 파일을 가져올 수 있습니다.
<style lang="scss">
@use "~/assets/scss/main.scss";
</style>
또는 Nuxt 설정의 css 속성을 사용할 수도 있습니다.
export default defineNuxtConfig({
css: ['~/assets/scss/main.scss'],
})
색상 변수와 같은 Sass partial에 코드를 주입해야 하는 경우, Vite의 preprocessors options를 사용해 그렇게 할 수 있습니다.
app/assets 디렉터리에 일부 partial을 생성하세요:
$primary: #49240F;
$secondary: #E4A79D;
$primary: #49240F
$secondary: #E4A79D
그런 다음 nuxt.config에서:
export default defineNuxtConfig({
vite: {
css: {
preprocessorOptions: {
scss: {
additionalData: '@use "~/assets/_colors.scss" as *;',
},
},
},
},
})
export default defineNuxtConfig({
vite: {
css: {
preprocessorOptions: {
sass: {
additionalData: '@use "~/assets/_colors.sass" as *\n',
},
},
},
},
})
Nuxt는 기본적으로 Vite를 사용합니다. 대신 webpack을 사용하고 싶다면, 각 전처리기 로더의 문서를 참고하세요.
Vite에는 전처리기 사용 속도를 높일 수 있는 실험적 옵션이 제공됩니다.
nuxt.config에서 이를 활성화할 수 있습니다:
export default defineNuxtConfig({
vite: {
css: {
preprocessorMaxWorkers: true, // CPU 개수 - 1
},
},
})
Vue와 SFC의 가장 좋은 점 중 하나는 스타일링을 자연스럽게 처리하는 능력입니다. 컴포넌트 파일의 style 블록에 직접 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 :class="classObject" />
</template>
<script setup lang="ts">
const isActive = ref(true)
const error = ref(null)
const classObject = computed(() => ({
'active': isActive.value && !error.value,
'text-danger': error.value && error.value.type === 'fatal',
}))
</script>
<template>
<div :class="classObject" />
</template>
<script setup lang="ts">
const isActive = ref(true)
const errorClass = ref('text-danger')
</script>
<template>
<div :class="[{ active: isActive }, errorClass]" />
</template>
<script setup lang="ts">
const activeColor = ref('red')
const fontSize = ref(30)
const styleObject = reactive({ color: 'red', fontSize: '13px' })
</script>
<template>
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }" />
<div :style="[baseStyles, overridingStyles]" />
<div :style="styleObject" />
</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>
scoped 속성을 사용하면 컴포넌트를 독립적으로 스타일링할 수 있습니다. 이 속성으로 선언된 스타일은 해당 컴포넌트에만 적용됩니다.
<template>
<div class="example">
hi
</div>
</template>
<style scoped>
.example {
color: red;
}
</style>
module 속성을 사용해 CSS Modules를 사용할 수 있습니다. 주입된 $style 변수를 통해 접근합니다.
<template>
<p :class="$style.red">
This should be red
</p>
</template>
<style module>
.red {
color: red;
}
</style>
SFC style 블록은 전처리기 문법을 지원합니다. Vite는 별도 설정 없이 .scss, .sass, .less, .styl 및 .stylus 파일에 대한 기본 지원을 제공합니다. 먼저 설치만 하면, lang 속성을 사용해 SFC에서 바로 사용할 수 있습니다.
<style lang="scss">
/* 여기에서 scss를 작성하세요 */
</style>
<style lang="sass">
/* 여기에서 sass를 작성하세요 */
</style>
<style lang="less">
/* 여기에서 less를 작성하세요 */
</style>
<style lang="stylus">
/* 여기에서 stylus를 작성하세요 */
</style>
Vite CSS 문서와 @vitejs/plugin-vue 문서를 참고할 수 있습니다. webpack 사용자는 vue loader 문서를 참고하세요.
Nuxt에는 postcss가 기본 내장되어 있습니다. nuxt.config 파일에서 설정할 수 있습니다.
export default defineNuxtConfig({
postcss: {
plugins: {
'postcss-nested': {},
'postcss-custom-media': {},
},
},
})
SFC에서 올바른 문법 하이라이팅을 위해 postcss lang 속성을 사용할 수 있습니다.
<style lang="postcss">
/* 여기에서 postcss를 작성하세요 */
</style>
기본적으로 Nuxt에는 다음 플러그인이 이미 사전 구성되어 있습니다:
@import 규칙을 개선url() 구문을 변환애플리케이션의 서로 다른 부분을 완전히 다르게 스타일링해야 한다면, 레이아웃을 사용할 수 있습니다. 서로 다른 레이아웃에 서로 다른 스타일을 사용하세요.
<template>
<div class="default-layout">
<h1>Default Layout</h1>
<slot />
</div>
</template>
<style>
.default-layout {
color: red;
}
</style>
Nuxt는 스타일링에 대해 의견을 강하게 가지지 않으며, 다양한 옵션을 제공합니다. UnoCSS나 Tailwind CSS 같은 인기 있는 라이브러리를 포함해 원하는 어떤 스타일링 도구든 사용할 수 있습니다.
커뮤니티와 Nuxt 팀은 통합을 더 쉽게 하기 위해 많은 Nuxt 모듈을 개발했습니다. 웹사이트의 modules 섹션에서 이를 찾아볼 수 있습니다. 시작하는 데 도움이 될 몇 가지 모듈은 다음과 같습니다:
Nuxt 모듈은 기본적으로 좋은 개발자 경험을 제공하지만, 선호하는 도구에 모듈이 없다고 해서 Nuxt에서 사용할 수 없다는 뜻은 아닙니다! 프로젝트에 맞게 직접 설정할 수 있습니다. 도구에 따라 Nuxt 플러그인을 사용해야 하거나 직접 모듈을 만들어야 할 수도 있습니다. 만들었다면 커뮤니티와 공유하세요!
Nuxt Google Fonts 모듈을 사용해 Google Fonts를 로드할 수 있습니다.
UnoCSS를 사용하는 경우, Google Fonts를 포함해 일반적인 제공자에서 폰트를 편리하게 로드할 수 있는 web fonts presets이 함께 제공된다는 점에 유의하세요.
Nuxt에는 Vue와 동일한 <Transition> 요소가 포함되어 있으며, 실험적인 View Transitions API도 지원합니다.
CLS를 줄이기 위해 Fontaine을 사용하는 것을 권장합니다. 더 고급 기능이 필요하다면, 빌드 프로세스나 Nuxt 런타임을 확장하는 Nuxt 모듈을 만드는 것을 고려하세요.
전역 CSS 파일 다운로드 속도를 높이기 위해 다음을 수행할 수 있습니다:
Cloudflare, Netlify 또는 Vercel과 같은 최신 플랫폼을 사용 중이라면, 이러한 작업 대부분은 자동으로 처리됩니다. LCP 최적화 가이드는 web.dev에서 확인할 수 있습니다.
모든 CSS가 Nuxt에 의해 인라인 처리되는 경우, (실험적으로) 렌더링된 HTML에서 외부 CSS 파일 참조를 완전히 중단할 수 있습니다. 이는 모듈 또는 Nuxt 설정 파일에 둘 수 있는 훅을 사용해 달성할 수 있습니다.
export default defineNuxtConfig({
hooks: {
'build:manifest': (manifest) => {
// app 엔트리와 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)
}
}
}
},
},
})