Skip to content

Skeleton

Place a skeleton where content is loading. In some scenarios, it provides a better visual experience than a loading spinner.

Basic Usage

Basic skeleton effect.

<template>
  <b-skeleton></b-skeleton>
</template>

More Parameters

Configure the number of skeleton paragraph rows to more closely match the real rendering. The displayed count will be one more than the number passed in; the first row is rendered as a leading paragraph at 33% width.

<template>
  <b-skeleton :rows="5"></b-skeleton>
</template>

Animation Effect

Can display animation effects.

<template>
  <b-skeleton animation></b-skeleton>
</template>

Custom

Use slots to define custom templates, allowing you to build a skeleton that closely matches the real DOM structure.

<template>
  <b-skeleton style="width: 240px" animation>
    <template #template>
      <b-skeleton-item variant="image" style="width: 240px; height: 240px" />
      <div style="padding: 14px">
        <b-skeleton-item variant="p" style="width: 50%" />
        <div flex="main:justify cross:center">
          <b-skeleton-item variant="text" style="margin-right: 16px" />
          <b-skeleton-item variant="text" style="width: 30%" />
        </div>
      </div>
    </template>
  </b-skeleton>
</template>

Loading loading

After loading completes, display the real UI via the slot.

User Info

User Info Content

User Info Content

User Info Content

2026-05-18

<template>
  <div>
    <div class="mb-15">
      <b-button @click="show">Show after 2s</b-button>
    </div>
    <b-skeleton style="width: 350px" :loading="loading" animation>
      <template #template>
        <div flex="cross:center" style="margin-bottom: 8px">
          <b-skeleton-item variant="circle" style="width: 36px; margin-right: 8px" />
          <div style="width: 200px">
            <div flex="main:justify cross:center">
              <b-skeleton-item variant="text" style="margin-right: 16px" />
              <b-skeleton-item variant="text" style="width: 30%" />
            </div>
          </div>
        </div>
        <b-skeleton />
      </template>
      <template #default>
        <div style="width: 350px">
          <div flex="cross:center" style="margin-bottom: 8px">
            <b-skeleton-item variant="circle" style="width: 36px; margin-right: 8px" />
            <div style="width: 200px">User Info</div>
          </div>
          <p>User Info Content</p>
          <p>User Info Content</p>
          <p>User Info Content</p>
          <p>{{ currentDate }}</p>
        </div>
      </template>
    </b-skeleton>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import dayjs from 'dayjs'

const loading = ref(false)
const currentDate = ref(dayjs().format('YYYY-MM-DD'))

function show() {
  loading.value = true
  setTimeout(() => {
    loading.value = false
  }, 2000)
}
</script>

Skeleton Props

ParameterDescriptionTypeOptionsDefault
animatedWhether to useanimationbooleantrue / falsefalse
countNumber of templates to render; use the smallest number possiblenumberinteger1
loadingWhether to show the real DOM structurebooleantrue / falsefalse
rowsNumber of skeleton paragraph rowsnumberPositive integer3
throttleDelay before rendering the placeholder DOM, in millisecondsnumberPositive integer0

Skeleton Item Attributes

ParameterDescriptionTypeOptionsDefault
variantStyle of the currently displayed placeholder elementEnum(string)p / text / h1 / h2 / h5 / text / caption / button / image / circle / recttext

Skeleton Slots

namedescription
defaultUsed to display the real UI
templateUsed to display custom placeholders