---
title: Inner Loading
desc: >-
  The QInnerLoading Vue component allows you to add a loading indicator within a
  component in the form of a local overlay.
related:
  - title: Linear Progress
    path: linear-progress.md
  - title: Circular Progress
    path: circular-progress.md
  - title: Spinners
    path: spinners.md
  - title: Skeleton
    path: skeleton.md
  - title: Loading Plugin
    path: ../quasar-plugins/loading.md
  - title: LoadingBar
    path: ../quasar-plugins/loading-bar.md
---
The QInnerLoading component allows you to add a progress animation within a component. Much like the [Loading Plugin](../quasar-plugins/loading.md), its purpose is to offer visual confirmation to the user that some process is happening in the background, which takes an excessive amount of time. QInnerLoading will add an opaque overlay over the delayed element along with a [Spinner](spinners.md).

## QInnerLoading API

### Props

- `transition-show` (string, optional), default `'fade'`
  One of Quasar's embedded transitions
  Examples: `'fade'`, `'slide-down'`
- `transition-hide` (string, optional), default `'fade'`
  One of Quasar's embedded transitions
  Examples: `'fade'`, `'slide-down'`
- `transition-duration` (string | number, optional), default `300`
  Transition duration (in milliseconds, without unit)
- `size` (string | number, optional), default `'42px'`
  Size in CSS units, including unit name, or standard size name (xs|sm|md|lg|xl), for the inner Spinner (unless using the default slot)
  Examples: `'16px'`, `'2rem'`, `'xs'`, `'md'`
- `showing` (boolean, optional)
  State - loading or not
- `color` (string, optional)
  Color name for component from the Quasar Color Palette for the inner Spinner (unless using the default slot)
  Examples: `'primary'`, `'teal'`, `'teal-10'`
- `label` (string, optional) *(added v2.2)*
  Add a label; Gets overriden when using the default slot
  Examples: `'Please wait...'`
- `label-class` (string, optional) *(added v2.2)*
  Add CSS class(es) to the label; Works along the 'label' prop only
  Examples: `'text-red q-mt-xl'`
- `label-style` (string | any[] | object, optional) *(added v2.2)*
  Apply custom style to the label; Works along the 'label' prop only
  Examples: `'font-size: 28px'`, `{ color: '#ff0000' }`
- `dark` (boolean, optional), default `null`
  Notify the component that the background is a dark color

### Slots

- `#default`
  Default slot is used for replacing default Spinner; Suggestions: a spinner or text

## Usage

> [!WARNING]
> In order for the spinner to be properly placed in the center of the element you want the loading display to show over, that element must have CSS position set to `relative` (or the `relative-position` CSS class declared).

> [!WARNING]
> QInnerLoading must be the last element inside its parent so it can appear on top of the other content.

### Basic

```vue
<template>
  <div class="q-pa-md q-gutter-md">
    <q-btn color="primary" @click="showTextLoading"> Show it </q-btn>

    <q-card class="relative-position card-example" flat bordered>
      <q-card-section class="q-pb-none">
        <div class="text-h6">Lorem Ipsum</div>
      </q-card-section>

      <q-card-section>
        <transition
          appear
          enter-active-class="animated fadeIn"
          leave-active-class="animated fadeOut"
        >
          <div v-show="showSimulatedReturnData">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent
            vel magna eu risus laoreet tristique. Nulla ut fermentum elit, nec
            consequat augue. Morbi et dolor nec metus tincidunt pellentesque.
            Nullam non semper ante. Fusce pellentesque sagittis felis quis
            porta. Aenean condimentum neque sed erat suscipit malesuada. Nulla
            eget rhoncus enim. Duis dictum interdum eros.
          </div>
        </transition>
      </q-card-section>

      <q-inner-loading :showing="visible">
        <q-spinner-gears size="50px" color="primary" />
      </q-inner-loading>
    </q-card>
  </div>
</template>

<script setup>
import { ref } from 'vue'

// Don't forget to specify which animations
// you are using in quasar.config file > animations.
// Alternatively, if using UMD, load animate.css from CDN.

const visible = ref(false)
const showSimulatedReturnData = ref(false)

function showTextLoading() {
  visible.value = true
  showSimulatedReturnData.value = false

  setTimeout(() => {
    visible.value = false
    showSimulatedReturnData.value = true
  }, 3000)
}
</script>

<style lang="sass" scoped>
.card-example
  width: 288px
  height: 315px
</style>
```

### Label *(v2.2+)*

You can add a label when using the default slot, but you can also use the "label" props instead:

### Label props

```vue
<template>
  <div class="q-pa-md q-gutter-md">
    <q-btn color="primary" @click="showTextLoading"> Show it </q-btn>

    <q-card class="relative-position card-example" flat bordered>
      <q-card-section class="q-pb-none">
        <div class="text-h6">Lorem Ipsum</div>
      </q-card-section>

      <q-card-section>
        <transition
          appear
          enter-active-class="animated fadeIn"
          leave-active-class="animated fadeOut"
        >
          <div v-show="showSimulatedReturnData">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent
            vel magna eu risus laoreet tristique. Nulla ut fermentum elit, nec
            consequat augue. Morbi et dolor nec metus tincidunt pellentesque.
            Nullam non semper ante. Fusce pellentesque sagittis felis quis
            porta. Aenean condimentum neque sed erat suscipit malesuada. Nulla
            eget rhoncus enim. Duis dictum interdum eros.
          </div>
        </transition>
      </q-card-section>

      <q-inner-loading
        :showing="visible"
        label="Please wait..."
        label-class="text-teal"
        label-style="font-size: 1.1em"
      />
    </q-card>
  </div>
</template>

<script setup>
import { ref } from 'vue'

// Don't forget to specify which animations
// you are using in quasar.config file > animations.
// Alternatively, if using UMD, load animate.css from CDN.

const visible = ref(false)
const showSimulatedReturnData = ref(false)

function showTextLoading() {
  visible.value = true
  showSimulatedReturnData.value = false

  setTimeout(() => {
    visible.value = false
    showSimulatedReturnData.value = true
  }, 3000)
}
</script>

<style lang="sass" scoped>
.card-example
  width: 288px
  height: 315px
</style>
```

## Accessibility *(v2.25+)*

QInnerLoading is a visual overlay only: the content it covers stays in the accessibility tree and remains focusable, and the loading state itself is never announced. Pass `role="status"` as an attribute and use the `label` prop so screen readers hear the state change, and manage the covered region yourself — set `aria-busy="true"` on it, or make it `inert` — when it shouldn't be reachable while loading.
