Custom Image Transition in Next.js With Tailwind CSS

Posted on May 12, 2022

- views

6 min read

Custom Image Transition in Next.js With Tailwind CSS

Make an image more interactive with the use of CSS transitions.

Table of Contents

  1. Introduction
  2. Getting Started
  3. How Tailwind CSS Transitions Work
  4. Understanding next/image onLoadingComplete callback
  5. Create Custom Images Components
  6. Apply a Blurred Effect to Images
  7. Create a Rick and Morty Character List With a Custom Image
  8. Conclusion

Introduction

One of the most important aspects of a website is its images. Images can now become more interactive with the use of CSS transitions. So, in this tutorial, we'll learn how to make images more interactive using the Tailwind CSS.

Tailwind CSS is a utility-first CSS framework packed with classes. Tailwind CSS does not come with components, unlike other CSS frameworks such as Bootstrap or Chakra UI. Tailwind CSS, on the other hand, works by giving you a set of classes. With these classes, you can quickly create your own designs.

Meme about tailwind css

Getting Started

If you don't already have one, begin by creating a new Next.js project. Using the Create Next App is the most usual method.

$ npx create-next-app my-project
$ cd my-project

After the project is created, we will move to the tailwind installation.

$ npm install -D tailwindcss postcss autoprefixer
$ npx tailwindcss init -p

Add the paths to all of your template files in tailwind.config.js file.

module.exports = {
  content: [
    './pages/**/*.{js,ts,jsx,tsx}',
    './components/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};

Add the @tailwind directives to ./styles/globals.css file.

@tailwind base;
@tailwind components;
@tailwind utilities;

After all we can start running project with:

$ yarn dev

# or

$ npm run dev

How Tailwind CSS Transitions Work

For example, we can make a button with a hover transition that changes the color of its background.

<button className='rounded-full bg-teal-600 px-6 py-3 font-medium text-white transition duration-300 hover:bg-indigo-500'>
  Hello Universe!
</button>
How tailwind css transitions work

it can be seen that with the transition class we can change the background color from bg-teal-600 to bg-indigo-500 with a duration of 300ms duration-300.

The transition stuff, which includes transition properties, transition duration, transition timing function, transition delay, and animation, can be found in the Tailwind CSS documentation. Here are all of the explanations for that:

Understanding next/image onLoadingComplete callback

onLoadingComplete is a callback function that is invoked once the image is completely loaded and the placeholder has been removed. This means that we can add a transition before the image is fully loaded.

To see how the onLoadingComplete callback works, we must create a state that contains the boolean false.

import React, { useState } from 'react';
import NextImage from 'next/image';

const Image = ({ src, ...props }) => {
  const [isReady, setIsReady] = useState(false);

  return (
    <NextImage objectFit='cover' src={src} {...props} layout='responsive' />
  );
};

export default Image;

Next, we create a function onLoadCallback which will change the state of isReady to true.

import React, { useState } from 'react';
import NextImage from 'next/image';

const Image = ({ src, ...props }) => {
  const [isReady, setIsReady] = useState(false);

  const onLoadCallback = () => {
    setIsReady(true);
  };

  return (
    <NextImage objectFit='cover' src={src} {...props} layout='responsive' />
  );
};

export default Image;

After that, we can call the onLoadCallback function in the onLoadingComplete props, which will trigger the event parameter which contains the loaded img.

import React, { useState } from 'react';
import NextImage from 'next/image';

const Image = ({ src, ...props }) => {
  const [isReady, setIsReady] = useState(false);

  const onLoadCallback = () => {
    setIsReady(true);
  };

  return (
    <NextImage
      objectFit='cover'
      src={src}
      {...props}
      onLoadingComplete={onLoadCallback}
      layout='responsive'
    />
  );
};

export default Image;

Create Custom Images Components

Now that we know how to use the onLoadingComplete callback, we can create custom image components by creating a components folder and putting the image.js file inside it.

├── README.md
├── components
│   └── image.js
├── next.config.js
├── package-lock.json
├── package.json
├── pages
│   ├── _app.js
│   ├── index.js
├── postcss.config.js
├── public
│   ├── favicon.ico
│   └── vercel.svg
├── styles
│   ├── Home.module.css
│   └── globals.css
└── tailwind.config.js

Then, in the image.js file, add the following code:

import React, { useState } from 'react';
import NextImage from 'next/image';

const Image = ({ src, ...props }) => {
  const [isReady, setIsReady] = useState(false);

  const onLoadCallback = () => {
    setIsReady(true);
  };

  return (
    <NextImage
      objectFit='cover'
      src={src}
      {...props}
      onLoadingComplete={onLoadCallback}
      layout='responsive'
    />
  );
};

export default Image;

Apply a Blurred Effect to Images

We use the blur effect to apply an effect to custom images that we created before. We can do this by adding the blur class with blur-2xl to the image when isReady is false and remove it when isReady is true with blur-0.

To make transition more interactive, we can add scale class with scale-120 to the image when isReady is false and scale-100 when isReady is true.

We also add the transition and duration-1000 class to the image to apply the transition effect.

<NextImage
  objectFit='cover'
  src={src}
  className={`bg-gray-400 transition duration-1000 ${
    isReady ? 'scale-100 bg-gray-400 blur-0' : 'scale-120 blur-2xl'
  }`}
  {...props}
  onLoadingComplete={onLoadCallback}
  layout='responsive'
/>

After That, we can import images components that we created before and use them in all images.

import Image from '../components/image';

const Test = () => {
  return (
    <main className='flex h-screen w-screen items-center justify-center'>
      <div className='w-1/4'>
        <Image src={`YOURIMAGESRC`} width={300} height={300} />
      </div>
    </main>
  );
};

export default Test;
use component on all images

Create a Rick and Morty Character List With a Custom Image

To apply to the project, we only need to import the components that were created earlier.

For example, we will implement the Rick and Morty API.

import Image from '../components/image';

export async function getStaticProps() {
  const res = await fetch('https://rickandmortyapi.com/api/character/');
  const content = await res.json();

  return {
    props: {
      content,
    },
  };
}

const Home = ({ content }) => {
  return (
    <div className='bg-gray-200 p-5 sm:p-16 lg:p-32'>
      <div className='grid grid-cols-1 gap-5 sm:grid-cols-2 md:gap-10 lg:grid-cols-3 xl:grid-cols-5'>
        {content.results.map((character) => {
          const { id, name, image, status, type, gender } = character;

          return (
            <div key={id} className='rounded-lg bg-white'>
              <div className='overflow-hidden rounded-t-lg'>
                <Image
                  src={image}
                  width={300}
                  height={300}
                  layout='responsive'
                />
              </div>
              <div className='mx-4 my-4'>
                <h2 className='text-xl font-bold text-gray-900'>{name}</h2>
                <p className='text-md text-gray-600'>Status : {status}</p>
                <p className='text-md text-gray-600'>Gender : {gender}</p>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
};

export default Home;

Here is the result of the implementation of the Rick and Morty Character List with a Custom Image.

implementation of the Rick and Morty Character List

Conclusion

Tailwind CSS can be used to provide a transition effect to custom images, making them more interactive.

The code of this project lives at : https://github.com/jagadyudha/custom-image-transition-in-nextjs-with-tailwind-css