Carte
VCard regroupe le contenu d’un même sujet : média, titre, corps et actions. Avec href, toute la carte devient un lien.
Utilisation
A cliff path above the sea, with two beaches to stop at and a lighthouse at the end.
<script setup lang="ts">
import { VButton, VCard } from 'vectis-ui'
</script>
<template>
<VCard title="Coastal trail" subtitle="12 km · 4 hours" class="card">
A cliff path above the sea, with two beaches to stop at and a lighthouse at the end.
<template #footer>
<VButton size="sm">Book a guide</VButton>
</template>
</VCard>
</template>
<style scoped>
.card {
max-inline-size: 22rem;
}
</style>Exemples
Variantes
variant choisit outline, elevated ou filled.
A border on the page surface.
A raised surface with a shadow.
A muted surface with no border.
<script setup lang="ts">
import { VCard } from 'vectis-ui'
</script>
<template>
<div class="grid">
<VCard variant="outline" title="Outline">A border on the page surface.</VCard>
<VCard variant="elevated" title="Elevated">A raised surface with a shadow.</VCard>
<VCard variant="filled" title="Filled">A muted surface with no border.</VCard>
</div>
</template>
<style scoped>
.grid {
display: grid;
flex: 1;
grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
gap: var(--vectis-space-4);
}
</style>Tailles
size règle les marges intérieures et les espacements entre les parties.
<script setup lang="ts">
import { VCard } from 'vectis-ui'
</script>
<template>
<div class="grid">
<VCard size="sm" title="Small" subtitle="Dense lists">Less padding.</VCard>
<VCard size="md" title="Medium" subtitle="The default">Standard padding.</VCard>
<VCard size="lg" title="Large" subtitle="Featured content">More padding.</VCard>
</div>
</template>
<style scoped>
.grid {
display: grid;
flex: 1;
grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
align-items: start;
gap: var(--vectis-space-4);
}
</style>Le slot media occupe toute la largeur au-dessus du contenu. Donnez aux images un texte alt, ou alt="" si elles sont décoratives.
A shaded walk under old oaks, suitable for children.
<script setup lang="ts">
import { VCard } from 'vectis-ui'
</script>
<template>
<VCard title="Forest loop" subtitle="6 km · 2 hours" class="card">
<template #media>
<div class="cover" />
</template>
A shaded walk under old oaks, suitable for children.
</VCard>
</template>
<style scoped>
.card {
max-inline-size: 22rem;
}
.cover {
aspect-ratio: 16 / 9;
background: linear-gradient(135deg, oklch(0.55 0.12 150), oklch(0.35 0.08 170));
}
</style>Horizontale
orientation="horizontal" place le média au début. Dans une carte étroite, le média repasse au-dessus du contenu.
A cliff path above the sea, with two beaches to stop at and a lighthouse at the end.
<script setup lang="ts">
import { VButton, VCard } from 'vectis-ui'
</script>
<template>
<VCard orientation="horizontal" title="Coastal trail" subtitle="12 km · 4 hours" class="card">
<template #media>
<div class="cover" />
</template>
A cliff path above the sea, with two beaches to stop at and a lighthouse at the end.
<template #footer>
<VButton size="sm">Book a guide</VButton>
</template>
</VCard>
</template>
<style scoped>
.card {
flex: 1;
}
.cover {
min-block-size: 8rem;
background: linear-gradient(135deg, oklch(0.6 0.12 230), oklch(0.4 0.1 250));
}
</style>Cartes liens
Avec href, le titre est un lien dont la zone cliquable couvre la carte. Les boutons de la carte restent des cibles distinctes. Les attributs autres que class et style vont au lien. headingLevel rend le titre sous forme de titre de section.
A cliff path above the sea.
A shaded walk under old oaks.
A short climb to a viewpoint facing west.
<script setup lang="ts">
import { ref } from 'vue'
import { VButton, VCard } from 'vectis-ui'
const trails = [
{ id: 'coast', title: 'Coastal trail', text: 'A cliff path above the sea.', hue: 230 },
{ id: 'forest', title: 'Forest loop', text: 'A shaded walk under old oaks.', hue: 150 },
{
id: 'ridge',
title: 'Sunset ridge',
text: 'A short climb to a viewpoint facing west.',
hue: 40,
},
]
const saved = ref<string[]>([])
function toggle(id: string) {
saved.value = saved.value.includes(id)
? saved.value.filter((item) => item !== id)
: [...saved.value, id]
}
</script>
<template>
<ul class="grid">
<VCard
v-for="trail in trails"
:key="trail.id"
as="li"
variant="elevated"
:heading-level="3"
:href="`#${trail.id}`"
:title="trail.title"
>
<template #media>
<div class="cover" :style="{ '--hue': trail.hue }" />
</template>
{{ trail.text }}
<template #footer>
<VButton
size="sm"
variant="outline"
tone="neutral"
:aria-pressed="saved.includes(trail.id)"
@click="toggle(trail.id)"
>
Save
</VButton>
</template>
</VCard>
</ul>
</template>
<style scoped>
.grid {
display: grid;
flex: 1;
grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
gap: var(--vectis-space-4);
margin: 0;
padding: 0;
list-style: none;
}
.cover {
aspect-ratio: 4 / 3;
background: linear-gradient(135deg, oklch(0.6 0.12 var(--hue)), oklch(0.4 0.1 var(--hue)));
}
</style>Désactivée
disabled retire la destination du lien et atténue le titre et le média. Les contrôles des slots ne sont pas concernés.
The pass reopens in May, when the snow has melted.
<script setup lang="ts">
import { VCard } from 'vectis-ui'
</script>
<template>
<VCard
href="#closed"
disabled
title="Mountain pass"
subtitle="Closed for the winter"
class="card"
>
The pass reopens in May, when the snow has melted.
</VCard>
</template>
<style scoped>
.card {
max-inline-size: 22rem;
}
</style>Chargement
loading affiche des emplacements de chargement et masque le pied. Définissez loadingText pour annoncer le chargement aux lecteurs d’écran.
<script setup lang="ts">
import { ref } from 'vue'
import { VButton, VCard } from 'vectis-ui'
const loading = ref(true)
</script>
<template>
<div class="demo">
<VButton variant="outline" tone="neutral" @click="loading = !loading">
{{ loading ? 'Show content' : 'Show loading' }}
</VButton>
<VCard
:loading="loading"
loading-text="Loading the trail"
title="Forest loop"
subtitle="6 km · 2 hours"
class="card"
>
<template #media>
<div class="cover" />
</template>
A shaded walk under old oaks, suitable for children.
</VCard>
</div>
</template>
<style scoped>
.demo {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: var(--vectis-space-3);
}
.card {
inline-size: 22rem;
max-inline-size: 100%;
}
.cover {
aspect-ratio: 16 / 9;
background: linear-gradient(135deg, oklch(0.55 0.12 150), oklch(0.35 0.08 170));
}
</style>API
Props
Slots
Variables CSS