bootstrapvueの使い方全覚書(横並び,b-container,b-col,b-form-radio)

おすすめのオンラインプログラミング学習

軽くbootstrapvueを使っているため、覚書を残しておきます。bootstrapの記事を何記事も書きたくないため、この記事に全部まとめています。

公式サイトをみると大抵のことは丁寧に書いてくれています(英語)が、デフォルト値などが邪魔になることやbootstrapを使わない方がよいケースもあるため、実践で気付いたことを含めてまとめです。

目次

【使い方】nuxtでbootstrapvueのレイアウト

b-containerの使い方

まず、コンテンツ部分はb-containerで囲みます。

<b-container fluid="sm">
狭い
</b-container>
<b-container fluid="md">
やや狭い
</b-container>
<b-container fluid="lg">
やや広い
</b-container>
<b-container fluid="xl">
広い
</b-container>
  • Small (sm) 576px
  • Medium (md) 768px
  • Large (lg) 992px
  • Extra large (xl) 1200px

b-containerはxlが好みです。

b-container fluidのpaddingが邪魔

b-containerは左右に15pxずつpaddingが入っています。たとえば、アイキャッチ画像のようなものを目一杯広げたいときに邪魔になることがあります。

width: calcの中央あわせ

通常はpaddingが入っていて問題ないため、no paddingするのではなく、画像を広げたい場所だけ次のコードで対応を行いました。右にはみでるため、marginで綺麗に中央にもってきました。

.photo-img {
  margin: 0 -15px;
  width: calc(100% + 30px);
}

b-colのpaddingが邪魔

b-colもデフォルトでpaddingが入っていますね。写真1枚のとき、タイトルと整列しなくて邪魔になることがあります。

<b-col cols="12" class="px-0"></b-col>

b-rowとb-colのレイアウト崩れ

bootstrapは合計12にしておけばレイアウトは崩れにくいのですが、なんかb-rowとb-colの間にdivを入れると、b-colが効いていないようですね。前後に入れましょう。

<b-row class="my-2 py-2">
  <div>
    <b-col cols="12">
    </b-col>
  </div>
</b-row>

mx-0の罠

.row {
  display: flex;
  flex-wrap: wrap;
  margin-right: -15px;
  margin-left: -15px;
}

mx-0にすると、デフォルトのマージン-15pxがなくなり、たとえば、背景色を塗りつぶした場合、端から端まで埋まらないことが起こります。

b-rowは使わずdivなどで背景色を隅から隅まで塗りたい場合は次のような対応が必要です。

<div class="bg" style="margin: 0 -15px;"></div>

mx-5以上にする

このあたりが中途半端に感じてしまうのですが、、bootstrapはなぜか5以上できないっぽいです。。結局、styleで調整しました。mx-5が3remみたいです。

<b-row class="py-2" style="margin: 0 5rem 0 5rem;"><b-row>

レイアウトの横並び

<b-row class="my-2 py-2 line">
<b-col cols="2">
</b-col>
<b-col cols="10">
</b-col>
</b-row>
  • my-2 marginのy軸(上下)の略
  • py-2 paddingのy軸(上下)の略
  • px-2 paddingのx軸(左右)の略
  • サイズは0、1(0.25rem)、2(0.5rem)、3(1rem)、4(1.5rem)、5(3rem)、auto
  • bootstrap4でpxからremに変わったようです。remはレスポンシブデザインで便利です。

レイアウトは線を入れることが多いでしょう。

.line {
  border-bottom: 1px solid #f2f2f2;
}

bootstrap-vueのグリットシステムをレスポンティブデザインに対応する

普通の書き方ではレスポンシブになりません。

<b-col cols="6"></b-col>
<b-col cols="6"></b-col>

次の書き方をするとブラウザの幅を変えるとレスポンティブデザインになります。

