はじめに
前回書いた記事「 Nuxt.jsにBulmaを組み込んだら、Vuexストアが理解できた件」の続きみたいなものです。少なくとも設定は同じです。
Bulmaには Footer が、ちゃんと1ページ使って説明されているのに、下部に固定化する方法についてはなにも言及していません。どうやって実現するのかなと調べたら、レイアウトファイルひとつで簡単に実現できたという、またまたアハ体験が待っておりました。
駆け足で、前回の記事を再現
- create-nuxt-appコマンドを使って
avocado
という名前のNuxt.jsアプリを作成 -
pages
ディレクトリにabout.vue
とcontact.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
ファイルを作成します。
<template>
<footer class="footer">
<div class="container">
<div class="content has-text-centered">
<p>
© 2018 Avocado
</p>
</div>
</div>
</footer>
</template>
今回は、新しいレイアウトファイルを用意します。
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
ファイルのスタイル定義が全ページに影響を及ぼしていて、こちらが意図したレイアウトの邪魔をするので、ローカルスコープにします。つまり「そのスタイル定義はそのページのみで有効」にさせます。
<!-- <style>を<style scoped>に変更 -->
<style scoped>
.container
{
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
...
</style>
すでにあるページに新しいレイアウトを適用
ページは何も指定しなければ、自動的にデフォルトのレイアウトが適用されますが、以下のように指定すればそのレイアウトファイルが適用されます。
<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>
その結果がこちらになります。
はい、フッターが浮いております。フッターの下に何もない(恥ずかしい)空間がある。
Bulmaのフッターは特に極太仕様になっておりますが、それでも、スマホの縦長画面では浮いてしまいがちです。このフッターをどうやって下げるかが、本日のお題です。
やっと辿り着いた感が半端ないですが、間もなく終わります。
スティッキーフッター (sticky footer)の実現
layouts/stickyfooter.vue
ファイルを修正します。
sf-site-all
とsf-site-content
という2つのCSSクラスを追加します
<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>
その結果がこちらです。
私のアハ体験ふたつ
「flexboxを使うとこんなに簡単にスティッキーフッターが実現できてしまうのか!」というのがひとつ。今まで後生大事にとっておいたスティッキーフッターのためのCSSテンプレートは捨ててしまいました。
「レイアウトファイルとページファイルを組み合せるための目印になっている<nuxt/>
にもクラス名を付加してよかったんだ!」というのがもうひとつ。どこにも書いてなかったので、できるとは思わなかったのですが、あとから考えてみたら、「どうしてできないと思ったのか?」のほうが不思議ですね。
最後に
冒頭にも書いた通り、Bulmaのフッターを下部に固定する方法はどこにも載っていないのですが、Bulmaの作者からすると「なんで、そんなことわざわざ書かなきゃいけないの?」って感じなんだと思います。「Flexboxを採用したBulmaを採用したあなたなら知ってて当然でしょう」という感覚。いずれ私もそっち側の人間になりたいなと思いつつ、その過程で生まれたアハ体験を、次の人のために記事にしておく次第です。
面白いと思っていただけたら「いいね」をクリックしてください。励みになります。