領域の確保(Card): v-card
v-card
は Vuetify3 を使って Web ページのデザインをするときに使う、最も基本的な要素の一つです。カードは v-sheet
と同様に、web ページの中に、一定の高さと幅を持った領域を確保する目的に使えます。
v-sheet
との最大の違いは、v-card
はお仕着せのスタイルが用意されている点です。自由なデザインがしたいときは v-sheet
を使用し、お仕着せのデザインで(短時間で)デザインしたいときは v-card
を使うと良いです。
基本
下記の画像は、v-card
コンポーネントの基本構造を示しています(公式サイトの画像をそのまま引用したものです)。
- 1: カード本体を示しています。
- 2: カードのタイトルです。フォントの大きさや配置位置は自動的に決まります。
- 3: カードのサブタイトルです。タイトルの下に自動的に配置されます。
- 4: カード内部に配置するテキストです。
- 5: ユーザが操作可能なボタンなどのコンポーネントです。
上記の要素の指定は、v-card
の prop としてして指定する方法と、v-card-title
, v-card-text
などの子要素として指定する方法、v-slot
で指定する方法の三通りがあります。いずれの場合でも、レンダリング(表示)結果はまったく同じになります。
下記コードは、子要素で指定した例です。v-card-
で始まる名前の子要素は、基本的に配置順序を入れ替えてもデザインに影響しません。タイトルは常にカードの最上部に配置され、v-card-actions
で指定したコンポーネントは常に最下部に配置されます。
<template>
<v-container>
<v-card class="w-50" elevation="4">
<v-card-title>平家物語</v-card-title>
<v-card-subtitle>作者不詳</v-card-subtitle>
<v-card-text>
祇園精舎の鐘の声、諸行無常の響きあり。
娑羅双樹の花の色、盛者必衰の理をあらわす。
おごれる人も久しからず、唯、春の夜の夢のごとし。
猛きものもついにはほろびぬ、
偏に風の前の塵に同じ。
</v-card-text>
<v-card-actions>
<v-btn>源氏を選択</v-btn>
<v-btn>平家を選択</v-btn>
</v-card-actions>
</v-card>
</v-container>
</template>
下記コードは、prop で指定した例です。prop で指定するコンテキスト(文字列)が短い場合には、こちらのほうがシンプルに記述できます。なお v-card-actions
は prop では指定できないため、子要素で指定しています。
<template>
<v-container>
<v-card class="w-50" elevation="4"
title="平家物語"
subtitle="作者不詳"
text="祇園精舎の鐘の声、諸行無常の響きあり。
娑羅双樹の花の色、盛者必衰の理をあらわす。
おごれる人も久しからず、唯、春の夜の夢のごとし。
猛きものもついにはほろびぬ、
偏に風の前の塵に同じ。"
>
<v-card-actions>
<v-btn>源氏を選択</v-btn>
<v-btn>平家を選択</v-btn>
</v-card-actions>
</v-card>
</v-container>
</template>
下記コードは v-slot
を使用した例です。カード内部に複数のコンポーネントを配置する場合や、細かなデザインをしたい場合はこの方法が適しています。
<template>
<v-container>
<v-card class="w-50" elevation="4">
<template v-slot:title>平家物語</template>
<template v-slot:subtitle>作者不詳</template>
<template v-slot:text>
祇園精舎の鐘の声、諸行無常の響きあり。
娑羅双樹の花の色、盛者必衰の理をあらわす。
おごれる人も久しからず、唯、春の夜の夢のごとし。
猛きものもついにはほろびぬ、
偏に風の前の塵に同じ。
</template>
<template v-slot:actions>
<v-btn>源氏を選択</v-btn>
<v-btn>平家を選択</v-btn>
</template>
</v-card>
</v-container>
</template>
外観の変更 (Variant)
variant
prop を指定すると、大まかなデザイン(色、枠、影)の変更ができます。variant
名としては elevated
, flat
, tonal
, outlined
, text
, plain
の6種類を指定することができます。
-
evelated
: 設定色で背景が塗りつぶされ、影が付きます。影の大きさはelevation
で指定できます。 -
flat
: 設定色で背景が塗りつぶされますが、影や枠はつきません。 -
tonal
: 設定色の府透明度を下げた色で背景が塗りつぶされます。影や枠はつきません。 -
outlined
: 背景は塗りつぶされません。代わりに設定色で枠がつきます。 -
text
: 背景は塗りつぶされません。枠も影もつきません。 -
plain
: ほぼtext
と同じですが、マウスカーソルが上にないときは、色が全体的に薄く表示されます。
上の図では、わかりやすくするために v-btn
にも同じ variant
を指定してします。
<template>
<v-container>
<v-row>
<v-col cols="4" v-for="val in variants">
<v-card :variant="val">
<v-card-title>平家物語</v-card-title>
<v-card-subtitle>{{val}}</v-card-subtitle>
<v-card-text>
祇園精舎の鐘の声、諸行無常の響きあり。
娑羅双樹の花の色、盛者必衰の理をあらわす。
おごれる人も久しからず、唯、春の夜の夢のごとし。
猛きものもついにはほろびぬ、
偏に風の前の塵に同じ。
</v-card-text>
<v-card-actions>
<v-btn :variant="val">源氏を選択</v-btn>
<v-btn :variant="val">平家を選択</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
data: () => {
return {
variants: ['elevated','flat','tonal','outlined','text','plain']
}
}
}
</script>
上の図は color="tonal-darken-4"
として色の設定の反映のされ方の違いを分かりやすくしたものです。色を指定すると flat
と text
の違いがよくわかります。
仕切り線
水平方向の仕切り線には v-divider
を使います。仕切り線は、v-card-text
の上下の位置にのみ入れることができます(通常は)。v-divider
で仕切り線を入れるときは、v-card-text
または v-slot:text
でテキスト部分を記述する必要があります。v-divider
の配置される位置は、v-divider
が v-card-text
より前に記述されているか、後ろに記述されているかだけで決まります。
なお、text
prop でテキストを記述して v-divider
も配置すると、必ずテキストの真下の位置に仕切り線が配置されます。
<template>
<v-container>
<v-card class="w-50" elevation="4">
<template v-slot:title>平家物語</template>
<template v-slot:subtitle>作者不詳</template>
<v-divider thickness="3"></v-divider>
<v-card-text>
祇園精舎の鐘の声、諸行無常の響きあり。
娑羅双樹の花の色、盛者必衰の理をあらわす。
おごれる人も久しからず、唯、春の夜の夢のごとし。
猛きものもついにはほろびぬ、
偏に風の前の塵に同じ。
</v-card-text>
<v-divider thickness="3"></v-divider>
<template v-slot:actions>
<v-btn>源氏を選択</v-btn>
<v-btn>平家を選択</v-btn>
</template>
</v-card>
</v-container>
</template>
画像関係
image
prop で背景画像を指定できます。下の例では、文字が背景画像の暗い部分に重なることを防ぐために、マージンを指定して多少位置をずらしています。
<template>
<v-container>
<v-row>
<v-col cols="4" v-for="val in variants">
<v-card :variant="val" image="https://cdn.vuetifyjs.com/images/cards/docks.jpg">
<v-card-title>平家物語</v-card-title>
<v-card-subtitle>{{val}}</v-card-subtitle>
<v-card-text>
祇園精舎の鐘の声、諸行無常の響きあり。
娑羅双樹の花の色、盛者必衰の理をあらわす。
おごれる人も久しからず、唯、春の夜の夢のごとし。
猛きものもついにはほろびぬ、
偏に風の前の塵に同じ。
</v-card-text>
<v-divider class="mb-5"></v-divider>
<v-card-actions class="mb-2">
<v-btn :variant="val" color="white">源氏を選択</v-btn>
<v-btn :variant="val" color="white">平家を選択</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
data: () => {
return {
variants: ['elevated','flat','tonal','outlined','text','plain']
}
}
}
</script>
背景画像が暗い場合には、theme="dark"
を指定する方法も使えます。これを指定すると elevated
, flat
のときだけテキストの色が白になります。テキストや v-card-actions
のコンポーネントの色を部分的に変えたい場合は、class="text-white"
や color="white"
などとして直接色を指定する必要があります。
タイトルへのアイコンの追加
prepend-icon
prop を使うと、タイトルの左側にアイコンを表示できます。
ただし、これを使うときは title
, subtitle
も prop で指定する必要か、もしくは v-slot
で記述する必要があります。
アイコンの色を指定するなど、細かなスタイルの指定をしたいときは v-slot
を使います。
なお、同様にして append-icon
prop でタイトルの右側にアイコンを追加することもできます。
<template>
<v-container>
<v-row>
<v-col cols="4">
<v-card variant="elevated"
prepend-icon="mdi-book-open-variant"
title="平家物語" subtitle="prop で指定した場合">
<v-card-text>
祇園精舎の鐘の声、諸行無常の響きあり。
娑羅双樹の花の色、盛者必衰の理をあらわす。
おごれる人も久しからず、唯、春の夜の夢のごとし。
猛きものもついにはほろびぬ、
偏に風の前の塵に同じ。
</v-card-text>
<v-card-actions>
<v-btn>
<v-icon icon="mdi-flag-outline" color="black" class="me-2"></v-icon>
源氏を選択
</v-btn>
<v-btn>
<v-icon icon="mdi-flag-variant" color="red-darken-4" class="me-2"></v-icon>
平家を選択
</v-btn>
</v-card-actions>
</v-card>
</v-col>
<v-col cols="4">
<v-card variant="elevated">
<template v-slot:prepend>
<v-icon icon="mdi-book-open-variant" color="primary"></v-icon>
</template>
<template v-slot:title>
平家物語
</template>
<template v-slot:subtitle>
v-slot で指定した場合
</template>
<v-card-text>
祇園精舎の鐘の声、諸行無常の響きあり。
娑羅双樹の花の色、盛者必衰の理をあらわす。
おごれる人も久しからず、唯、春の夜の夢のごとし。
猛きものもついにはほろびぬ、
偏に風の前の塵に同じ。
</v-card-text>
<v-card-actions>
<v-btn>
<v-icon icon="mdi-flag-outline" color="black" class="me-2"></v-icon>
源氏を選択
</v-btn>
<v-btn>
<v-icon icon="mdi-flag-variant" color="red-darken-4" class="me-2"></v-icon>
平家を選択
</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
入れ子のカード
v-card
を入れ子にしたり、縦や横に並べるとデザインの幅が広がります。入れ子にした場合、親カードの色や variant
などは子カードに継承されません。個別に指定する必要があります。
<template>
<v-container>
<v-row>
<v-col cols="6">
<v-card variant="elevated" elevation="5"
color="indigo-darken-4" rounded="xl">
<div class="d-flex justify-center">
<v-card color="indigo-darken-4"
class="w-50" variant="flat">
<template v-slot:prepend>
<v-icon icon="mdi-book-open-variant" color="blue-lighten-3"></v-icon>
</template>
<template v-slot:title>
平家物語
</template>
<template v-slot:subtitle>
v-slot で指定した場合
</template>
<v-card-text>
祇園精舎の鐘の声、諸行無常の響きあり。
娑羅双樹の花の色、盛者必衰の理をあらわす。
おごれる人も久しからず、唯、春の夜の夢のごとし。
猛きものもついにはほろびぬ、
偏に風の前の塵に同じ。
</v-card-text>
<v-card-actions>
<v-btn>
<v-icon icon="mdi-flag-outline" color="white" class="me-2"></v-icon>
源氏を選択
</v-btn>
<v-btn>
<v-icon icon="mdi-flag-variant" color="red-darken-4" class="me-2"></v-icon>
平家を選択
</v-btn>
</v-card-actions>
</v-card>
<v-img src="https://cdn.vuetifyjs.com/images/cards/docks.jpg" class="me-4"></v-img>
</div>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
タイトルやボタンを中央や右に寄せる
タイトルとサブタイトルは <div class="d-flex justify-center">
とすれば寄せられます。v-card-actions
の子要素は普通の方法では寄せらません。いくつか方法はありますが、下の例では v-layout
で強引に寄せてみました。
左右のカードを見比べるとわかるのですが、カードの中のコンポーネントやテキストをデフォルト以外の方向に寄せると、寄せる方法によって微妙に縦方向のサイズに影響がでて、v-slot
を使う場合と子要素を使う場合で高さが変わることがあります。
このようにお仕着せのデザインが気にらない場合は、v-card
を使って強引にレイアウトするより、v-sheet
を使って自力でレイアウトを指定したほうが幸せなことが多いです。
<template>
<v-container>
<v-row>
<v-col>
<v-card variant="elevated" elevation="4">
<template v-slot:title>
<div class="d-flex justify-center">作者不詳</div>
</template>
<template v-slot:subtitle>
<div class="d-flex justify-center">中央寄せ</div>
</template>
<v-card-text>
祇園精舎の鐘の声、諸行無常の響きあり。
娑羅双樹の花の色、盛者必衰の理をあらわす。
おごれる人も久しからず、唯、春の夜の夢のごとし。
猛きものもついにはほろびぬ、
偏に風の前の塵に同じ。
</v-card-text>
<template v-slot:actions>
<v-layout>
<v-spacer></v-spacer>
<v-btn>源氏を選択</v-btn>
<v-btn>平家を選択</v-btn>
<v-spacer></v-spacer>
</v-layout>
</template>
</v-card>
</v-col>
<v-col>
<v-card variant="elevated" elevation="4">
<v-card-title>
<div class="d-flex justify-end">平家物語</div>
</v-card-title>
<v-card-subtitle>
<div class="d-flex justify-end">右寄せ</div>
</v-card-subtitle>
<v-card-text>
祇園精舎の鐘の声、諸行無常の響きあり。
娑羅双樹の花の色、盛者必衰の理をあらわす。
おごれる人も久しからず、唯、春の夜の夢のごとし。
猛きものもついにはほろびぬ、
偏に風の前の塵に同じ。
</v-card-text>
<v-card-actions>
<v-layout>
<v-spacer></v-spacer>
<v-btn>源氏を選択</v-btn>
<v-btn>平家を選択</v-btn>
</v-layout>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
v-card
の variant
, prop
については下記を見てください。