nuxt logo

ドキュメント翻訳(非公式)

スタイリング

Nuxtアプリケーションのスタイリング方法を学びます。

Nuxtはスタイリングに関して非常に柔軟です。独自のスタイルを書くことも、ローカルや外部のスタイルシートを参照することもできます。 CSSプリプロセッサ、CSSフレームワーク、UIライブラリ、Nuxtモジュールを使用してアプリケーションをスタイルすることができます。

ローカルスタイルシート

ローカルスタイルシートを書く場合、自然な置き場所は app/assets/ ディレクトリ です。

コンポーネント内でのインポート

スタイルシートをページ、レイアウト、コンポーネントに直接インポートできます。 JavaScriptのインポートやCSSの@importステートメントを使用できます。

app/pages/index.vue
<script>
// サーバーサイド互換性のために静的インポートを使用
import '~/assets/css/first.css'

// 注意: 動的インポートはサーバーサイド互換性がありません
import('~/assets/css/first.css')
</script>

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

スタイルシートはNuxtによってレンダリングされたHTMLにインライン化されます。

CSSプロパティ

Nuxtの設定でcssプロパティを使用することもできます。 スタイルシートの自然な置き場所はapp/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/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プラグインでレンダリングされたheadを変更

より高度な制御が必要な場合は、フックを使用してレンダリングされたHTMLをインターセプトし、headをプログラムで変更できます。

~/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

スタイルシートを書く自然な場所はapp/assetsディレクトリです。 その後、プリプロセッサの構文を使用してapp.vue(またはレイアウトファイル)にソースファイルをインポートできます。

app/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のプリプロセッサオプションを使用して行うことができます。

app/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を使った動的スタイル

スタイルブロック内でJavaScript変数や式をv-bind関数で参照できます。 バインディングは動的であり、変数の値が変わるとスタイルが更新されます。

<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ファイルをネイティブにサポートしています。まずそれらをインストールするだけで、SFCでlang属性を使用して直接利用できます。

<style lang="scss">
  /* ここにscssを書く */
</style>

Vite CSSドキュメント@vitejs/plugin-vueドキュメントを参照してください。 webpackユーザーはvue loaderドキュメントを参照してください。

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>Default Layout</h1>
    <slot />
  </div>
</template>

<style>
.default-layout {
  color: red;
}
</style>
こちらも参照 guide > directory-structure > app > 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ランタイムを拡張することを検討してください。

アプリケーションのスタイリングをより簡単かつ効率的にするために、Webエコシステム全体で利用可能なさまざまなツールや技術を活用することを常に忘れないでください。ネイティブCSS、プリプロセッサ、postcss、UIライブラリ、モジュールのいずれを使用しても、Nuxtはあなたをサポートします。スタイリングを楽しんでください!

LCPの高度な最適化

グローバルCSSファイルのダウンロードを高速化するために、以下のことを行うことができます:

  • CDNを使用して、ファイルをユーザーに物理的に近づける
  • アセットを圧縮する、理想的にはBrotliを使用
  • 配信にHTTP2/HTTP3を使用
  • アセットを同じドメインでホストする(異なるサブドメインを使用しない)

これらのほとんどは、Cloudflare、Netlify、Vercelのような現代のプラットフォームを使用している場合、自動的に行われるべきです。 LCP最適化ガイドをweb.devで見つけることができます。

すべての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)
        }
      }
    },
  },
})