DEV Community

Cover image for CSS | Worm Animation
Shubham Tiwari
Shubham Tiwari

Posted on

CSS | Worm Animation

Hello Frontend developers, today i will show you how to create a smooth worm or snake animation, whatever name you like, with html and css only. We are going to SASS just for writing less css. You can get the css code from sass in the codepen below. Just click the dropdown in the CSS tab and select "view compiled css".

Let's get started...

What we are going to build?

HTML



<div class="parent">
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
</div>


Enter fullscreen mode Exit fullscreen mode
  • So we have just created a container with class name "parent" with 12 child elements with a class name "circle"

CSS

Basic stylings



html {
  color-scheme: dark light;
}
body {
  min-height: 100vh;
  display: grid;
  place-items: center;
}

.parent {
  margin-top: 50px;
  width: 200px;
  aspect-ratio: 1;
  position: relative;
}


Enter fullscreen mode Exit fullscreen mode
  • The color-scheme property specifies that the web page should adapt to both dark and light color schemes.
  • The body style ensures that the body of the web page is centered both horizontally and vertically on the screen.
  • The parent class defines a container with a square aspect ratio (width equals height) and relative positioning.

Child elements stylings



.circle {
  --size: 25px;
  width: var(--size);
  aspect-ratio: 1;
  border-radius: 50%;
  position: absolute;
  top: 0;

  @media screen and (max-width: 580px) {
    --size: 15px;
  }
}


Enter fullscreen mode Exit fullscreen mode
  • We have 1 variables size for width of the circles
  • aspect ration ensures the circles will always have a equal width and height and border radius makes the circles circular.
  • top property initial value is set to 0 and will be used in the animation part.

Colors



$colors: (
  #ff5733,
  #ffbd33,
  #33ff57,
  #33a1ff,
  #b933ff,
  #ff33a1,
  #33ffbd,
  #338aff,
  #ff3333,
  #33ffa1,
  #a1ff33,
  #ff33bd
);


Enter fullscreen mode Exit fullscreen mode
  • As we have 12 child elements, we are defining 12 different colors for each cirlce

Logic for the circles



@for $i from 1 through length($colors) {
  .circle:nth-of-type(#{$i}) {
    background-color: nth($colors, $i);
    animation: rotate ease-in-out infinite alternate;
    animation-delay: #{$i *
      0.1}s; // Adjust the delay to control the spacing between animations
    animation-duration: 2s; // Adjust the duration as needed for the speed of rotation
    transform-origin: center; // Rotate from the center of each circle
    left: #{$i * 20}px;
  }
}


Enter fullscreen mode Exit fullscreen mode
  • Using SASS, we are looping through the colors array from 1-12.
  • Then passing the value of i to the nth-child, it will applied like this (nth-child(1), nth-child(2), ... and so on)
  • Then we have passed the animation name, transition value, iteration as infinite and alternate so it will be in flow not start the animation from scratch again and again.
  • Animation delay is different for each item as we are using i times .1s, which will be like this(animation-delay:.1s, animation-delay:.2s, animation-delay:.3s,... and so on).Making the left side circles move fast and right side ones slow. Animation delay makes the animation looks like worm
  • Then animation duration set to 2s to make the animation little bit slow.
  • Then left property with a value i multiplied by 20(20,40,60), to provide a gap between the circles.

Animation



@keyframes rotate {
  0% {
    top: 0;
  }
  50% {
    top: 100%;
  }
  100% {
    top: -100%;
  }
}


Enter fullscreen mode Exit fullscreen mode
  • So the initial position of the circles are center as i have made the body as grid and place items as center. you can use some other container or div to wrap around the parent container and make the outer container as grid and place the items at center with height 100vh.
  • Animation will start the top 0, which is center, the at 50 % go downwards and at 100% go upwards and then keep this flow runnning.

