36
22

More than 5 years have passed since last update.

Nuxt.jsに組み込んだBulmaでスティッキーフッター (sticky footer) を実現する

Last updated at Posted at 2018-05-03

はじめに

前回書いた記事「:link: Nuxt.jsにBulmaを組み込んだら、Vuexストアが理解できた件」の続きみたいなものです。少なくとも設定は同じです。

Bulmaには :link: Footer が、ちゃんと1ページ使って説明されているのに、下部に固定化する方法についてはなにも言及していません。どうやって実現するのかなと調べたら、レイアウトファイルひとつで簡単に実現できたという、またまたアハ体験が待っておりました。

駆け足で、前回の記事を再現

  • create-nuxt-appコマンドを使ってavocadoという名前のNuxt.jsアプリを作成
  • pagesディレクトリにabout.vuecontact.vueの2つのファイルを作成し、インデックスページ以外のページを用意
  • componentsディレクトリにNavbar.vueを作成し、ナビゲーションメニューのコンポーネントを用意
  • layouts/default.vueファイルを編集し、ナビゲーションメニューのコンポーネントをレイアウトファイルに取り付け
  • npm run devコマンドを叩いて開発サーバーを起動

avocadoのディレクトリの中はこんな感じになっています

|--components/
|    |--Logo.vue ... index.vueが使用するコンポーネント
|    `--Navbar.vue ... ナビゲーションメニュー
|--layouts/
|    `--default.vue ... デフォルトのレイアウトファイル
`--pages/
     |--about.vue ... 新たに作成したページ
     |--contact.vue ... 新たに作成したページ
     `--index.vue ... 最初から用意されているトップページ

前回の記事ではページ遷移後のメニューのトグルにVuexストアを使っていましたが、@takanoripさんの貴重なコメントにより、Navbar.vueファイルだけで実現できるようになりました。store/index.jsファイルは登場しません。

フッターコンポーネントの作成

componentsディレクトリにBottom.vueファイルを作成します。

components/Bottom.vue
<template>
  <footer class="footer">
    <div class="container">
      <div class="content has-text-centered">
        <p>
          &copy; 2018 Avocado
        </p>
      </div>
    </div>
  </footer>
</template>

今回は、新しいレイアウトファイルを用意します。
layoutsディレクトリにstickyfooter.vueファイルを作成します。
そこにフッターコンポーネントを取り付けます

layouts/stickyfooter.vue
<template>
  <div>
    <navbar/>
    <nuxt/>
    <bottom/>
  </div>
</template>

<script>
import Navbar from '~/components/Navbar.vue'
import Bottom from '~/components/Bottom.vue'

export default {
  components: {
    Navbar,
    Bottom
  }
}
</script>

なぜFooter.vueではなく、Bottom.vueというファイル名にしたかというと、コンポーネントを取り付けるときに、<footer/>という要素名が、すでにHTML5で採用された要素とダブるからです。

話の流れとは直接関係ない修正

pages/index.vueファイルのスタイル定義が全ページに影響を及ぼしていて、こちらが意図したレイアウトの邪魔をするので、ローカルスコープにします。つまり「そのスタイル定義はそのページのみで有効」にさせます。

pages/index.vue
<!-- <style>を<style scoped>に変更 -->
<style scoped>
.container
{
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}
...
</style>

すでにあるページに新しいレイアウトを適用

ページは何も指定しなければ、自動的にデフォルトのレイアウトが適用されますが、以下のように指定すればそのレイアウトファイルが適用されます。

pages/contact.vue
<template>
  <div>
    <section class="hero is-info is-bold">
      <div class="hero-body">
        <h1 class="title is-size-2">
          Contact
        </h1>
        <h2 class="subtitle is-size-4">
          お問い合わせ
        </h2>
      </div>
    </section>
    <div class="container">
      お問い合わせ
    </div>
  </div>
</template>

<script>
export default {
  layout: 'stickyfooter'
}
</script>

その結果がこちらになります。

01a.png

はい、フッターが浮いております。フッターの下に何もない(恥ずかしい)空間がある。
Bulmaのフッターは特に極太仕様になっておりますが、それでも、スマホの縦長画面では浮いてしまいがちです。このフッターをどうやって下げるかが、本日のお題です。

やっと辿り着いた感が半端ないですが、間もなく終わります。

スティッキーフッター (sticky footer)の実現

layouts/stickyfooter.vueファイルを修正します。
sf-site-allsf-site-contentという2つのCSSクラスを追加します

layouts/stickyfooter.vue
<template>
  <div class="sf-site-all">
    <navbar/>
    <nuxt class="sf-site-content"/>
    <bottom/>
  </div>
</template>

<script>
import Navbar from '~/components/Navbar.vue'
import Bottom from '~/components/Bottom.vue'

export default {
  components: {
    Navbar,
    Bottom
  }
}
</script>

<style>
.sf-site-all {
  min-height: 100vh; /* 全体の高さを最低でもビューポートの100%にする */
  display: flex; /* 子クラスを横並びにする */
  flex-direction: column; /* 子クラスの横並びの方向を縦にする */
}
.sf-site-content {
  flex: 1; /* flexに1つだけ数値を指定するとその要素は伸びる */
}
/* NavbarとBottomにはflexを指定しないので伸びない */
/* 結果としてページファイルの中味だけが伸びて、ビューポート100%を実現 */
/* Bottomは下に貼り付く。スティッキーフッターを実現 */
</style>

その結果がこちらです。

2a.png

私のアハ体験ふたつ

「flexboxを使うとこんなに簡単にスティッキーフッターが実現できてしまうのか!」というのがひとつ。今まで後生大事にとっておいたスティッキーフッターのためのCSSテンプレートは捨ててしまいました。

「レイアウトファイルとページファイルを組み合せるための目印になっている<nuxt/>にもクラス名を付加してよかったんだ!」というのがもうひとつ。どこにも書いてなかったので、できるとは思わなかったのですが、あとから考えてみたら、「どうしてできないと思ったのか?」のほうが不思議ですね。

最後に

冒頭にも書いた通り、Bulmaのフッターを下部に固定する方法はどこにも載っていないのですが、Bulmaの作者からすると「なんで、そんなことわざわざ書かなきゃいけないの?」って感じなんだと思います。「Flexboxを採用したBulmaを採用したあなたなら知ってて当然でしょう」という感覚。いずれ私もそっち側の人間になりたいなと思いつつ、その過程で生まれたアハ体験を、次の人のために記事にしておく次第です。

面白いと思っていただけたら「いいね」をクリックしてください。励みになります。

36
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36
22