Home   reactjs  

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:

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

Published on: Jul 05, 2024, 08:23 AM  
 

Comments

Add your comment