Skeleton
A loading placeholder component that displays a skeleton screen while content is loading.
| Name | Category | Description | Type | Default |
|---|---|---|---|---|
animated | Style | Whether to show shimmer animation | boolean | true |
animation | Style | Animation style: shimmer (scanline sweep), pulse (two-frame blink), dither (checkerboard dissolve) | 'shimmer' | 'pulse' | 'dither' | 'shimmer' |
variant | Style | Skeleton shape variant | 'text' | 'circular' | 'rectangular' | 'rounded' | 'rectangular' |
width | Size | Custom width (number as px, string as-is) | string | number | — |
height | Size | Custom height (number as px, string as-is) | string | number | — |
size | Size | Skeleton size | 'large' | 'default' | 'small' | 'default' |
loading | State | Whether to show the skeleton | boolean | true |
rows | Content | Number of rows for text variant (only when variant="text" and rows > 1) | number | 1 |
default | Slot | Content to display when loading is complete | — |
Basic Usage
Display skeleton placeholders with different widths.
<template>
<div class="demo-skeleton">
<px-skeleton />
<px-skeleton width="75%" />
<px-skeleton width="50%" />
</div>
</template>
<style scoped>
.demo-skeleton {
display: flex;
flex-direction: column;
gap: 12px;
}
</style>Variants
Use variant to change the skeleton shape: rectangular (default), circular, rounded, or text.
<template>
<div class="demo-skeleton">
<div class="demo-skeleton__item">
<span class="demo-skeleton__label">rectangular</span>
<px-skeleton variant="rectangular" width="120px" height="80px" />
</div>
<div class="demo-skeleton__item">
<span class="demo-skeleton__label">circular</span>
<px-skeleton variant="circular" />
</div>
<div class="demo-skeleton__item">
<span class="demo-skeleton__label">rounded</span>
<px-skeleton variant="rounded" width="120px" height="80px" />
</div>
<div class="demo-skeleton__item">
<span class="demo-skeleton__label">text</span>
<px-skeleton variant="text" width="200px" />
</div>
</div>
</template>
<style scoped>
.demo-skeleton {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
gap: 24px;
}
.demo-skeleton__item {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
}
.demo-skeleton__label {
font-size: 12px;
color: var(--vp-c-text-2);
font-family: var(--px-font-family, monospace);
}
</style>Animation
Use animated to toggle animation on/off. Use animation to choose the animation style: shimmer (scanline sweep), pulse (two-frame blink), or dither (checkerboard dissolve).
<template>
<div class="demo-skeleton">
<div>
<p class="demo-skeleton__label">shimmer (default)</p>
<px-skeleton animation="shimmer" width="200px" />
</div>
<div>
<p class="demo-skeleton__label">pulse</p>
<px-skeleton animation="pulse" width="200px" />
</div>
<div>
<p class="demo-skeleton__label">dither</p>
<px-skeleton animation="dither" width="200px" />
</div>
<div>
<p class="demo-skeleton__label">static</p>
<px-skeleton :animated="false" width="200px" />
</div>
</div>
</template>
<style scoped>
.demo-skeleton {
display: flex;
gap: 32px;
flex-wrap: wrap;
}
.demo-skeleton__label {
margin-bottom: 8px;
font-size: 12px;
color: var(--vp-c-text-2);
font-family: var(--px-font-family, monospace);
}
</style>Loading Toggle
Use loading to switch between skeleton and actual content via the default slot.
<template>
<div class="demo-skeleton">
<px-button @click="loading = !loading" size="small">
{{ loading ? 'Show Content' : 'Show Skeleton' }}
</px-button>
<px-skeleton :loading="loading" width="300px">
<p class="demo-skeleton__content">Content loaded successfully!</p>
</px-skeleton>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const loading = ref(true);
</script>
<style scoped>
.demo-skeleton {
display: flex;
flex-direction: column;
gap: 16px;
}
.demo-skeleton__content {
margin: 0;
font-family: var(--px-font-family, monospace);
}
</style>Text Rows
Use variant="text" with rows to render multiple text lines. The last row is automatically shorter.
<template>
<div class="demo-skeleton">
<px-skeleton variant="text" :rows="3" width="300px" />
</div>
</template>
<style scoped>
.demo-skeleton {
display: flex;
flex-direction: column;
gap: 12px;
}
</style>Sizes
Use size to set predefined skeleton heights: large, default, or small.
<template>
<div class="demo-skeleton">
<div class="demo-skeleton__item">
<span class="demo-skeleton__label">large</span>
<px-skeleton size="large" width="200px" />
</div>
<div class="demo-skeleton__item">
<span class="demo-skeleton__label">default</span>
<px-skeleton width="200px" />
</div>
<div class="demo-skeleton__item">
<span class="demo-skeleton__label">small</span>
<px-skeleton size="small" width="200px" />
</div>
</div>
</template>
<style scoped>
.demo-skeleton {
display: flex;
flex-direction: column;
gap: 16px;
}
.demo-skeleton__item {
display: flex;
align-items: center;
gap: 12px;
}
.demo-skeleton__label {
font-size: 12px;
color: var(--vp-c-text-2);
font-family: var(--px-font-family, monospace);
min-width: 60px;
}
</style>Custom Dimensions
Use width and height props for precise control. Numbers are treated as pixels, strings are used as-is.
<template>
<div class="demo-skeleton">
<px-skeleton :width="250" :height="40" />
<px-skeleton width="80%" height="3rem" />
<px-skeleton variant="circular" :width="64" :height="64" />
</div>
</template>
<style scoped>
.demo-skeleton {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 16px;
}
</style>