Swinging Robot using HTML and CSS Only

Share your love

What if you could craft a charming robot and set it swinging joyfully—all with pure HTML and CSS? In this blog, we’ll guide you through building a playful swinging robot using CSS keyframes and 3D transforms. From designing the robot’s quirky head, arms, and legs to adding a smooth swinging animation, we’ll create a dynamic character that feels alive on the screen. This project is perfect for sharpening your animation skills while having fun with creative design. Let’s bring this robotic friend to life and set it in motion!

I would recommend you don’t just copy and paste the code, just look at the code and type by understanding it.

Demo

See the Pen A swinging robot (CSS only) by Amit Sheen (@amit_sheen) on CodePen.

HTML Code 

Starter Template

<!doctype html>
<html lang="en">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSS -->
    <link rel="stylesheet" href="style.css">

    <title>Coding Torque</title>
</head>

<body>
    <!-- Further code here -->

</body>

</html>

Paste the below code in your <body> tag.

<div class="scene">
  <div class="floor">
    <div class="shadow"></div>
  </div>
  <div class="swing">
    <div class="structure">
      <div class="top">
        <i></i><i></i><i></i><i></i><i></i><i></i>
      </div>
      <div class="legs">
        <div>
          <i></i><i></i><i></i><i></i><i></i><i></i>
        </div>
        <div>
          <i></i><i></i><i></i><i></i><i></i><i></i>
        </div>
      </div>
      <div class="legs">
        <div>
          <i></i><i></i><i></i><i></i><i></i><i></i>
        </div>
        <div>
          <i></i><i></i><i></i><i></i><i></i><i></i>
        </div>
      </div>
    </div>
    <div class="moving">
      <div class="line"></div>
      <div class="line"></div>
      <div class="seat">
        <i></i><i></i><i></i><i></i><i></i><i></i>
      </div>
      
      <div class="robot">
        <div class="thigh">
          <i></i><i></i><i></i><i></i><i></i><i></i>
          <div class="calf">
            <i></i><i></i><i></i><i></i><i></i><i></i>
            <div class="foot">
              <i></i><i></i><i></i><i></i><i></i><i></i>
            </div>
          </div>
        </div>
        <div class="thigh">
          <i></i><i></i><i></i><i></i><i></i><i></i>
          <div class="calf">
            <i></i><i></i><i></i><i></i><i></i><i></i>
            <div class="foot">
              <i></i><i></i><i></i><i></i><i></i><i></i>
            </div>
          </div>
        </div>
        
        <div class="thorax">
          <i></i><i></i><i></i><i></i><i></i><i></i>
          <div class="neck">
            <i></i><i></i><i></i><i></i><i></i><i></i>
            <div class="head">
              <i></i><i></i><i></i><i></i><i></i><i></i>
            </div>
          </div>
          <div class="arm">
            <i></i><i></i><i></i><i></i><i></i><i></i>
            <div class="hand">
              <i></i><i></i><i></i><i></i><i></i><i></i>
            </div>
          </div>
          <div class="arm">
            <i></i><i></i><i></i><i></i><i></i><i></i>
            <div class="hand">
              <i></i><i></i><i></i><i></i><i></i><i></i>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

CSS Code 

Create a file style.css and paste the code below.

*, *::before, *::after {
    padding: 0;
    margin: 0 auto;
    box-sizing: border-box;
}

body {
  background-color: #000;
  color: #fff;
  min-height: 100vh;
  display: grid;
  place-items: center;
  perspective: 800px;
  overflow: hidden;
  
  * {
    transform-style: preserve-3d;
  }
  
  --duration: 2s;
  --delay: -3s;
}

.scene {
  position: relative;
  animation: scene 48s -28s infinite linear;

  * {
    position: absolute;
  }
}

@keyframes scene {
  to { rotate: y 1turn; }  
}

