Square Animation Using Tailwindcss

June 2024

Tech Stack: Tailwindcss, Visual Studio Code, HTML, JavaScript.

Animated spinning squares using Tailwind CSS

I wanted to add some type of movement to my website. I wasn't sure what, but decided to keep it simple and add some animated squares to my homepage. I wanted to accomplish doing this with tailwindcss and avoid creating css files or adding to my global.css file.

How it works?

To create the animation I created two div's with borders for the boxes. One with a rotation of 45 degrees so the squares will be offset from eachother.

<div className="flex flex-grow justify-center items-center">
          <div className=" rotate-45 w-40 h-40 md:w-56 md:h-56 absolute border-2 dark:border-white border-black"></div>
          <div className="w-40 h-40 md:w-56 md:h-56 border-2 border-[#E6A297]"></div>
</div>

This code will give you two boxes one being 45 degrees offset.

image of two squares

To add the custom animation @keyframes I added keyframes to theme configuration in tailwind.config.js.

theme: {
    extend: {
      animation: {
        'spin-square-right': 'rotateright 3s ease-in-out 0s infinite alternate',
        'spin-square-left': 'rotateleft 3s ease-in-out 0s infinite alternate',
      },
      keyframes:{
        rotateright: {
        '0%' :{ transform: 'rotate(0)'},
        '25%' :{ transform: 'rotate(90deg)'},
        '50%'  :{transform: 'rotate(180deg)'},
        '75%' :{transform: 'rotate(270deg)'},
        '100%' :{transform: 'rotate(360deg)'},
        },
        rotateleft: {
          '0%' :{ transform: 'rotate(45)'},
          '25%' :{ transform: 'rotate(-45deg)'},
          '50%'  :{transform: 'rotate(-135deg)'},
          '75%' :{transform: 'rotate(-225deg)'},
          '100%' :{transform: 'rotate(-315deg)'},
        }
      } 
    },
  },

Adding these to tailwind.config.js allowed me to create custom tailwind calls animate-spin-square-left``` and animate-spin-square-right`.

<div className="flex flex-grow justify-center items-center">
          <div className=" rotate-45 w-40 h-40 md:w-56 md:h-56 absolute border-2 dark:border-white border-black animate-spin-square-left"></div>
          <div className="w-40 h-40 md:w-56 md:h-56 border-2 border-[#E6A297] animate-spin-square-right"></div>
</div>

After adding these calls to my boxes I got the below results.

Four Spinning Squares

I reused the same code from the overlapping squares on these but instead of overlapping have them next to eachother.

<div className="flex flex-grow justify-center items-center my-20 gap-5">
          <div className="rotate-45 w-16 h-16 md:w-24 md:h-24  border-2 dark:border-white border-black animate-spin-square-left"></div>
          <div className="w-16 h-16 md:w-24 md:h-24 border-2 border-[#E6A297] animate-spin-square-right"></div>
          <div className="rotate-45 w-16 h-16 md:w-24 md:h-24  border-2 dark:border-white border-black animate-spin-square-left"></div>
          <div className="w-16 h-16 md:w-24 md:h-24 border-2 border-[#E6A297] animate-spin-square-right"></div>
</div>

The Animation Changes by Changing the Window Size.

To get this to work I had to use some javascript. It is checking if the window size is shrinking. If the window size is shrinking it calls the big overlapping squares, otherwise it's the four spinning square animation.

const [width, setWidth] = useState(0);
  const [isShrinking, setIsShrinking] = useState(false);

  useEffect(() => {
    const handleResize = () => {
      setIsShrinking(window.innerWidth < width);
      setWidth(window.innerWidth);
    };

    window.addEventListener("resize", handleResize);

    return () => {
      window.removeEventListener("resize", handleResize);
    };
  }, [width]);

  return (
    <>
      {isShrinking ? <SquareAnimation /> : <TinySquares />}
    </>
  );

Final Thoughts?

If tailwind.config gets a bit messy I would take out the animation portion and use arbitrary values like animate-[rotateright 3s ease-in-out 0s infinite alternate] instead of animate-spin-square-right. This could help consolidate the file some. I personally think it is cleaner to include the animation section. I like the ease of use instead of using arbitrary values.

I want to add a few more animations eventually.

AnimationFront-End