Tips to create a Modern animated gradient background website with React/Next.js 13 (very easy )

Alain TAI
7 min readJun 26, 2023

--

Some people don’t care about design until it’s done poorly.

-Evan Williams

Here is a quick overview of the final result 😊

Why does design matter more than ever in 2023?

In the digital age, a website serves as the virtual storefront for businesses and organizations. It’s often the first point of contact for potential customers or clients, making it a critical component of your brand’s identity. Among the many elements that contribute to a website’s effectiveness, visual effects hold a significant place. I bet I haven’t told you anything new up until now 😅, just in case.

Visual effects can evoke emotions and create a mood that aligns with a brand’s identity, hence they can convey a brand’s personality and values, helping to build trust and connection with the audience.

Ready to get personal?

I’m a full-stack software developer with a deep-seated passion for WebGL and high-end front-end development. Now, I won’t pretend to be a design expert — my background is in classic computer science, not design school. But ever since I wrote my first line of code back in 2016, I’ve been on a mission to bridge the gap between design and development. It used to frustrate me, seeing the disparity between a designer’s vision and the final product. But that challenge has fueled my journey and shaped the developer I am today. Let’s get into the nitty-gritty :)

Step 1

Init the Next.js Project

Ready to recreate the example?

Start by initializing a Next.js project. You can follow the steps outlined in the official documentation. Choose a directory you’re comfortable with, and let’s get this show on the road! I’m going to assume you’ve already dipped your toes into the world of JavaScript and have some experience with the React framework. If that’s the case, we’re all set to dive in!

Step 2

Set up your main component

Got your project set up? Great! Now, let’s dive into the page.jsx file in the /appfolder. Clear out all the existing content - we're starting with a clean slate. Your mission now is to create the initial layout for the main section of your landing page. Think of this as your primary component, the star of the show, which will be rendered as a child inside the layout.tsx file. Ready? Let's get coding!👨‍💻

import './main.css' //personal main.css that I created

export default function Home() {
return (
<main className="main">
<div className="mainDiv">
<h1 className="bigTitle"><span className="welcomeTexjt">Welcome</span> to my blog </h1>
<div className='research'>scroll down to discover</div>
<div className="line"/>
</div>
</main>
)
}

Step 3

Set up the global styling

Next up, let’s tackle the global.css file. This is where we'll establish our main theme, including colors and styling. You might be wondering, Why can't I just set up any colors as I go along with my coding? Why do these global variables matter so much?' Well, imagine you want to introduce a custom dark theme, or perhaps change the theme colors down the line. If you haven't grouped these global variables together from the start, you'll find yourself spending a lot of time adjusting each child and component individually as your project grows. So, let's save future you some time and get those global variables set up now!

:root{
/**/
/*other default setting ...*/
/**/
--secondary-glow: conic-gradient(
from 10deg at 50% 50%,
#eb7494 0deg,
#ae77b2 55deg,
#97b5da 120deg,
#0099ca 160deg,
transparent 360deg
);

--third-glow: conic-gradient(
from 90deg at 50% 50%,
#ff8b7e 0deg,
#e24e6b 160deg,
#7ed2da 120deg,
#8bdce0 55deg,
transparent 360deg
);
}

Feel free to add those gradient colors we’ve discussed. They’ll be the key to configuring our vibrant gradient shapes.

Next, let’s add some basic styling to the main component in the new file created in the same folder /app named main.css. It's like prepping the stage before the magic show begins!

.main {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 40vh 0 0 0;
min-height: 100vh;
}

.mainDiv{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-family:'Prospect';
font-size:3rem;
}

.research{
margin: 2rem 0;
border-radius: 3vh;
display: flex;
justify-content: flex-start;
align-items: center;
font-size: 1.5rem;
font-family: 'Helvetica';
padding: 0 1rem;
}

.line
{
background-color: black;
display: flex;
flex-direction:row;
height:50vh;
width: 1px;

}

Step 4

Make magic happens

We’re about to add a gradient to the body element that will be applied across all pages. It’s like giving your website a fresh coat of paint! We’ll be using the ::beforeand ::after pseudo-elements on the <body> tag. But remember, this isn't just for the body tag - you can apply the same magic to any <div> that catches your eye just as showcased bellow:

body::before,
body::after {
content: '';
position: absolute;
z-index: -1;
opacity:0.8
}

Important things to understand for ::before and ::afterpseudo-element

  1. Let’s clear up a common misconception. When you type body::before and body::after, these elements are inserted inside the body element, not before or after it as you might initially interpret.
  2. Next up, the content property. This is your ticket to display anything visible. If you don't have any specific strings to display, no worries - just leave it as an empty string, like so: ' '.
  3. And finally, position: absolute. This little gem positions an element relative to its parent tag. It's like the obedient child who stays close to their parent at all times!

