最終更新日: 2023年08月15日

スタイリング

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

ローカルのスタイルシート

ローカルのスタイルシートを作成する場合、assets/ディレクトリに配置してください。。

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

スタイルシートは、ページ、レイアウト、コンポーネントなどから直接インポートすることができます。 JavaScriptのimport文やCSSの@import文を使用することができます。

  • pages/index.vue
  • vue
<script>
    // サーバーサイドとの互換性のために、静的インポートを使用してください。
    import "~/assets/css/first.css";

    // 注意: ダイナミックインポートはサーバーサイドと互換性がありません。
    import("~/assets/css/first.css");
</script>

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

CSSプロパティ

また、nuxt.config.tscssプロパティを設定することで簡単に利用ができます。スタイルシートの配置場所はassets/ディレクトリです。 下記のように記述することで、すべてのページでmain.cssが適用されます。

  • nuxt.config.ts
  • ts
export default defineNuxtConfig({
  css: ["~/assets/css/main.css"],
});

フォントの扱い方

ローカルのフォントファイルは、~/public/ディレクトリ(例:~/public/fonts)に配置します。 その後、スタイルシート内でurl()を使用してください。

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

その後、スタイルシート、ページ、またはコンポーネント内で名前を使ってフォントを参照します。

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

NPMを使用したスタイルシートの適用

npmで配布されているスタイルシートを参照することもできます。ここでは、人気のあるanimate.cssライブラリを例に使用しましょう。

  • npm
  • bash
npm install animate.css

その後、ページ、レイアウト、コンポーネントで直接参照することができます。

  • app.vue
  • vue
<script>
import "animate.css";
</script>

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

また、Nuxtの設定ファイルに記述することで、全体でcssを適用することができます。

  • nuxt.config.ts
  • ts
export default defineNuxtConfig({
  css: ["animate.css"],
});

外部スタイルシート

外部のスタイルシートをアプリケーションに含めるには、nuxt.configファイルのheadセクションにlink要素を追加します。 これを実現するために、異なる方法があります。 また、ローカルのスタイルシートも同様にこの方法で含めることができます。

Nuxtの設定ファイルのapp.headプロパティを使用して、headセクションを操作することができます。

  • nuxt.config.ts
  • 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に動的な値を設定することができます。

  • ts
useHead({
  link: [{ rel: "stylesheet", href: "https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" }],
});

Nuxtは内部でunheadを使用しており、その詳細なドキュメントについてはこちらを参照してください。

Info 「API」 > 「Composables」 > 「Use Head」を参照してください。

Nitroプラグインを使用した(レンダリングされた)ヘッドの変更

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

次のように、~/server/plugins/my-plugin.tsにプラグインを作成します。

  • server/plugins/my-plugin.ts
  • 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ページは、レンダリングに時間がかかる可能性があります。 詳細については、web.devを参照してください。

プリプロセッサの使用

SCSS、Sass、Less、Stylusなどのプリプロセッサを使用するには、まずそれをインストールする必要があります。

  • Sass & SCSS
  • bash
npm install sass

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

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

または、Nuxt の設定の css プロパティを使用することもできます。

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

もし、Sassのパーシャルファイルやカラー変数を含むようなプリプロセッサファイルにコードを挿入する必要がある場合は、vite の preprocessorsオプションを使用することができます。

assets ディレクトリにいくつかのパーシャルファイルを作成してください。

  • assets/_colors.scss
  • scss
$primary: #49240f;
$secondary: #e4a79d;

それから、nuxt.config.js に以下の設定を追加してください。

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

デフォルトでは、NuxtはViteを使用します。Webpackを代わりに使用したい場合は、各プリプロセッサローダーの ドキュメントを参照してください。

シングルファイルコンポーネント(SFC)のスタイリング

