Shimmering skeleton screen (Placeholder components) in React
Showing placeholder loading images, often referred to as skeleton screens, is a common practice to improve user experience during data fetching or page loading. Skeleton screens create the illusion of faster loading by displaying a placeholder structure that resembles the actual content. Here's how they are typically implemented, considering different viewport sizes:
1. Designing Skeleton Screens
Skeleton screens should mimic the layout and structure of the actual content. They are usually composed of gray boxes and lines to represent text, images, and other UI elements.
2. CSS for Skeleton Screens
Using CSS, you can create responsive skeleton screens that adapt to different viewport sizes. Here’s an example of how to create a simple skeleton screen using CSS:
/* Skeleton CSS */
.skeleton {
background-color: #e0e0e0;
border-radius: 4px;
animation: shimmer 1.5s infinite linear;
}
@keyframes shimmer {
0% {
background-position: -200px 0;
}
100% {
background-position: 200px 0;
}
}
.skeleton-text {
height: 16px;
margin: 10px 0;
}
.skeleton-rect {
width: 100%;
height: 200px;
margin: 10px 0;
}
3. Using CSS Grid/Flexbox for Responsive Layouts
To ensure that your skeleton screens adapt to different viewports, use CSS Grid or Flexbox. Here’s an example with Flexbox:
/* Container */
.skeleton-container {
display: flex;
flex-direction: column;
gap: 10px;
}
@media (min-width: 768px) {
.skeleton-container {
flex-direction: row;
}
}
.skeleton-item {
flex: 1;
padding: 10px;
}
4. JavaScript for Conditional Rendering
Use JavaScript or a front-end framework like React to conditionally render skeleton screens while data is loading.
Example in React
import React, { useState, useEffect } from 'react';
const Skeleton = () => (
<div className="skeleton-container">
<div className="skeleton-item">
<div className="skeleton skeleton-rect"></div>
<div className="skeleton skeleton-text"></div>
<div className="skeleton skeleton-text"></div>
<div className="skeleton skeleton-text"></div>
</div>
<div className="skeleton-item">
<div className="skeleton skeleton-rect"></div>
<div className="skeleton skeleton-text"></div>
<div className="skeleton skeleton-text"></div>
<div className="skeleton skeleton-text"></div>
</div>
</div>
);
const DataComponent = () => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
setTimeout(() => {
setData({ title: "Loaded Content" });
setLoading(false);
}, 2000); // Simulate loading delay
}, []);
return (
<div>
{loading ? (
<Skeleton />
) : (
<div>
<h1>{data.title}</h1>
<p>Actual content goes here.</p>
</div>
)}
</div>
);
};
export default DataComponent;
5. Handling Different Viewports
Ensure that the skeleton screen scales appropriately on different devices:
- Use media queries in CSS to adjust the size and layout of skeleton elements based on the viewport width.
- Use responsive units (e.g., %, vw, vh) instead of fixed units (e.g., px) for widths and heights.
- Test the skeleton screens on different devices to ensure they look good across various screen sizes.
Example for Different Viewports
/* Mobile */
.skeleton-container {
display: flex;
flex-direction: column;
}
.skeleton-item {
width: 100%;
}
/* Tablet */
@media (min-width: 768px) {
.skeleton-container {
flex-direction: row;
}
.skeleton-item {
width: 48%;
margin: 1%;
}
}
/* Desktop */
@media (min-width: 1024px) {
.skeleton-item {
width: 32%;
margin: 1%;
}
}
Live demo at https://stackblitz.com/edit/react-kkrsvm?file=src%2FSkeleton.js