Loading

Page or container loading indicators.

Class name Type
.prs-loading Component Container
.prs-loading-scale Modifier Scale zoom
.prs-loading-pulse Modifier Opacity fade - reduce motion fallback
.prs-loading-reverse Modifier Light on dark
.prs-loading-xs Modifier Size
.prs-loading-sm Modifier Size
.prs-loading-md Modifier Size
.prs-loading-lg Modifier Size
.prs-loading-xl Modifier Size
  • Default

    Defaults to pulse when reduce motion OS setting is applied.

    <span class="prs-loading">
      <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" role="img"><use href="/_assets/prs-icons.svg#brand-ml-burst" /></svg>
    </span>
    
  • Scale

    Defaults to pulse when reduce motion OS setting is applied.

    <span class="prs-loading prs-loading-scale">
      <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" role="img"><use href="/_assets/prs-icons.svg#brand-ml-burst" /></svg>
    </span>
    
  • Pulse

    Fallback for when reduce motion OS setting is applied.

    <span class="prs-loading prs-loading-pulse">
      <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" role="img"><use href="/_assets/prs-icons.svg#brand-ml-burst" /></svg>
    </span>
    
  • <span class="prs-loading prs-loading-reverse">
      <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" role="img"><use href="/_assets/prs-icons.svg#brand-ml-burst" /></svg>
    </span>
    
    <span class="prs-loading prs-loading-reverse prs-loading-scale">
      <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" role="img"><use href="/_assets/prs-icons.svg#brand-ml-burst" /></svg>
    </span>
    
  • <!-- xs -->
    <span class="prs-loading prs-loading-xs"><svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" role="img"><use href="/_assets/prs-icons.svg#brand-ml-burst" /></svg></span>
    
    <!-- sm -->
    <span class="prs-loading prs-loading-scale prs-loading-sm"><svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" role="img"><use href="/_assets/prs-icons.svg#brand-ml-burst" /></svg></span>
    
    <!-- md/default -->
    <span class="prs-loading"><svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" role="img"><use href="/_assets/prs-icons.svg#brand-ml-burst" /></svg></span>
    
    <!-- lg -->
    <span class="prs-loading prs-loading-scale prs-loading-lg"><svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" role="img"><use href="/_assets/prs-icons.svg#brand-ml-burst" /></svg></span>
    
    <!-- xl -->
    <span class="prs-loading prs-loading-xl"><svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" role="img"><use href="/_assets/prs-icons.svg#brand-ml-burst" /></svg></span>
    
    <!-- custom -->
    <span class="prs-loading prs-loading-scale" style="--size-selector: 1.5rem"><svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" role="img"><use href="/_assets/prs-icons.svg#brand-ml-burst" /></svg></span>
    
  • Full Working Example

    Toggle the button to see a full working example with transition and styles applied. Please use the --prs-c-gray-900 color set to 80% opacity and a backdrop-filter: blur(8px); as well as cursor: wait. The status panel should fade in and then out for 500ms each.

    Make sure to adjust the status text to indicate what we are waiting for.

    <div x-data="
      {
        saving: false,
        flash(duration = 500) {
          this.saving = true
          setTimeout(() => {
            this.saving = false
          }, duration)
        },
      }
    ">
    
      <button @click="flash(5000)" class="prs-btn prs-btn-primary">Save</button>
    
      <!-- ⚠️ notice the aria attributes ⚠️ -->
      <div role="status" aria-live="polite" aria-atomic="true" x-show="saving" x-transition.opacity.duration.500ms class="backdrop-blur-sm flex items-center justify-center fixed inset-0 z-50 cursor-wait select-none before:(content-[''] [background-color:var(--prs-c-gray-900)] absolute inset-0 z-[-1] opacity-80)" x-cloak>
        <span class="prs-loading prs-loading-sm prs-loading-reverse">
          <span class="sr-only">Saving...</span>
          <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" role="img" class="w-full h-full"><use href="/_assets/prs-icons.svg?v={% bust %}#brand-ml-burst" /></svg>
        </span>
      </div>
    
    </div>
    

CSS

Full Library

Component Only

.prs-loading {
  pointer-events: none;
  aspect-ratio: 1;
  vertical-align: middle;
  width: calc(var(--size-selector, .625rem) * 6);
  display: inline-block;
  animation: loading-pulse 2s ease infinite;

  @media (prefers-reduced-motion: no-preference) {
    animation: loading-bounce 1.5s ease infinite;
  }

  &:where(.prs-loading-scale) {
    animation: loading-pulse 2s ease infinite;
    @media (prefers-reduced-motion: no-preference) {
      animation: loading-scale 2s ease infinite;
    }
  }

  &:where(.prs-loading-pulse) {
    animation: loading-pulse 2s ease infinite;
  }

  &:where(.prs-loading-reverse) {
    color: var(--prs-c-white);
  }

  &:where(.prs-loading-xs) {
    width: calc(var(--size-selector, .625rem) * 2);
  }
  &:where(.prs-loading-sm) {
    width: calc(var(--size-selector, .625rem) * 4);
  }
  &:where(.prs-loading-md) {
    width: calc(var(--size-selector, .625rem) * 6);
  }
  &:where(.prs-loading-lg) {
    width: calc(var(--size-selector, .625rem) * 8);
  }
  &:where(.prs-loading-xl) {
    width: calc(var(--size-selector, .625rem) * 10);
  }
}

@keyframes loading-bounce {
  50% {
    transform: translateY(-10%);
  }
}
@keyframes loading-pulse {
  50% {
    opacity: 0.5;
  }
}
@keyframes loading-scale {
  50% {
    transform: scale(1.2);
  }
}

Coming soon...