Back
Learn how to create content placeholders with animated shimmer effects for a more engaging and less intrusive loading experience.
<div class="skeleton-card"> <div class="skeleton-img"></div> <div class="skeleton-content"> <div class="skeleton-title"></div> <div class="skeleton-text"></div> <div class="skeleton-text"></div> <div class="skeleton-text skeleton-text-short"></div> </div> </div>
.skeleton-card { width: 300px; background-color: #FFFFFF; border-radius: 8px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); overflow: hidden; position: relative; }The shimmer effect is created using a pseudo-element that sweeps across the card. We create a diagonal gradient that's mostly transparent but has a semi-transparent white section in the middle. We initially position this gradient to the left of the card (translateX(-100%)) and then animate it to sweep across and beyond the card (translateX(100%)).
.skeleton-card::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0)); transform: translateX(-100%); animation: shimmer 1.5s infinite; } @keyframes shimmer { 100% { transform: translateX(100%); } }Now, let's style the image placeholder. This tall rectangle at the top of the card mimics a hero image or thumbnail that would typically appear in a content card.
.skeleton-img { height: 150px; background-color: #E2E8F0; }The content section gets some padding to match typical card layouts, creating space between the placeholder elements.
.skeleton-content { padding: 16px; }For the title placeholder, we create a taller rectangle with a light gray background. The rounded corners soften the appearance while it's in the loading state.
.skeleton-title { height: 24px; background-color: #E2E8F0; border-radius: 4px; margin-bottom: 16px; }The text placeholders are similar but shorter in height to represent lines of body text. By making the last line shorter (70% width), we create a more natural-looking paragraph structure.
.skeleton-text { height: 12px; background-color: #E2E8F0; border-radius: 4px; margin-bottom: 12px; } .skeleton-text-short { width: 70%; }Skeleton screens offer numerous advantages over traditional spinners or loaders: - Perceived performance: Users perceive interfaces with skeleton screens to load faster than those with generic loading indicators, even if the actual loading time is identical. - Reduced cognitive load: By previewing the layout that's about to appear, skeleton screens help users mentally prepare for the incoming content. - Lower bounce rates: The immediate visual feedback and layout preview keeps users engaged during loading, reducing the likelihood they'll abandon the page. - Progressive enhancement: As real content loads, it can replace skeleton elements one by one, creating a smooth transition to the fully loaded state. - Brand consistency: Unlike generic spinners, skeleton screens can be styled to match your application's specific layout and design language. This approach to loading states has been adopted by major platforms like LinkedIn, Facebook, and YouTube because it creates a more seamless, less jarring loading experience for users.
<div class="skeleton-card"> <div class="skeleton-img"></div> <div class="skeleton-content"> <div class="skeleton-title"></div> <div class="skeleton-text"></div> <div class="skeleton-text"></div> <div class="skeleton-text skeleton-text-short"></div> </div> </div> <style> .skeleton-card { width: 300px; background-color: #FFFFFF; border-radius: 8px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); overflow: hidden; position: relative; } .skeleton-card::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0)); transform: translateX(-100%); animation: shimmer 1.5s infinite; } .skeleton-img { height: 150px; background-color: #E2E8F0; } .skeleton-content { padding: 16px; } .skeleton-title { height: 24px; background-color: #E2E8F0; border-radius: 4px; margin-bottom: 16px; } .skeleton-text { height: 12px; background-color: #E2E8F0; border-radius: 4px; margin-bottom: 12px; } .skeleton-text-short { width: 70%; } @keyframes shimmer { 100% { transform: translateX(100%); } } </style>Thank you for reading this article.
Comments