VueとSFCの素晴らしい点の一つは、スタイリングの取り扱いが自然であることです。 コンポーネントファイルのstyleブロックに直接CSSまたはプリプロセッサのコードを記述することができます。 そのため、CSS-in-JSのようなものを使用する必要はありません。 ただし、CSS-in-JSを使用したい場合は、pinceauなどのサードパーティのライブラリやモジュールを使用することができます。

SFCでコンポーネントのスタイリングについての包括的な参照については、Vueのドキュメントを参照してください。

クラスとスタイルのバインディング

VueのSFC(Single File Components)の機能を活用して、クラスやスタイル属性を使用してコンポーネントにスタイルを適用することができます。

  • Ref and Reactive
  • vue
<script setup>
const isActive = ref(true);
const hasError = ref(false);
const classObject = reactive({
  active: true,
  "text-danger": false,
});
</script>
<div class="static" :class="{ active: isActive, 'text-danger': hasError }"></div>
<div :class="classObject"></div>
  • computed
  • vue
<script setup>
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"></div>
</template>
  • Array
  • vue
<script setup>
const isActive = ref(true);
const errorClass = ref("text-danger");
</script>

<template>
  <div :class="[{ active: isActive }, errorClass]"></div>
</template>
  • style
  • vue
<script setup>
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>
  <div :style="[baseStyles, overridingStyles]"></div>
  <div :style="styleObject"></div>
</template>

Vueのドキュメントを参照して、詳細な情報を確認してください。

v-bindを利用した動的スタイル

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

  • vue
<script setup>
const color = ref("red");
</script>

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

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

スコープ付きスタイル

scoped属性を使用すると、コンポーネントを隔離してスタイルを適用することができます。 この属性で宣言されたスタイルは、このコンポーネントにのみ適用されます。

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

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

CSS モジュール

module属性を使用してCSSモジュールを利用することができます。$styleという注入された変数を使ってアクセスすることができます。

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

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

プリプロセッサのサポート

SFC(Single File Components)のスタイルブロックは、プリプロセッサの構文をサポートしています。 Viteは、.scss、.sass、.less、.styl、および.stylusファイルの組み込みサポートを提供しており、追加の設定は必要ありません。 まずそれらをインストールし、lang属性を使用してSFC内で直接利用することができます。

  • SCSS
  • scss
// SCSS Sass LESS Style など記述方法は同じ。 例:lang="sass" などになる
<style lang="scss">
    /* Write scss here */
</style>

ViteのCSSドキュメント@vitejs/plugin-vueのドキュメントを参照してください。 Webpackを使用している場合は、 vue-loaderのドキュメントを参照してください。

PostCSSの利用

Nuxtには組み込みのPostCSSが付属しています。nuxt.configファイルで設定することができます。

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

ViteのCSSドキュメントと@vitejs/plugin-vueドキュメントを参照してください。 Webpackを使用している場合は、vue-loaderのドキュメントを参照してください。

  • ts
<style lang="postcss">/* Write stylus here */</style>

デフォルトで、Nuxtには以下のプラグインが事前に設定されています:

  • postcss-import: @importルールを改善します。
  • postcss-url: url()ステートメントを変換します。
  • autoprefixer: ベンダープレフィックスを自動的に追加します。
  • cssnano: 最小化とパージ(不要なコードの削除)を行います。

複数のスタイルを活用するためのレイアウト

もしアプリケーションの異なる部分を完全に異なるスタイルで装飾したい場合は、レイアウトを使用することができます。 異なるレイアウトに対して異なるスタイルを適用します。

  • vue
<template>
  <div class="default-layout">
    <h1>Default Layout</h1>
    <slot />
  </div>
</template>

<style>
.default-layout {
  color: red;
}
</style>

Info 詳細は、「ガイド」 > 「ディレクトリ構築」 > 「レイアウト」をご覧ください。

サードパーティのライブラリやモジュール

Nuxtはスタイリングに関しては意見を持っておらず、さまざまな選択肢を提供しています。 UnoCSSやTailwind CSSなどの人気のあるライブラリなど、好きなスタイリングツールを使用することができます。

