現在幅: {{ width }}px [ Extra Small Small Medium Large Extra Large ]

Vuetify Grid System

<v-container> <v-row> <v-col> の関係

2020/11/17 作成
概要

Vuetify は Grid System を使用して画面をレイアウトします。 使用する主なタグは <v-container> <v-row> <v-col> です。このレイアウト方法を活用すると、殆どの場面で自在にデザインできるようになります。 Vuetify の Grid System は全く別のJavaScriptフレームワークである BootstrapGrid System から影響を受けています。 考え方が良く似ているため、Bootstrapを使用する際にも適用できます。 大きな特徴は画面横幅を 12分割してレイアウトする方法を用いる点です。 画面横幅を 12等分し、その幅のうちどのくらいの割合を使用するかを設定します。 このページでは、この方法について基本的な部分を説明しています。 より詳細な仕様については、Vuetify.js の公式ドキュメント Grid System を参照してください。

このページも Vuetify の Grid System を活用して記述しています。 また、ライブラリはCDNを使用しており、ページは単一ファイルで構成されているため、 このページを右クリックしソースコードを表示後、 全選択・コピーして手元のコンピュータでxxx.htmlファイルを作成し貼り付けるだけで、ブラウザに表示できます。 ソースコードをお気に入りのエディタで表示して、ブラウザでの見え方を確認しながら改変等して学習にご活用ください。

Grid System 「v-container ▶ v-row ▶ v-col」と12等分の概念
  • v-containerは、全体を覆うタグです。
  • v-rowは、行です。
  • v-colは、列です。
v-colの中には、テキストやHTMLのタグが入ります。 v-colが複数(または 1つ)記述されたものを、v-rowで囲みます。 v-rowが複数(または 1つ)記述されたものを、v-containerで囲みます。 以下のようになります。

v-container ▶ v-row ▶ v-col のコードサンプル
<v-container fluid>
  <v-row>
    <v-col cols="6">A1</v-col>
    <v-col cols="6">A2</v-col>
  </v-row>
  <v-row>
    <v-col cols="4">B1</v-col>
    <v-col cols="4">B2</v-col>
    <v-col cols="4">B3</v-col>
  </v-row>
</v-container>

v-containerにある属性、fluidは画面いっぱいに表示する設定です。 このページでは、わかりやすさのためfluidをつけています。 詳しくはこのページの最下部にある 補足: v-container のfluid属性の有無による違い を参照してください。

v-container v-row v-col
A1
v-col
A2
v-row v-col
B1
v-col
B2
v-col
B3
図: タグの関係を構造化したイメージ

v-rowv-colの入れ子関係が逆になることはありません。 v-rowの中にv-colを入れる関係を保ったままレイアウトします。 v-rowv-colは、ネストする(入れ子にする)ことができます。 つまり、v-rowの中にv-colをいれ、そのv-colのなかに v-rowを入れることができます。そしてv-colを入れます。 その際、外側のv-colの中に、v-containerの記述は基本的に不要です。 v-containerは、v-rowの外側に(直接の親要素でなくとも)1つあれば必要十分です。

v-container v-row v-col v-row v-col v-row v-col v-col v-col v-col 図: ネストのイメージ (ページ全体を2カラムに分けたい場合)

レイアウトを構成する際に必要となるのが横幅に対して12等分する考え方です。 12が使用されている理由は約数(1,2,3,4,6,12)が多く都合が良いからです。 この12のうち、要素にどのくらいの割合を適用するかを決めることで画面を構成します。 設定は v-colに指定します。

例1 1行に12列分の幅が入ることを確認する

v-rowの中に<v-col cols="1">数字</v-col>を 14個入れます。

見やすくするために、v-colの背景に をつけています。
幅が 1 の要素が 14個あるため 1 × 12 = 12で 12個目までは 1行で表示されます。 13個目の要素から、12個を超えるため次の行に表示されます。 14個目は13個目の続きに表示されます。 これにより、12等分に分割されていることがわかります。

mdi-arrow-down実装例
{{ index+1 }} 例1のコードサンプル
<v-container fluid>
  <v-row>
    <v-col cols="1" class="blue">1</v-col>
    <v-col cols="1" class="pink">2</v-col>
    <v-col cols="1" class="blue">3</v-col>
    <v-col cols="1" class="pink">4</v-col>
    <v-col cols="1" class="blue">5</v-col>
    <v-col cols="1" class="pink">...</v-col>
  </v-row>