<b-col md="10"></b-col>
<b-col md="2"></b-col>
  • Extra small (xs) <576px
  • Small (sm) ≥576px
  • Medium (md) ≥768px 1カラム62.5px(左右15pxを含む
  • Large (lg) ≥992px 1カラム80.8…px(左右15pxを含む)
  • Extra large (xl) ≥1200px 1カラム97.5px(左右15pxを含む)

mdが好みですが、mdはsmなどに変えられますのでお好みでどうぞ。ただ、bootstrapのグリットシステムは合計12にします。12以上は2行になります。

xsは仕様変更があり効かないです。colsと書きます。

モバイル(スマホ)とタブレットとPCを分ける

モバイル(スマホ)2列(cols)、タブレット3列(sm)、PC6列(md)に分ける場合はこうなります。2*6は12掛け算するとどれも12になります。

<b-col md="2" sm="4" cols="6">
</b-col>

ツールを使うとわかりやすいです。colでスマホを2列、タブレット3列、PC6列にしてみましょう。

Shoelace - Visual Bootstrap 3 Grid Builder
The only visual Bootstrap 3 grid builder featuring full responsive media query views and fully functional preview.

iPad Pro11の横幅が1194px。そこで1200px以上を6列にする場合、次のようになります。

<b-col lg="2" sm="4" cols="6">
</b-col>

xsは仕様変更があり効かないです。colsと書きます。

表示要素の横並びと中央あわせ

表示要素の中央あわせはどうするか。

(追記)もっと簡単な方法がありました。親要素以下、中央になります。

<b-row class="text-center"></b-row>

CSSを確認すると以下のようになっています。

.text-center {
    text-align: center !important;
}

旧記事。

<b-col cols="12" align-content="center">
</b-col>

ただ、これじゃうまくいかない場合があります。

中央合わせと横並びをあわせて行いたい場合は、親要素にflexが手っ取り早いです。

.wrap {
  display: flex;
  justify-content: center;
}

他にも子要素にdisplay: inline-block、親要素にtext-align:centerなんていう方法もありますが、詳細は割愛しますが、for文など入りコードが複雑になった場合、flexの方があっさりと解決できると思ったことがあります。

bootstrapvueでサイドバーをわける

nuxtのレイアウト機能、具体的にはlayouts/default.vueですが、default.vue内でb-colを使うと、簡単にサイドバーをわけることができます。

bootstrapvueではレイアウトの分岐はメディアクエリを使う!?

公式サイトに記載がないっぽいようですが、どうやらメディアクエリを使って対応している人が多いようです。

スマホやモバイルのみ余白(margin/padding)が邪魔

結構、このケースありました。

一般的かどうかわかりませんけど、m-mobileというclassを作成して書き換えました。直接、rowを書き換えると影響が大きそうだったので。

@media (max-width: 480px) {
  .m-mobile {
    margin: 0 !important;
  }
}
スポンサーリンク

bootstrapvueのinput要素など

ラジオボタン(radio button)のクリックイベント(click event)

clickはボタンなのでinputはchangeを使いましょう。v-on:change=@change省略記法です。

<b-form-radio v-on:click="event">動かない</b-form-radio>
<b-form-radio v-on:change="event">動く</b-form-radio>
<b-form-radio @change="event">動く</b-form-radio>

ラジオボタン(radio button)でcssサイズ変更が効かない罠

beforeでボーダーを使ってボタンを表示し、通常のボタンはopacity: 0%;していますね。通常のやり方でラジオボタンのサイズなどを変えようとしても効きませんでした。

いろいろなカスタマイズする方法はありますが、元に戻す方法は以下のとおりです。

.custom-control-label::before {
  border: none;
}

.custom-control-input {
  width: 5vw;
  height: 5vw;
  opacity: 100%;
}

こちらチェック時のコードも修正が必要ですね。

もしくはborderの方をそのままいかすかですかね。今回は後者の方がコストが安そうだったので選択しました。

.custom-control-label::before {
  position: static;
  width: 5vw;
  height: 5vw;
  /* border: none; */
}

bootstrapって余計なことしていることが多く、こういうこと調べているとbootstrap使わなくてもいいんじゃ…と思ってしまうのですよね。。

画像をアップロードできるb-form-fileよりVeeValidate

画像をアップロードできるb-form-fileという機能があります。

        <b-form-file
          id="img"
          v-model="img"
          placeholder=""
          drop-placeholder=""
          accept=".jpg, .png"
          required
          plain
        ></b-form-file>

b-form-fileでも画像ファイルの種類ぐらいは制御できるのですが、画像サイズや縦横のピクセル数まで制御できるVeeValidateに魅力を感じ使っていません。

input要素の横並び

b-input-groupなら同列になることがわかりました。

Display two fields side by side in a Bootstrap Form - Stack Overflow

結構、他でも使えるかも。

Input group
Input group(インプットグループ)では,テキスト入力, カスタム選択, カスタムファイル入力の両側にテキスト, ボタン, またはボタングループを追加して, フォームコントロールを拡張可能です。

b-input-groupは基本input要素に使うもののようです。たとえばセレクトボックスの誕生日の入力とかチェックボックスの羅列です。

b-input-groupのレスポンシブ対応

b-colとかは使いません。不都合が構造になることが多くて・・・。

公式にはresponsiveのことが書かれていませんでした。結局、一般的なCSSの対応をしました。

@media (max-width: 768px) {
  .input-group {
    display: block;
  }
}

たとえば、横並びのチェックボックスが縦になります。

参考。

how to make input-group responsive (search and dropdown) - Stack Overflow

ただ、input-groupの場合、他に影響がでることが多いため実際は別クラスの対応が多いですね。

@media (max-width: 768px) {
  .responsive-input-group {
    display: block;
  }
}

b-input-groupの横と縦の中央あわせ

b-input-groupはソースコードをみるとflexになっています。

中央あわせする場合は次のとおりです。

<b-input-group style="justify-content: center;" >
</b-input-group>

justify-content: space-between;は両端のアイテムを余白を空けずに配置し、他の要素は均等に配置します。単純に均等の場合はjustify-content: space-around;ですね。

<b-input-group style="justify-content: space-between;" >
</b-input-group>

高さはalign-items: center;。上揃えの場合はalign-items: start;、下揃えの場合はalign-items: end;などで注意しましょう。うっかりtopと書いたことがある。

フォームの横並び

<b-form inline></b-form>

スマホでinlineが効かず困ったことがあります。768px必要だと。bootstrapの仕様ですが、bootstrapvueもおそらく一緒でしょう。これは使えません。。

Add .form-inline to your form (which doesn’t have to be a

) for left-aligned and inline-block controls. This only applies to forms within viewports that are at least 768px wide.

CSS · Bootstrap
Bootstrap, a sleek, intuitive, and powerful mobile first front-end framework for faster and easier web development.

テキストとセレクトボックスの高さを揃える

<b-col cols="3" style="display: flex; align-items: center;">
  {{ animal.key }}
<b-col cols="9">
  <b-form-select
    v-model="model"
    :options="options"
  ></b-form-select>
</b-col>

テキストが一行ならline-height: 2.2;もありです。

タブの実装

Tabs | Components | BootstrapVue
Create a widget of tabbable panes of local content. The tabs component is built upon navs and cards internally, and provides full keyboard navigation control of...
<template>
  <div>
    <b-container fluid="xl">
      <b-card no-body>
        <p>タブを選んでください。</p>
        <b-tabs card>
          <b-tab title="タブ1" active><p>タブ1</p></b-tab>
          <b-tab title="タブ2"><p>タブ2</p></b-tab>
          <b-tab title="タブ3"><p>タブ3</p></b-tab>
        </b-tabs>
      </b-card>
    </b-container>
  </div>
</template>

cardは使わなくてもいいですが、使った方がレイアウトしやすいかもしれません。

タブの幅widthをフル幅にする

fillをつけるだけです。ui的に押しやすいかもです。

<b-tabs fill></b-tabs>

b-cardの背景とborderをシンプルにnone

よく邪魔になることがある。この書き方がシンプル。

<b-card class="bg-transparent border-0"></b-card>

card-bodyのpaddingが邪魔

@media (max-width: 480px) {
  .card-body {
    padding: 0 !important;
  }
}

card-bodyというクラスにpaddingが入っていました。モバイルなどで邪魔になることがあるのですよね…。

チェックボックスの判定

v-modelで簡単にできます。

<div v-for="task in tasks">
  <b-form-checkbox v-model="task.checked"> </b-form-checkbox>
</div>

firebaseからデータを取得し、checkedというプロパティがない場合も勝手に作ってくれます。

トグルボタンは?

トグルボタンはいろいろデザインの工夫もできます。

bootstrapvueもちょっとありましたが、個人的には普通にCSSのコードで書いた方がよいという結論です。詳しくはこちらの記事をみてください。

モダールウィンドウ

bootstrapvueにはモーダルウィンドウの機能はあります。

ただ、柔軟性に欠け構造的に問題がでそうだったので、Udemyで紹介されていたモーダルウィンドウの方法を採用しました。

【Vue.js2&Vue.js3対応】基礎から【Vuetify】を使った応用まで! 超初心者から最短距離でレベルアップ

という講座です。詳しくはこちらの記事をみてください。

Modal | Components | BootstrapVue
Modals are streamlined, but flexible dialog prompts powered by JavaScript and CSS. They support a number of use cases from user notification to completely custo...

画像の横並び

Image | Components | BootstrapVue
Create responsive images, optionally adding lightweight styles to them — all via props. Support for rounded images, thumbnail styling, alignment, and even the a...

アコーディオン

accordionはbootstrapの機能を使わせてもらいました。最小レベルのコードは以下のような感じ。

<b-button v-b-toggle.accordion-1 block>アコーディオン1</b-button>
<b-collapse id="accordion-1" visible>
 中身
</b-collapse>

accordionはトグルの一種でidでひっかけてボタンを押しているだけです。

blockはブロック要素にする。visibleはデフォルト時に開いた状態にします。

公式のリファレンスはこちら。

Collapse | Components | BootstrapVue
Easily toggle content visibility on your pages. Includes support for making accordions.

v-forでまわす場合は次のようになります。

<div v-for="(l, index) in list" :key="index">
  <b-button v-b-toggle="'accordion-' + index" block>
    {{ l.name }}
  </b-button>
  <b-collapse :id="'accordion-' + index">中身</b-collapse>
</div>

レスポンシブテーブル

スマホになると左右2列の縦並びになる方式を採用しました。htmlは簡単です。

<b-table stacked="md" striped hover :items="items"></b-table>
thead-class="bg-primary text-white"

htmlに上記のコードをつかえばヘッド部分に色をつけられますが、全体として思った通りにならずfieldsで色をつけています。

scriptはこうです。

export default {
  data() {
    return {
      items: [
        { 項目: 'A', 名前: 'Aさん', 年齢: '29' },
        { 項目: 'B', 名前: 'Bくん', 年齢: '31' },
      ],
      fields: [
        { key: '項目', class: 'bTableStyle' },
        { key: '名前', variant: 'danger' },
        { key: '年齢', thClass: 'bg-white text-dark' }
      ]
    }
  }
}

ただし、variantは列を塗れますが、任意の色がつけられません。thClassもあまり融通がききません。

左側と最初の一行目に色をつけたい場合、次のような感じがいいかもしれません。

{
  key: '項目',
  tdClass: 'bTableLeftCellStyle',
  thStyle: 'background-color: #f2f2f2;'
},
{ key: '名前', thStyle: 'background-color: #f2f2f2;' },
{ key: '年齢', thStyle: 'background-color: #f2f2f2;' }

色を自分で選びたい場合は、thClassよりthStyleがよいですかね。ちなみに、tdStyleはないようです。classとtdClassはここでは効果がかわりません。

classはcssの適応が必要です。

::v-deep .table .bTableLeftCellStyle {
  background-color: #323232;
}

CSSはtext-alignを左寄せと右寄せで配置したい場合、ちょっとややこしかったですけど、結論としてはこうです。

@media (max-width: 767.98px) {
  ::v-deep .table.b-table.b-table-stacked-md > tbody > tr > [data-label]::before {
    text-align: left;
  }

  ::v-deep .table.b-table.b-table-stacked-md > tbody > tr > [data-label] > div {
    text-align: right;
  }
}

簡単に解説すると、左側はdata-labelでbeforeの要素を使っているため、beforeが最後につきます。

右側も下記のようなコードではうまくいきません。

.table.b-table.b-table-stacked-md > tbody > tr > td > div {
  text-align: right;
}
.table > tbody > tr > td > div {
  text-align: right;
}

どちらも::v-deepは必須です。::v-deepはscopedのままdeep selectors。スタイルをオーバライドできるようです。

ただ、stylelintのルールにひっかるため回避のコードが必要です。

module.exports = {
  rules: {
    'selector-pseudo-element-no-unknown': [
      true,
      {
        ignorePseudoElements: ['v-deep']
      }
    ]
  }
};

bootstrapってなんか回りくどいですね。。テーブルは楽になっているかわかりません。。

プロフィール

Avatarという機能があるんですね。いつか使ってみたいです。

Avatar | Components | BootstrapVue
Avatars are typically used to display a user profile as a picture, an icon, or short text.
スポンサーリンク

bootstrap-vueの不具合・エラー

CSSが全般的に崩れる

ある日、突然、すべてのCSSが崩れる状態になったことがあった。直近の作業を見なしていくとよくみるとbootstrapに絡んだコードばかりだった。

bootstrapのバージョンを5にしたのが原因だった。(注)bootstrapvueではなく、bootstrap。

ひとまず、4.6にダウングレードしたら元に戻りました。

スポンサーリンク

bootstrap-vueの使い所はどこまで

bootstrapvueというか、元のbootstrapが中途半端な気がします。

とくに、デザインとして見た場合、たとえば、角丸30%が好きなのですが、できません。決まったフォーマットしか選べません。

またグラデーションもないっぽいです、結局、ボタンはcssで書いた方が早いですね。CSSで書けばあっさりとかけるのに、返って余計な時間を使ってしまいました。。

チェックボックスもデザインにこる場合は、普通に書いた方がいい気がしますね。

仮のレイアウトを作るのならいいかもしれませんが、デザインをしっかりとしたい人には中途半端かもしれません。bootstrapは使い所を絞ってグリットのレイアウト、チェックボックスやラジオボタンに使うぐらいですかね。何でもbootstrapでできると思わず、絞ってコンパクトに使うといい感じじゃないかもという気がします。

コメント

タイトルとURLをコピーしました