コミュニティとNuxtチームは、統合を容易にするために多くのNuxtモジュールを開発しています。 ウェブサイトのモジュールセクションでそれらを見つけることができます。 以下は、始めるのに役立ついくつかのモジュールです:

  • UnoCSS: 即座に利用できるオンデマンドのCSSエンジン
  • Tailwind CSS: ユーティリティファーストのCSSフレームワーク
  • Fontaine: フォントメトリックのフォールバック
  • Pinceau: スタイリングフレームワーク
  • NuxtLabs UI

Nuxtモジュールは、使いやすい開発体験を提供していますが、お気に入りのツールがモジュールとして提供されていない場合でも、それをNuxtと一緒に使用することはできます。 プロジェクトに合わせて自分で設定することができます。 ツールによっては、Nuxtプラグインを使用したり、独自のモジュールを作成する必要があるかもしれません。 自分が作成したものをコミュニティと共有しましょう!

Webフォントの簡単な読み込み

Nuxt Google Fonts モジュールを使用して、Google フォントを読み込むことができます。

UnoCSSを使用している場合は、一般的なプロバイダー(Google Fontsなど)からフォントを便利に読み込むためのWebフォントプリセットが付属していることに注意してください。

高度な設定

トランジション

NuxtはVueと同様に<Transition>要素を持っており、View Transitions APIにも対応しています。

フォントの高度な最適化

CLSを削減するためには、Fontaineの使用をお勧めします。 さらに高度な操作が必要な場合は、Nuxtのビルドプロセスやランタイムを拡張するためのNuxtモジュールを作成することを検討してください。

LCPの高度な最適化

以下の方法を使用して、グローバルCSS(外部CSS)ファイルのダウンロード速度を向上させることができます:

  • CDNの使用:CDNを使用すると、ファイルがユーザーに物理的に近い場所に配置されるため、高速なダウンロードが可能になります。
  • アセットの圧縮:可能であれば、Brotliなどの圧縮アルゴリズムを使用してアセットを圧縮します。 圧縮されたアセットは、ファイルサイズが小さくなり、ダウンロード速度が向上します。
  • HTTP2/HTTP3の使用:HTTP2やHTTP3などの最新のプロトコルを使用してアセットを配信します。 これにより、並行的なダウンロードや効率的なヘッダー圧縮などの恩恵を受けることができます。
  • 同じドメインでのホスティング:アセットを異なるサブドメインではなく、同じドメインでホストするようにします。 これにより、クッキーのオーバーヘッドやDNSのロード時間を削減し、ダウンロード速度を向上させることができます。

もしCloudflare、Netlify、またはVercelなどのモダンなプラットフォームを使用している場合、これらの手法のほとんどは自動的に行われるはずです。 Web.devには、LCPの最適化ガイドがありますので、参考にしてください。 それらのプラットフォームでは、CDNの提供、アセットの圧縮、最新のプロトコルの使用など、パフォーマンスの向上に関する最適化が自動的に行われる場合があります。 そのため、特に手動での設定や調整は必要ありませんが、パフォーマンスの向上を確認するためには適切なテストやモニタリングを行うことが重要です。

もしNuxtによってすべてのCSSがインライン化されている場合、レンダリングされるHTMLから外部のCSSファイルを完全に参照しないようにすることができます(実験的な機能です)。 これは、モジュール内やNuxtの設定ファイル内にフックを配置することで実現できます。

  • nuxt.config.ts
  • ts
export default defineNuxtConfig({
  hooks: {
    "build:manifest": (manifest) => {
      // find the app entry, css list
      const css = manifest["node_modules/nuxt/dist/app/entry.js"]?.css;
      if (css) {
        // start from the end of the array and go to the beginning
        for (let i = css.length - 1; i >= 0; i--) {
          // if it starts with 'entry', remove it from the list
          if (css[i].startsWith("entry")) css.splice(i, 1);
        }
      }
    },
  },
});