Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/crutchcorn/sync-skeleton. Vanilla CSS Synchronized Skeleton Loaders sync-skeleton.dev
Something went wrong. Try again.
4.0 kB · 135 lines
CSS
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136:root { /* global skeleton colors */ --skeleton-base-color: hsl(0 0% 92% / 100%); --skeleton-base-color-dark: hsl(0 0% 20% / 100%); --skeleton-highlight-color: hsl(0 0% 96% / 100%); --skeleton-highlight-color-dark: hsl(0 0% 15% / 100%);
/* global radius of skeletons */ --skeleton-radius: 0px;
/* global gradient sizes */ --skeleton-highlight-size: clamp(100px, 50vw, 500px); --skeleton-highlight-leading-edge-blur: clamp( 10px, 5vw, 50px ); /* set to 0px for a sharp edge */ /* global gradient angle */ --skeleton-angle: 90deg;
/* time to travel a given distance */ --skeleton-animation-animation-speed: 400; /* travel this many PIXELS */ --skeleton-animation-animation-time: 1; /* over this many SECONDS */ --skeleton-animation-animation-scaler: 0.7; /* scale the speed up as the screen size increases (0-1), 0.7 feels good. */
/* easing */ --skeleton-ease: cubic-bezier(0.45, 0.3, 0.7, 0.55);
/* ↓ stuff to calc, don't edit */
/* interesting hack to get viewport as an Integer; https://dev.to/janeori/css-type-casting-to-numeric-tanatan2-scalars-582j */ --skeleton-full-viewport: 100vw; --skeleton-calc-int-width: calc( 10000 * tan(atan2(var(--skeleton-full-viewport), 10000px)) ); /* scale the animation speed so it gets faster as the screen gets larger, because elements don't normally take up 100% width on larger screens and so the animation would slow down as screen gets larger without this. */ --skeleton-calc-scaled-time: calc( ( 1 - (var(--skeleton-calc-int-width) / 400) * var(--skeleton-animation-animation-scaler) / 5 ) ); /* get the animation time as a fraction of our desired distance/time */ --skeleton-calc-anim-time: calc( ( ( var(--skeleton-calc-int-width) / var(--skeleton-animation-animation-speed) ) * (var(--skeleton-animation-animation-time) * 1.33) ) * var(--skeleton-calc-scaled-time) ); /* we have the animation waiting for 1/3 of the time before starting each loop, so we multiple total time by 1.33 to account for it */}
.loading-skeleton { --skeleton-base: light-dark( var(--skeleton-base-color), var(--skeleton-base-color-dark) ); --skeleton-highlight: light-dark( var(--skeleton-highlight-color), var(--skeleton-highlight-color-dark) );
color: transparent; user-select: none; background-color: var(--skeleton-base); border-radius: var(--skeleton-radius);
--anim-pos: calc( var(--skeleton-percentage) * (100vw + var(--skeleton-highlight-size) * 2) - var(--skeleton-highlight-size) );
--leading-edge: calc( var(--anim-pos) + var(--skeleton-highlight-size) + var(--skeleton-highlight-leading-edge-blur) );
--gradient-end: calc( var(--anim-pos) + (var(--skeleton-highlight-size) * 100 / 100) );
background-image: linear-gradient( var(--skeleton-angle, 90deg), hsl(from var(--skeleton-highlight) h s l / calc(alpha * 0)) var(--anim-pos), hsl(from var(--skeleton-highlight) h s l / calc(alpha * 1)) var(--gradient-end), hsl(from var(--skeleton-highlight) h s l / calc(alpha * 0)) var(--leading-edge) );
background-attachment: fixed;}
@media not (prefers-reduced-motion) { .loading-skeleton { animation: skeletonPercent calc(1000ms * var(--skeleton-calc-anim-time)) var(--skeleton-ease) infinite; }}
.loading-skeleton.dark { color-scheme: dark;}
@property --skeleton-percentage { syntax: '<number>'; inherits: false; initial-value: 0;}
@property --skeleton-full-viewport { syntax: '<length>'; initial-value: 0px; inherits: false;}
@keyframes skeletonPercent { 0% { --skeleton-percentage: 0; } 66%, 100% { --skeleton-percentage: 1; } /* 66% allows for a short pause at the end of animation, avoiding extremely fast animations on mobile device viewports */}