Feel free to give suggestions in comments to improve the component and make it more reusable and efficient.
THANK YOU FOR CHECKING THIS POST
You can contact me on -
Instagram - https://www.instagram.com/supremacism__shubh/
LinkedIn - https://www.linkedin.com/in/shubham-tiwari-b7544b193/
Email - shubhmtiwri00@gmail.com

You can help me with some donation at the link below Thank you👇👇

☕ --> https://www.buymeacoffee.com/waaduheck <--

Also check these posts as well

Top comments (8)

Collapse
 
efpage profile image
Eckehard

Check out this beautiful Jellyfish-menue I created for this page. This is reacting to mouse movement and is super easy to use (see example lower on this page). Do you think, this could be achieved using CSS only? And can we build a code module somehow to reuse it in any other project?

Collapse
 
shubhamtiwari909 profile image
Shubham Tiwari

Like we can create that circular layout alone with CSS but for that mouse movement, we need javascript, or if the movement is automatic then we can do that with CSS only as well

Collapse
 
efpage profile image
Eckehard

So, is there any advantage of using CSS instead of using JS directly? I found that even modifying CSS through Javascript works amazingly well on most browsers.

Thread Thread
 
shubhamtiwari909 profile image
Shubham Tiwari

No just less javascript means less compilation for the code, better website performance, As the browser don't have to rely on javascript to function, as soon as the page loads on slow network even than the layout will be functional

Thread Thread
 
efpage profile image
Eckehard

Oh, this is just a fairy tale.

The latency associated with a single asset, especially a basic HTML page, may seem trivial. But websites generally involve multiple requests: the HTML includes requests for multiple CSS, scripts, and media files. The greater the number and size of these requests, the greater the impact of high latency on user experience. MDN: understanding latency

The thing is: all this happens, after your initial page was loaded.

Browsers are increadibly fast on decoding HTML, so decoding the page only takes just microseconds. Javascript is executed as soon as it is found in the source, so your scripts start running long before your page gets visible. Often you need to take care that a script does not acces the page before the DOM is fully established.

There is a difference between "building the DOM" and "displaing the page on screen" (-> rendering). The browser cannot start rendering the page, until all CSS is loaded. But is can run your scripts before your page is displayed.

Thread Thread
 
shubhamtiwari909 profile image
Shubham Tiwari

How about slow networks?
Their the download and execution time increases, that's why it is preferred to use CSS as much as possible for stylings and animation

Thread Thread
 
efpage profile image
Eckehard • Edited

Slow performance affects all ressources in the same way, regardless if it´s a CSS file or an ES6-module. See mozilla -> how browsers work

While the browser builds the DOM tree, this process occupies the main thread. As this happens, the preload scanner will parse through the content available and request high-priority resources like CSS, JavaScript, and web fonts. Thanks to the preload scanner, we don't have to wait until the parser finds a reference to an external resource to request it.

HTML files are read from top to bottom. Scripts located in the main HTML file are executed when they appear. So, they are usually running before CSS is loaded completely. Just the browser does not show the action, because he cannot show anything before CSS is ready.

Even on a slow network, you do not need to wait for Javascript. Thanks to the preload scanner, all external files, including CSS, are requested in parallel. What returns first is executed first. Even if the broswer needs to wait for the the React core to be loaded, a smaller script file can already be executed long before React is ready.

Bulky ressources may in fact slow down the page start. But if you include a bulky CSS file, just to save some bytes of Javascript, this might be a bad advice: If the script is loaded slowly, your animation will start a bit delayed. But if your CSS loads slowly, the user will see an empty or wrong formatted page.

Thread Thread
 
shubhamtiwari909 profile image
Shubham Tiwari

Actually in one of my task I have worked on, there is a book section with book imaged and details, we have created a logic with JS to randomly change the book details from 5 available books, On slow network, the section is empty for a second or two, so I created a default book section with static html and css to load it on slow network as well, then when the JS execution completes, randomly change the book, Sometimes JS stops interactivity for the elements, As my senior taught me to look after for all the edge cases, I try to minimise the code wherever possible