</v-container>

例2 v-rowで区切ると強制的に次の行になる

v-rowの中に<v-col cols="1">数字</v-col>を1個入れたものを2つ記述した場合

col幅が 1 の要素が 1個のため、1行には残り11幅分の要素を入れることができますが、 v-row で次の行を指定しているため B は次の行に表示されます。

mdi-arrow-down実装例
A B 例2のコードサンプル
<v-container fluid>
  <v-row>
    <v-col cols="1" class="blue">A</v-col>
  </v-row>
  <v-row>
    <v-col cols="1" class="pink">B</v-col>
  </v-row>
</v-container>

例3 v-colcolsを変える

v-rowの中にv-colを入れ、colsを1つずつ大きくします。 v-colの中の数字は幅です。 v-rowは1つしかありませんが、col幅が 12を超えているため、複数行に渡って表示されています。
ポイント
  • 1行目は、幅 1 + 2 + 3 + 4 = 10 で12以下のため 1行で表示されます。5 は 10 + 5 = 15 > 12 のため次の行に表示されます。
  • 2行目は、幅 5 + 6 = 11 で12以下のため 1行で表示されます。7 は 11 + 7 = 18 > 12 のため次の行に表示されます。
  • 3行目以降の行は、2つの要素を合わせると12を超えるため 1要素ずつ表示されます。
mdi-arrow-down実装例
1 2 3 4 5 6 7 8 9 10 11 12 例3のコードサンプル
<v-container fluid>
  <v-row>
    <v-col cols="1" class="red">1</v-col>
    <v-col cols="2" class="pink">2</v-col>
    <v-col cols="3" class="purple">3</v-col>
    <v-col cols="4" class="deep-purple">4</v-col>
    <v-col cols="5" class="indigo">5</v-col>
    <v-col cols="6" class="blue">6</v-col>
    <v-col cols="7" class="light-blue">7</v-col>
    <v-col cols="8" class="cyan">8</v-col>
    <v-col cols="9" class="teal">9</v-col>
    <v-col cols="10" class="green">10</v-col>
    <v-col cols="11" class="light-green">11</v-col>
    <v-col cols="12" class="lime">12</v-col>
  </v-row>
</v-container>
ブレイクポイント レスポンシブデザイン、モバイルフレンドリーなデザインを簡単に構築する

Vuetifyには、柔軟なデザインを構築するために、4つのブレイクポイント(5つの状態)があります。 ブレイクポイントは一般的なデバイスの画面横幅に対して決められています。 ブレイクポイント別にそれぞれ xs、sm、md、lg、xl という状態の名前がついています。 このページも表示しているブラウザ画面の大きさによって、レイアウトが変わります。 現在の画面の横幅(px)と状態は上のバーに表示しています。 画面サイズを変えて確認してみてください。詳しいブレイクポイントに関する内容は以下の通りです。

表 画面横幅のブレイクポイント

スクロールバーが表示される場合はその領域を含みます。
Vuetifyドキュメントを参考に一部修正。 オリジナルは Display Breakpoints を参照。

レスポンシブデザイン

画面の横幅に応じて表示のデザインを変更し、画面サイズの異なるディスプレイで表示しても、 常に適切な文字の大きさで表示することをレスポンシブデザインと言います。 また、スマートフォンで表示した際に適切な文字やボタンの大きさで表示されることを、 モバイルフレンドリーなデザインと言います。

インターネットでページを表示する際に、ユーザーエージェントがサーバーに渡されます。 このユーザーエージェントには、どんなデバイスを使っているかを識別することができます。 この仕組みを利用して、スマートフォン用、PC用に専用にレイアウトしたHTMLファイルを作成し レスポンスする方法があります。これはモバイルフレンドリーなデザインを提供できますが、 レスポンシブデザインではないと言えます。 レスポンシブデザインは、一つのファイルで画面の横幅が異なっても適切にレイアウトされます。 そのため一度ページを表示したあとでも、ブラウザの横幅を変えると、自動的にレイアウトが組み変わります。