.floor {
  inset: -100em;
  background-color: #333;
  background-image:
    radial-gradient(closest-side, transparent, #000),
    radial-gradient(circle at 46.3% 44.6%, #0006, transparent 2em),
    radial-gradient(circle at 53.7% 44.6%, #0006, transparent 2em),
    radial-gradient(circle at 53.7% 55.4%, #0006, transparent 2em),
    radial-gradient(circle at 46.3% 55.4%, #0006, transparent 2em),
    repeating-linear-gradient(#0003 0, #0000, #0003 1em),
    repeating-linear-gradient(90deg, #0003 0, #0000, #0003 1em);
  transform: translateY(16em) rotateX(90deg);
  
  .shadow {
    inset: 90em;
    background-image: radial-gradient(closest-side, #0003, 75%, transparent);
    animation:
      shadowMove var(--duration) infinite ease-in-out alternate,
      shadowOpacity calc(var(--duration) * 0.5) infinite ease-in-out alternate;
  }
}

@keyframes shadowMove {
  from { translate: -15em; }
  to { translate: 15em; }
}

@keyframes shadowOpacity {
  from { opacity: 0.5; scale: 2; }
  to { opacity: 1; scale: 1; }
}

.swing {
  position: absolute;
  translate: 0 -12em;
}

.structure {
    left: -0.5em; top: -1.2em;
    --color: brown;
  
  .top {
    rotate: 45deg;

    --width: 1em;
    --height: 1em;
    --depth: 24em;    
  }
  
  .legs {
    translate: 0 1em var(--tz, 11em);
    
    div {
      transform-origin: top;
      rotate: var(--rz, 15deg);
      
      --width: 1em;
      --height: 30em;
      --depth: 1em;
      
      &:nth-child(2) { --rz: -15deg; }
    }
    &:nth-child(2) { --tz: -11em; }
  }

}

.moving {
  animation: swing var(--duration) infinite ease-in-out alternate;
  
  .line {
    left: -0.1em; top: 0;
    width: 0.2em; height: 20em;
    background-image: linear-gradient(90deg, #fff, #777, #fff);
    transform: translateZ(var(--tz, 4em));
    
    &:nth-child(2) {
      --tz: -4em;
    }
    
    &::after {
      content: '';
      position: absolute;
      inset: 0;
      rotate: y 90deg;
      background: inherit;
    }
  }
  
  .seat {
    left: -2em; top: 20em;
    
    --width: 4em;
    --height: 1em;
    --depth: 10em;
    --color: brown;
  }
}

@keyframes swing {
  from { rotate: 45deg; }
  to { rotate: -45deg; }
}

.robot {
  translate: -1.5em 19.5em;
  
  .thigh {
    left: 0.5em; top: -0.5em;
    transform: translateZ(var(--tz, 1em)) rotateY(var(--ry, -10deg));

    --width: 5em;
    --height: 1em;
    --depth: 1em;
    
    &:nth-child(2) { --tz: -1em; --ry: 10deg; }
  }
  
  .calf {
    left: 100%; top: 0;
    width: 4em; height: 1em;
    transform-origin: top left;
    animation: calf var(--duration) var(--delay) infinite ease-in-out alternate;
    
    --width: 4em;
    --height: 1em;
    --depth: 1em;
  }

  .foot {
    left: 100%; top: 0;
    transform-origin: bottom left;
    animation: foot var(--duration) var(--delay) infinite ease-in-out alternate;

    --width: 2em;
    --height: 1em;
    --depth: 1em;
  }
  
  .thorax {
    left: -0em; bottom: -0.5em;
    transform-origin: bottom left;
    animation: thorax var(--duration) var(--delay) infinite ease-in-out alternate;
    
    --width: 2em;
    --height: 6em;
    --depth: 4em;
  }
  
  .neck {
    left: 0.5em; top: -1.5em;
    transform-origin: bottom;
    animation: head var(--duration) var(--delay) infinite ease-in-out alternate;
      
    --width: 1em;
    --height: 2em;
    --depth: 1em;
  }
  
  .head {
    left: -0.5em; top: -2.5em;
    transform-origin: bottom;
    animation: head var(--duration) var(--delay) infinite ease-in-out alternate;
      
    --width: 2em;
    --height: 3em;
    --depth: 2em;
  }
  
  .arm {
    left: 0.5em; top: 1em;
    transform-origin: 50% 50% calc(var(--lr, 1) * -1.5em);
    animation: arm var(--duration) var(--delay) infinite ease-in-out alternate;

    --width: 1em;
    --height: 1em;
    --depth: 4em;
    
    &:nth-child(9) { --lr: -1; }
  }
  .hand {
    left: 0; top: 0;
    transform-origin: 0% 50% calc(var(--lr, 1) * -1.5em);
    animation: hand var(--duration) var(--delay) infinite ease-in-out alternate;
   
    --width: 1em;
    --height: 1em;
    --depth: 3em;
  }
}

@keyframes calf {
  0% { rotate: 5deg; }
  100% { rotate: 85deg; }
}
@keyframes foot {
  0%, 30% { rotate: -45deg; }
  70%, 100% { rotate: -25deg; }
}
@keyframes thorax {
  0%, 20% { translate: 0.5em -0em; rotate: -60deg; }
  80%, 100% { translate: -0em 0em; rotate: 15deg; }
}
@keyframes head {
  0% { rotate: -5deg; }
  100% { rotate: 10deg; }
}
@keyframes arm {
  0%, 20% { transform: translateZ(calc(var(--lr, 1) * 3em)) rotateX(calc(var(--lr, 1) * -40deg)) rotateY(calc(var(--lr, 1) * 20deg)); }
  80%, 100% { transform: translateZ(calc(var(--lr, 1) * 3em)) rotateX(0deg) rotateY(calc(var(--lr, 1) * -60deg)); }
}
@keyframes hand {
  0%, 20% { transform: translateZ(calc(var(--lr, 1) * 3.5em)) rotateY(calc(var(--lr, 1) * 60deg)) rotateZ(40deg); }
  80%, 100% { transform: translateZ(calc(var(--lr, 1) * 3.5em)) rotateY(calc(var(--lr, 1) * 120deg)) rotateX(0deg); }
}

/* boxes */
*:has(> i) {
  width: var(--width);
  height: var(--height);
  
  i {
    left: 50%; top: 50%;
    background-color: var(--color, #fff);
    box-shadow: 0 0 1em #000 inset;

    &:nth-child(1) {
      inset: 0;
      transform: translateZ(calc(var(--depth) * 0.5));
    }
    &:nth-child(2) {
      width: var(--depth); height: 100%;
      transform: translate(-50%, -50%) rotateY(90deg) translateZ(calc(var(--width) * 0.5));
    }
    &:nth-child(3) {
      inset: 0;
      transform: rotateY(180deg) translateZ(calc(var(--depth) * 0.5));
    }
    &:nth-child(4) {
      width: var(--depth); height: 100%;
      transform: translate(-50%, -50%) rotateY(270deg) translateZ(calc(var(--width) * 0.5));
    }
    &:nth-child(5) {
      width: var(--width); height: var(--depth);
      transform: translate(-50%, -50%) rotateX(90deg) translateZ(calc(var(--height) * 0.5));
    }
    &:nth-child(6) {
      width: var(--width); height: var(--depth);
      transform: translate(-50%, -50%) rotateX(270deg) translateZ(calc(var(--height) * 0.5));
    }
  }
}

Final Output

Written by: Piyush Patil

Code Credits: https://codepen.io/amit_sheen/pen/QWXOYvz

If you found any mistakes or have any doubts please feel free to Contact Us

Hope you find this post helpful💖

Share your love

Leave a Reply

Your email address will not be published. Required fields are marked *