23
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ハンズラボAdvent Calendar 2019

Day 17

【BootstrapVue】 Stacked table のスタイルを Sass でカスタマイズする

Last updated at Posted at 2019-12-16

はじめに

BootstrapVue の Stacked table というものがあります。

image.png

普通のテーブルだとヘッダーにあたる部分が左に表示され、データを key, value の形式で表すことができます。
b-table タグに stacked というオプションを入れるだけでこのようになってくれるので非常に頼もしいのですが、
key 項目の文字左寄せ背景色の変更など、スタイルを自由にできないところが難点です。

そこで、Bootstrap の設定を上書きすることで、このようなカワイイ stacked table を作りたいと思います!

image.png
アドベントカレンダーなのでクリスマスカラー🎄

  • vue-cli でのアプリ開発をしたことがある方を対象に書いています。
  • 内容は主に Sass ですが、解説というより「コピペしたら使えるもの」を目指しています。
  • 完全なコードはこちら(github)

環境

vue-cli 3
bootstrap-vue 2.0.2

準備

BootstrapVue をインストール

公式ドキュメントの Getting Started に沿って BootstrapVue の使える環境にします。

$ npm install bootstrap-vue bootstrap

main.js
import Vue from 'vue'
import App from './App.vue'
import BootstrapVue from 'bootstrap-vue'

import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.use(BootstrapVue)

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

Stacked table を作成

HelloWorld.vue
<template>
  <div class="content-area">
    <b-table
      stacked
      :items="items"
      :fields="fields"
    >
    </b-table>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      fields: [
        { key: 'id', label: '商品コード' },
        { key: 'name', label: '商品名' },
        { key: 'group', label: '分類' },
        { key: 'allergies', label: 'アレルギー' },
      ],
      items: [
        {
          id: '628402942632',
          name: 'えびおかき',
          group: '菓子',
          allergies: 'えび'
        }
      ]
    }
  }
}
</script>

<style scoped>
.content-area {
  width: 550px;
  margin: auto;
}
</style>

商品詳細画面を想定し、items はオブジェクトひとつです。

image.png

今から

  • key 項目の文字を左寄せにする
  • key 項目の背景色を変える
  • value 項目の背景を縞々にする
  • ボーダーを消す

をやります。

スタイル上書きファイルの作成

1. Sass が使える環境にします

$ npm install sass-loader node-sass
※ Windowsの場合、Rubyのインストールが必要だそうです。詳しくはググってください。

2. 適当な場所に .scss ファイルを作ります

今回は src/assets の下に scss ディレクトリを噛ませ、 custom.scss という名前で作りました。

src
├── App.vue
├── assets
│   ├── logo.png
│   └── scss
│       └── custom.scss
├── components
│   └── HelloWorld.vue
└── main.js

3. main.js を書き換えます

main.js
import Vue from 'vue'
import App from './App.vue'
import BootstrapVue from 'bootstrap-vue'

//import 'bootstrap/dist/css/bootstrap.css'      // 削除
//import 'bootstrap-vue/dist/bootstrap-vue.css'  // 削除
import './assets/scss/custom.scss'               // 追加
Vue.use(BootstrapVue)
// ・・・

4. custom.scss で Bootstrap の設定を import します

custom.scss
// Bootstrap and its default variables
@import "~bootstrap/scss/bootstrap";
@import "~bootstrap-vue/src";

これで準備完了です!

Sass を書いていく

Sass には記法が2つ、sass 記法と scss 記法があります。
Bootstrap が scss 記法で書かれているので、そちらに合わせて scss で書きます。

key 項目の文字を左寄せにする

先ほどの import の下から書いていきます。

custom.scss
// ・・・
@if $bv-enable-table-stacked {
  .table.b-table {
    &.b-table-stacked {
      @each $breakpoint in map-keys($grid-breakpoints) {
        $next: breakpoint-next($breakpoint, $grid-breakpoints);
        $infix: breakpoint-infix($next, $grid-breakpoints);

        &#{$infix} {
          @include media-breakpoint-down($breakpoint) {

            > tbody {
              > tr {
                > [data-label] {
                  &::before {
                    text-align: left;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

key 項目の要素は <th> ではなく、:before で表現されています。
だから容易にカスタマイズできないんだろうな…

image.png

key項目の背景色を変える

custom.scss
$b-table-stacked-heading-width: 27%;

// Bootstrap and its default variables
@import "~bootstrap/scss/bootstrap";
@import "~bootstrap-vue/src";

// ・・・

            > tbody {
              > tr {
                > td {
                  padding: 0;
                  position: relative;
                }
                > [data-label] {
                  > div {
                    width: 100%;
                    padding: $table-cell-padding;
                    padding-left: 29%;
                  }
                  &::before {
                    text-align: left;
                    color: #ffffff;
                    background-color: #ca1818;
                    padding: $table-cell-padding;
                    position: absolute;
                    height: 100%;
                  }
                > [data-label]:nth-of-type(odd) {
                  &::before {
                    background-color: #157512;
                  }
                }
                }
              }
            }
// ・・・

ポイント解説

  • 一番上の$b-table-stacked-heading-width は Bootstrap-vue の scss ファイル内で使われている変数です。
    この変数を上書きすることで、key 項目の幅を調節できます。

  • ... > [data-label] > divpadding-left: 29%; は、:before 要素の幅分スペースを空けてあげるための記述です。

  • :before要素の height を100%にすることで、value 項目の改行に耐えることができます。

image.png

value項目の背景を縞々にする

custom.scss
// ・・・
            > tbody {
              > tr {
                > td:nth-of-type(odd) {
                  background-color: $table-accent-bg;
                }
// ・・・

$table-accent-bg も Bootstrap に元からある変数です。
普通の table に striped オプションをつけた時と同じ色の縞々になります。

ボーダーを消す

custom.scss
.table {
  td {
    border-top: 0px;
  }
}

あとは微調整して…

できました

image.png

おわりに

上書きする前のスタイルは ./node_modules/bootstrap-vue/src/components/table/_table.scss で確認できます。

Sass というものを初めて触りましたが、css をプログラムっぽく書けるのが面白かったです。
また、一度設定すると全ての vue コンポーネントに反映するので、プロジェクト全体に統一感を与えることができるのも良いなと思いました。
primary とかの variant color をカスタマイズできるのがめっちゃ便利✨

それでは、よいクリスマスを🎅🍻🎅


ハンズラボアドベントカレンダー2019 👉18日目は @mimimi-no-sesese さんです🏓

23
12
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
23
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?