レスポンシブデザインを構築するのは、スタイルシート(CSS)の知識が必要です。 しかし、Vuetifyはブレイクポイントを使用することで、スタイルシートの書き方を知らなくても、 簡単かつ確実にレスポンシブデザインができるように設計されています。

レスポンシブデザインの最初の設定

デフォルトでは、スマートフォンで表示しても小さく表示されてしまいます。 これは、スマートフォンのブラウザに仮想的なスクリーンサイズがあるためです。 実際の画面サイズを適用する(厳密には調整された適切な値)ための設定が、ビューポートの設定です。 レスポンシブデザインにするためには、headタグ内に以下を追加してください。

headタグ内にビューポートを設定するためのmetaタグを記述する
<head>
  ...
  <meta name="viewport" content="width=device-width, initial-scale=1">
  ...
</head>

レスポンシブデザインレイアウトの例

Vuetifyでは、まずスマートフォンのレイアウトから考えます。 PCを使って、大きな画面で開発を始めることが多いため、 多くの人は、まずPC画面でのレイアウトを考えますが、 PC画面を設計後に、スマートフォンレイアウトを考えるのは 少し難しいです。モバイルデザインファーストで考えましょう。 ただし、モバイルデザインは思いのほか画面の幅が小さく、 複雑なレイアウトはできません。 基本的には、1カラムのレイアウトにすることが多いです。

1カラムレイアウト
2カラムレイアウト
3カラムレイアウト
図 カラムの例

スマートフォン版のレイアウトを決めたら、そこから徐々に大きな画面を考え、 ページのコンテンツに応じてレイアウトを変更していきます。 この時、コンテンツの順番を意識してください。 おそらくスマートフォンレイアウトで構成したものを上から順番にHTMLに記述していくでしょう。 つまり、PC版で表示する際には、スマートフォンレイアウトから派生した形で作る必要があります。 慣れるまでは、PCレイアウトはあまり複雑でない構成にしましょう。

実は複雑でない構成というものを初学者に伝えるのは少し難しいです。 例えば、下図のレイアウトは比較的簡単な構成です。直感的にHTMLを書くことができます。 しかし、下図のスマートフォンレイアウトからPCレイアウトで「メニューと広告を右側に配置するレイアウト」は難しいです。 また、PCレイアウトの構成のままに スマートフォンレイアウトの「広告と内容を入れ替える」のも難しいです。 いくつかの方法がありますが、orderを使用する方法があります。 このページでは、Grid Systemの基本的な説明のため、orderの説明はしていません。 詳しくはスタイルシートの Flexbox に関する内容を学習し、Vuetifyの Flex Order を参照してください。 メニュー 広告 内容
スマートフォン
mdi-arrow-right-bold
mdi-arrow-down-bold
メニュー 広告 内容
PC
図 スマートフォン版とPC版のレイアウト

例4 画面サイズによって幅を変える

基本的なデザインの例です。xs ▶ sm ▶ md ▶ lg ▶ xl のように、 小さい画面から大きい画面の順に考えます。

A cols="12" B cols="12" C cols="12" D cols="12"
スマートフォン
md
ブレイクポイント
ブレイクポイント
mdi-arrow-right-bold
mdi-arrow-down-bold
A
md="6"
B
md="6"
C
md="6"
D
md="6"
タブレット
lg
ブレイクポイント
ブレイクポイント
mdi-arrow-right-bold
mdi-arrow-down-bold
A
lg="3"
B
lg="3"
C
lg="3"
D
lg="3"
PC
図 ブレイクポイントで幅を変える

スマートフォンでは1カラム、 mdのブレイクポイントで2カラム、 lgのブレイクポイントで4カラム となるように、v-col に指定します。 この通りの挙動にするためには、以下の計算となります。

  • スマートフォン表示: 各v-colの幅を 12 にする。12 のため、 1で1行が埋まります。
  • タブレット表示: 各v-colの幅を 6 にする。6 + 6 = 12 のため、 2で1行が埋まります。
  • PC表示: 各v-colの幅を 3 にする。3 + 3 + 3 + 3 = 12 のため、 4で1行が埋まります。

指定の仕方は、ブレイクポイントの指定コードを属性として使用します。 xsがデフォルトのため、xsは cols に指定します。