Now, it’s time to bring in those conic gradients we defined earlier. You’ll notice I’m using two coordinate systems here — vh and vw. These stand for 'viewport height'and 'viewport width' But don't feel boxed in - feel free to define any units that suit your design vision!

body::before {
background: var(--third-glow);
border-radius: 50%;
width: 50vw;
height: 50vw;
margin-left: -200px;
filter:blur(90px);
top: calc(50vh - 50vw/2);
left: calc(50vw );
}

body::after {
background: var(--secondary-glow);
border-radius: 50%;
width: 500px;
height: 700px;
filter:blur(90px);
top: calc(50vh - 50vw/2);
left: calc(50vw - 50vw/2);
}

The final texture is given by the filter: blur(). How does it work? Imagine the blur() function as a soft-focus lens for your website. It applies a Gaussian blur, gently smudging the details of your input image. The value inside the parentheses, like blur(95px), sets the radius of this soft-focus effect. So, with 95px, your image will be artistically blurred across a generous 95-pixel radius. It's like adding a touch of impressionist painting right into your webpage!

Step 5

Now, for the grand finale! Let’s sprinkle in some infinite looped animations.

Think of it as the secret sauce that keeps the visual feast going on and on by defining some keyframes like this.

@keyframes animateBefore {
0% {
transform: translateY(0);
}
50% {
transform: translateY(200px) scale(0.8);

}
100% {
transform: translateY(0);
}
}

@keyframes animateAfter{
0% {
transform: translateX(0);
}
50% {
transform: translateX(-250px) scale(1.2);

}
100% {
transform: translateX(0);
}
}

Explanations:

Picture 'animateBefore' as a choreographed dance for your webpage elements. At the start of the dance, at 0%, our element is standing tall at its original position - that's our 'transform: translateY(0)'.

But the dance is just getting started. At the 50% mark, our element makes a bold move — it slides down 200 pixels and shrinks slightly, becoming 80% of its original size. That’s what 'transform: translateY(200px) scale(0.8)' is all about.

And for the grand finale, at 100%, our element glides back to its original position, completing the dance with 'transform: translateY(0)'.

And the best part? This dance keeps repeating, creating a dynamic, engaging visual effect on your webpage. It’s like having a perpetual motion machine, constantly drawing the eye and adding a touch of life to your design. Then you can just add those keyframes into an animation function.

body::before {
/*...previous props*/
animation: animateBefore 7s cubic-bezier(0.47, 0, 0.745, 0.715) infinite;
}

body::after {
/*...previous props*/
animation: animateAfter 7s cubic-bezier(0.47, 0, 0.745, 0.715) infinite;
}

Explanations:

Think of the 'animation property as the director of a play, calling the shots on how your webpage elements should perform.

In this case, 'animateAfter' is the name of the keyframes that the animation is based on. It's the script that our actors (the webpage elements) will follow.

Next up, '7s' is the duration of the animation. That's how long each cycle of the animation will last. So, our actors will perform the entire 'animateAfter' script in a span of 7 seconds.

The ‘cubic-bezier(0.47, 0, 0.745, 0.715)' part? That's the pacing of the animation. It's like the rhythm of the music that our actors are dancing to. This specific cubic-bezier function creates an easing effect, meaning the animation starts off slow, speeds up, and then slows down again. I love cubic-bezier(), and it can make your moves look smoother, you can customize your cubic-bezier() functions by clicking here.

And finally, 'infinite'. This means that the animation will repeat forever. Our actors will keep performing the 'animateAfter' script, over and over, creates a continuous, captivating spectacle on your webpage!

Conclusion

And there you have it! We’ve journeyed together through a handful of simple yet powerful tips to modernize your website. Whether it’s embracing minimalism, optimizing for mobile, or adding a splash of animation, each of these strategies can breathe new life into your online presence. Remember, even the smallest changes can make a big difference. I hope you’ve found these insights helpful and inspiring. So, go ahead, roll up your sleeves, and start transforming your website into a digital masterpiece. Until next time, happy designing :)

Enjoyed this piece? Don’t keep it to yourself! Give that like button a click and share the love with your friends who are also starting their journey with Fuel. Your feedback is the fuel that keeps me going, so feel free to drop a comment here or slide into my Twitter DMs.

And hey, if front-end development sparks your interest, why not take a detour to my portfolio? It’s a showcase of my passion for creating digital magic. For more tips and insights, follow me on Twitter. Let’s continue this journey of learning and growing together!

--

--

Alain TAI

I'm a engineering creative full stack developer from France, webGL, shader and front-end lover❤️ :)