Skip to content

Instantly share code, notes, and snippets.

@mrtrimble
Created December 21, 2020 13:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrtrimble/1c2770bd4ecd8dd2ffe9521fff438ecb to your computer and use it in GitHub Desktop.
Save mrtrimble/1c2770bd4ecd8dd2ffe9521fff438ecb to your computer and use it in GitHub Desktop.
Simple way to make skeletons in CSS and JavaScript
.skeleton {
position: relative;
box-sizing: border-box;
display: -webkit-box;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
flex-flow: column;
width: 100%;
}
.skeleton__line {
overflow: hidden;
position: relative;
box-sizing: border-box;
display: block;
height: 1em;
width: 100%;
background: #efefef;
border-radius: 3px;
}
.skeleton__line + .skeleton__line:last-child {
width: 50%;
}
.skeleton--sm {
width: 25%;
}
.skeleton--md {
width: 50%;
}
.skeleton--lg {
width: 75%;
}
.skeleton--full {
width: 100%;
}
.skeleton--animation {
position: abosolute;
display: -webkit-box;
display: flex;
height: 100%;
background: white;
background: -webkit-gradient(linear, left top, right top, from(rgba(255, 255, 255, 0)), color-stop(10%, rgba(255, 255, 255, 0)), color-stop(50%, rgba(255, 255, 255, 0.5)), color-stop(90%, rgba(255, 255, 255, 0)), to(rgba(255, 255, 255, 0)));
background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 10%, rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 90%, rgba(255, 255, 255, 0) 100%);
-webkit-animation: shine 3s infinite cubic-bezier(0.55, 0.055, 0.675, 0.19);
animation: shine 3s infinite cubic-bezier(0.55, 0.055, 0.675, 0.19);
}
.skeleton:last-child {
margin-bottom: 0;
}
p .skeleton__line {
margin-bottom: 0.6em;
}
.skeleton-image {
overflow: hidden;
display: block;
background-color: #efefef;
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBpZD0iTGF5ZXJfMSIgeD0iMCIgeT0iMCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMjIyLjQgMjg4IiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAyMjIuNCAyODgiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyIvPjxnPjxwYXRoIGQ9Ik0yMTgsNzQuM0wxNDguOSw1LjhjLTItMi00LjgtMy4yLTcuNy0zLjJIMjQuN0MxMi4xLDIuNiwxLjksMTIuOCwxLjksMjUuNFYyNjNjMCwxMi42LDEwLjIsMjIuOCwyMi44LDIyLjhoMTczLjcgYzEyLjYsMCwyMi44LTEwLjIsMjIuOC0yMi44VjgyQzIyMS4yLDc5LjEsMjIwLjEsNzYuMywyMTgsNzQuM3ogTTE0NS44LDM2LjVsNDEuMyw0MWgtNDEuM1YzNi41eiBNMjUuOSwyNjEuOFYyNi42aDk1Ljh2NTkuMiBjMCw4LjYsNywxNS42LDE1LjYsMTUuNmg1OS44djE2MC40SDI1Ljl6Ii8+PGNpcmNsZSBjeD0iNzMuMyIgY3k9IjExNS4yIiByPSIyNy4xIi8+PHBhdGggZD0iTTE0Mi43LDEzNy42Yy0xLjgtMS45LTQuMy0zLTYuOS0yLjljLTIuNiwwLjEtNS4xLDEuMy02LjcsMy4zbC0zOC4yLDQ2LjVsLTkuMy05LjdjLTEuOC0xLjktNC4yLTIuOS02LjgtMi44IGMtMi42LDAuMS01LDEuMy02LjYsMy4zbC0yNS4zLDMwLjZjLTEuMywxLjYtMi4xLDMuNi0yLjEsNS43djI3LjJjMCw1LDQsOSw5LDloMTI0LjhjNSwwLDktNCw5LTlWMTg2YzAtMi4yLTAuOC00LjQtMi4zLTYuMSBMMTQyLjcsMTM3LjZ6IE0xNjUuNiwyMjkuN0g1OC44di0xNWwxNi44LTIwLjNsOS4zLDkuN2MxLjgsMS45LDQuMywyLjksNi44LDIuOGMyLjYtMC4xLDUtMS4zLDYuNi0zLjNsMzgtNDYuM2wyOS4yLDMyLjFWMjI5Ljd6Ii8+PC9nPjwvc3ZnPg==");
background-blend-mode: overlay;
background-repeat: no-repeat;
background-position: center;
background-size: 15px;
}
.skeleton-image--sm {
height: 50px;
width: 50px;
}
.skeleton-image--md {
height: 100px;
width: 100px;
}
.skeleton-image--lg {
height: 200px;
width: 200px;
}
.skeleton-image--xl {
height: 400px;
width: 400px;
}
.skeleton-image--full {
height: 100%;
width: 100%;
}
.skeleton-image--landscape {
width: 100% !important;
}
.skeleton-image--portrait {
height: 100% !important;
}
.skeleton-image--circle {
border-radius: 50%;
box-shadow: inset 0px 0px 1px #707070;
}
h1 .skeleton__line,
h2 .skeleton__line,
h3 .skeleton__line,
h4 .skeleton__line,
h5 .skeleton__line,
h6 .skeleton__line {
margin-bottom: 0.2em;
}
@-webkit-keyframes shine {
0% {
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
}
30% {
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
100% {
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
}
@keyframes shine {
0% {
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
}
30% {
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
100% {
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
}
const skeletons = document.querySelectorAll(".skeleton");
if (skeletons) {
skeletons.forEach((skelly) => {
let lineCount = parseInt(skelly.getAttribute("data-lines"));
let animation = skelly.getAttribute("data-animation") === "true";
if (!lineCount && skelly.innerHTML.trim().length == 0) {
lineCount = 1;
}
for (i = 0; i < lineCount; i++) {
const line = document.createElement("span");
line.classList.add("skeleton__line");
if (animation === true) {
const animationElement = document.createElement("span");
animationElement.classList.add("skeleton--animation");
line.appendChild(animationElement);
}
skelly.appendChild(line);
}
});
}
const skeletonImages = document.querySelectorAll(".skeleton-image");
if (skeletonImages) {
skeletonImages.forEach((skelly) => {
let animation = skelly.getAttribute("data-animation") === "true";
if (animation === true) {
const animationElement = document.createElement("span");
animationElement.classList.add("skeleton--animation");
skelly.appendChild(animationElement);
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment