Ghostly
Reference

CSS Reference

Custom properties, selectors, animations, transitions, and Tailwind plugin.

Importing

globals.css
@import '@ghostly-ui/core/css';

Custom Properties

Override these to customize Ghostly globally.

--ghostly-color

Base color of skeleton blocks.

ThemeDefault
Lighthsl(220 13% 87%)
Darkhsl(220 13% 18%)

--ghostly-shine

Highlight color for the shimmer gradient.

ThemeDefault
Lighthsl(220 13% 94%)
Darkhsl(220 13% 25%)

--ghostly-radius

Border radius for skeleton blocks. Default: 4px. Controlled by the radius prop.

--ghostly-speed

Animation cycle duration. Default: 1.5s. Controlled by the speed prop.

--ghostly-transition

Duration of the smooth fade-out transition when loading ends. Default: 0.3s. Active only when data-ghostly-smooth is present.

Example

globals.css
:root {
  --ghostly-color: hsl(210 40% 88%);
  --ghostly-shine: hsl(210 40% 94%);
  --ghostly-radius: 8px;
  --ghostly-speed: 1.2s;
  --ghostly-transition: 0.5s;
}

.dark {
  --ghostly-color: hsl(210 15% 15%);
  --ghostly-shine: hsl(210 15% 22%);
}

Animations

Shimmer (ghostly-shimmer)

Gradient sweep from right to left.

@keyframes ghostly-shimmer {
  0% { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}

Pulse (ghostly-pulse)

Opacity fades between 100% and 40%.

@keyframes ghostly-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

Wave

Uses ghostly-wave with staggered animation-delay on each direct child (0ms, 80ms, 160ms...). Supports up to 12 children with individual delays, plus a catch-all for 13+.

Dark Mode Detection

Ghostly auto-detects dark mode through three methods:

  1. .dark class — Tailwind convention
  2. data-theme="dark" — shadcn/ui / Radix convention
  3. prefers-color-scheme: dark — System preference
.dark,
[data-theme='dark'] {
  --ghostly-color: hsl(220 13% 18%);
  --ghostly-shine: hsl(220 13% 25%);
}

@media (prefers-color-scheme: dark) {
  :root:not(.light):not([data-theme='light']) {
    --ghostly-color: hsl(220 13% 18%);
    --ghostly-shine: hsl(220 13% 25%);
  }
}

Specificity

Ghostly uses :where() for most selectors, which has zero specificity. Override with a single class:

/* Overrides Ghostly's min-height for paragraphs */
[data-ghostly] p {
  min-height: 2em;
}

!important is used on color, background-color, and border-color to override component-level styles. These are scoped to [data-ghostly] and only apply during loading.

Minimum Dimensions

Elementmin-heightmin-width
h11.75em40%
h21.5em50%
h31.3em55%
h4-h61.15em45%
p3em80%
span, a, li1em2rem
input, textarea2.5rem6rem
button2.25rem5rem
img (no size)aspect-ratio: 16/9100%
svg1.5rem1.5rem

Reduced Motion

@media (prefers-reduced-motion: reduce) {
  [data-ghostly] * { animation: none !important; transition: none !important; }
}

Tailwind CSS Plugin

Ghostly includes an official Tailwind CSS plugin for utility-class workflows.

Setup

tailwind.config.js
import ghostly from '@ghostly-ui/core/tailwind'

export default {
  plugins: [ghostly],
}

Available Utilities

Radius

ClassCSS Variable
ghostly-radius-none--ghostly-radius: 0px
ghostly-radius-xs--ghostly-radius: 2px
ghostly-radius-sm--ghostly-radius: 4px
ghostly-radius-md--ghostly-radius: 8px
ghostly-radius-lg--ghostly-radius: 12px
ghostly-radius-full--ghostly-radius: 9999px

Speed

ClassCSS Variable
ghostly-speed-slow--ghostly-speed: 2s
ghostly-speed-normal--ghostly-speed: 1.5s
ghostly-speed-fast--ghostly-speed: 0.8s

Arbitrary Colors

<div class="ghostly-color-[hsl(210_40%_88%)] ghostly-shine-[hsl(210_40%_94%)]">
  ...
</div>

ghostly: Variant

Target elements inside a ghostly container:

<p class="ghostly:min-h-[5em] ghostly:w-3/4">
  Content that has custom skeleton dimensions
</p>

This compiles to [data-ghostly] & { ... }.