<v-col cols="12" md="6" lg="3">
mdi-arrow-down実装例 上のバーの状態も見比べながら、ブラウザの横幅を変えてみてください。
A B C D 例4のコードサンプル
<v-container fluid>
  <v-row>
    <v-col cols="12" md="6" lg="3" class="blue">A</v-col>
    <v-col cols="12" md="6" lg="3" class="pink">B</v-col>
    <v-col cols="12" md="6" lg="3" class="green">C</v-col>
    <v-col cols="12" md="6" lg="3" class="yellow">D</v-col>
  </v-row>
</v-container>

例5 カードを追加する

v-colの中にv-cardを追加すると、カードデザインができます。 サンプルコードと見た目を見比べて、タグの使い方を把握しましょう。 なおv-から始まるタグは、HTMLの標準にあるタグではありません。 Vuetifyが用意したタグです。Vuetifyの公式ドキュメントを見てサンプルコードを動かして見ましょう。 v-cardのドキュメントは Components/Card から確認できます。 サンプル画面の右上にある mdi-code-tags のアイコンを押すと、そのプログラムを見ることができます。

mdi-arrow-down実装例 上のバーの状態も見比べながら、ブラウザの横幅を変えてみてください。
Card 1 すべてのv-colcols="12" md="6" lg="3"を適用。 Card 2
  • xs と sm は 12、つまり 1 カラムで表示される。
  • md は 6、つまり 2 カラムで表示される。
  • lg と xl は 3 、つまり 4 カラムで表示される。
Card 3
中にv-cardv-card-textを入れると、 カードデザインができます。v-colで指定したcol幅に 横幅を任せるのが、うまくデザインするコツです。
サンプル
<v-col cols="12" md="6" lg="3">
  <v-card height="100%">
    <v-card-title>Title Text</v-card-title>
    <v-card-text>Contents Text</v-card-text>
  </v-card>
</v-col>
Card 4 v-cardheight="100"をつけると v-colの最大の高さに合わせてくれます。
例5のコードサンプル
<v-container fluid>
  <v-row>
    <v-col cols="12" md="6" lg="3" class="grey">
      <v-card height="100%">
        <v-card-title>Card 1</v-card-title>
        <v-card-text>Text</v-card-text>
      </v-card>
    </v-col>
    <v-col cols="12" md="6" lg="3">
      <v-card height="100%">
        <v-card-title>Card 2</v-card-title>
        <v-card-text>Text</v-card-text>
      </v-card>
    </v-col>
    <v-col cols="12" md="6" lg="3">
      <v-card height="100%">
        <v-card-title>Card 3</v-card-title>
        <v-card-text>Text</v-card-text>
      </v-card>
    </v-col>
    <v-col cols="12" md="6" lg="3">
      <v-card height="100%">
        <v-card-title>Card 4</v-card-title>
        <v-card-text>Text</v-card-text>
      </v-card>
    </v-col>
  </v-row>
</v-container>

補足: v-container のfluid属性の有無による違い

  • fluid属性なしの場合、幅 md以上で、段階的に幅が大きくなります。
  • fluid属性ありの場合、幅いっぱいに表示され続けます。

fluid属性なしとありの使い分け

fluid属性がない場合は、段階的に幅が大きくなるためレイアウトチェックのコストが減ります。
fluid属性がある場合は、実質的に無限段階のパターン(画面幅)でチェックする必要があります。 また、横幅が大きくなると、文章を読む際の目の横移動の量が増えるため、文章が読みづらくなることがあります。

ページの内容が、主に文章で構成される場合は、fluidをつけないほうがレイアウトしやすく文章も読みやすくなります。
ポータルサイトなどで多くの情報を一度に見せたい場合や、グラフ・表などを多く使用する場合は、 fluid属性をつけることで、無駄な余白が出ないようになります。 その場合、なるべく目の横移動の量が多くなりすぎないように、レイアウトを調整することを意識しましょう。
なお、どのような状況でも、目の横移動量に関して注意しておくと、見やすいページになります。 場合によっては、style="max-width:1000px;" 等をつけて、最大幅を指定することもあります。

◀もっと横幅を広げて!▶
v-container
fluid なし
mdi-arrow-collapse-left {{ containerNoFluidWidth }}px mdi-arrow-collapse-right
v-container
fluid あり
mdi-arrow-collapse-left {{ containerFluidWidth }}px mdi-arrow-collapse-right