How to create a custom loading screen with CSS in React

When developing a React application, it's common to have asynchronous operations that may take some time to complete. During this time, it's a good practice to provide a loading screen with some form of loading animation to keep users informed about the progress. Although we do have multiple powerful tools and packages available online to help us such as react-lottie, react-loading, react-spinner and react-loaders, we will explore how to create a custom loading screen using CSS in a React application.

Style the screen loader

Let's start with styling the loading screen and the loading animation (loading spinner) using CSS. This is to customize the loading screen as per our application's requirements. Create a new CSS file, e.g., LoadingScreen.css, and add the following styles:

.loading-screen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #6dc8cf;
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.loading-spinner {
border: 7px solid #f3f3f3;
border-top: 7px solid #f7ae65;
border-radius: 50%;
width: 100px;
height: 100px;
animation: spin 1.5s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

Code explanation

  • Lines 1–12: The .loading-screen class is used to set:

    • The location of the screen loader (loading spinner) on the loading screen. The position is set to fixed to ensure the loading screen covers the entire viewport. The properties display: flex, justify-content: center, and align-items: center center the loading spinner both vertically and horizontally.

    • The background color of the loading screen. The background-color is set to a semi-transparent black color (rgba(0, 0, 0, 0.8)) to create a dimmed effect.

  • Lines 14–21: The .loading-spinner class is used to create and style an object that will be used to demonstrate the loading animation.

  • Lines 23–30: The @keyframes rule in CSS is used to define an animation sequence with multiple keyframes. In the provided code snippet, @keyframes spin is a keyframe animation named "spin." The spin animation animates the transformation of an element's rotation from 0deg to 360deg over a specific duration.

Create the loading screen component

Next, create a new component in your React application to represent the loading screen. This component will use the styles we have defined in LoadingScreen.css. In the component file, LoadingScreen.js, import React and any necessary CSS files (e.g. LoadingScreen.css). Then, write the code to render the loading spinner:

import React from 'react';
import './LoadingScreen.css';
const LoadingScreen = () => {
return (
<div className="loading-screen">
<div className="loading-spinner"></div>
</div>
);
};
export default LoadingScreen;

We create a separate loading screen component to improve code organization, enable reusability, enhance readability, gain customization options, simplify conditional rendering, and facilitate testing. These benefits contribute to a more maintainable and scalable React application.

Use the loading screen component

Now that we have our LoadingScreen component and the corresponding styles, we can use it in our main component. Import the LoadingScreen component and use it conditionally based on the loading state.

import React, { useState, useEffect } from 'react';
import LoadingScreen from './LoadingScreen';
function App() {
const [loading, setLoading] = useState(true)
useEffect(() => {
setTimeout(() => setLoading(false), 3000)
}, [])
return (
<>
{loading && <LoadingScreen />}
{/* Rest of your component's content */}
</>
);
}
export default App;

In the code above, we have a loading state variable that is initially set to true. After a simulated asynchronous operation (in this case, a 3-second timeout), the loading state is set to false. When the loading state is true, the LoadingScreen component is rendered and displayed. Once the loading state becomes false, the loading screen disappears, and the rest of your component's content is shown.

Example

Let's look at a simple demo application where we have created a loading screen using the LoadingScreen component we have just created. Click “Run” to execute the code. Once the server starts, we can either interact with the application in the output tab or click on the URL next to “Your app can be found at:” to view the application in the new browser tab.

.App {
  text-align: center;
}

.App-logo {
  height: 40vmin;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 20s linear;
  }
}

.App-header {
  background-color: #fcbb79;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  font-family: "Comic Sans MS", "Comic Sans", cursive;
  color: black;
}
Screen loading using customized screen loader

The execution of the code above displays the application page that shows the loading screen, having a circular loading spinner, before displaying the application's landing (home) page. Now, try commenting out line 17 in the above code widget, and run the application again. This time, you will see a square loading spinner instead of a circular.

Benefits of creating a custom loading screen with CSS

Although using the online React packages/libraries is convenient, let's consider the advantages of using a custom loading screen:

  • Customization: We can have full control over the design, animations, and behavior of the loading screen, allowing us to tailor it to match our application's branding and user experience.

  • Lightweight: By creating a custom loading screen, we can keep our application lightweight by including only the necessary code and assets, avoiding unnecessary dependencies.

  • Flexibility: Custom loading screens provide the flexibility to implement specific functionality based on our application's requirements and handle various loading scenarios that align with our use cases.

  • Code optimization: We can optimize and fine-tune the component specifically for our application's needs with a custom loading screen, ensuring efficient rendering and performance.

  • Seamless integration: Custom loading screens seamlessly integrate into the React components and application structure, providing a consistent user experience.

  • Learning and growth: Building a custom loading screen helps deepen our understanding of CSS and React, enhancing our skills and knowledge in web development.

The aforementioned points can help you decide whether to create a custom loading screen or use pre-existing packages/libraries in your React app.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved