You may be wondering why on earth am I writing a tutorial about creating HAL 9000 with pure CSS. First of all, this tutorial shows you how advanced CSS has become and how you can use these techniques to your own advantage. HAL 9000 is a fictional character in Arthur C. Clarke’s Space Odyssey series.
Secondly, HAL 9000 can be a great notification button for web application. I can definitely see myself having a similar notification button on my app one day. With this tutorial you will learn the techniques used to create HAL 9000 from scratch with pure CSS. Without further ado, let’s head on and bring HAL 9000 to life.
[tut demo=”https://onextrapixel.com/examples/hal-9000-with-pure-css/” download=”https://onextrapixel.com/examples/hal-9000-with-pure-css/hal-9000-with-pure-css.zip”]
Manufacturing HAL 9000
Let’s start with the HAL 9000 body. I used a simple background gradient style to create a smooth body for HAL 9000. The tricky parts are the frame and the lens. I used a separate div for the frame instead of a border so that I can add a background gradient style to the frame to create depth. For lighting and shadows of the frame, I used a combination of layered box-shadow to create a believable surface for the frame.
For the lens, instead of creating it in one go with background gradients, I decided to create a separate div so that I can animate each one individually. I also ran into trouble when trying to animate HAL 9000 with one background gradient. Unfortunately, complex gradients and CSS transitions don’t play well together (yet) so to solve this I have to separate colors into multiple divs
.
You can see an example code below:
CSS
notification { background: #2D2A2B; background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#494852), to(#2A2A30)); background-image: -webkit-linear-gradient(#494852, #2A2A30); background-image: -moz-linear-gradient(#494852, #2A2A30); background-image: -o-linear-gradient(#494852, #2A2A30); background-image: linear-gradient(#494852, #2A2A30); box-shadow: inset 0 1px 0px rgba(255, 255, 225, 0.25),0 1px 2px rgba(0, 0, 0, 0.25); -moz-box-shadow: inset 0 1px 0px rgba(255,255,225,0.25),0 1px 2px rgba(0,0,0,0.25); -webkit-box-shadow: inset 0 1px 0px rgba(255, 255, 225, 0.25),0 1px 2px rgba(0, 0, 0, 0.25); border-radius: 15px; -moz-border-radius: 15px; -webkit-border-radius: 15px; border: 1px solid #231F20; width: 100px; height: 100px; } .metal { width: 70%; height: 70%; border-radius: 50px; -moz-border-radius: 50px; -webkit-border-radius: 50px; box-sizing: border-box; background: #417d9f; background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#43637c), to(#2c3c4b)); background-image: -webkit-linear-gradient(#43637c, #2c3c4b); background-image: -moz-linear-gradient(#43637c, #2c3c4b); background-image: -o-linear-gradient(#43637c, #2c3c4b); background-image: linear-gradient(#43637c, #2c3c4b); border-top: 2px solid #b8ccd7; margin: 15%; padding: 5px; box-shadow: 0 2px 0 #21262c, 0 4px 0 #232429, 0 6px 0 #040003, 0 0 20px #000, 0 5px 20px #000, 0 -2px 0 #6d93a6; -moz-box-shadow: 0 2px 0 #21262c, 0 4px 0 #232429, 0 6px 0 #040003, 0 0 20px #000, 0 5px 20px #000, 0 -2px 0 #6d93a6; -webkit-box-shadow: 0 2px 0 #21262c, 0 4px 0 #232429, 0 6px 0 #040003, 0 0 20px #000, 0 5px 20px #000, 0 -2px 0 #6d93a6); } .light { position: relative; border-radius: 50px; -moz-border-radius: 50px; -webkit-border-radius: 50px; width: 100%; height: 100%; box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; -moz-box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; -webkit-box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; background: #ffe913; background: #920000; background: -moz-radial-gradient(center, ellipse cover, #920000 39%, #2d0408 67%, #000000 71%); background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(39%,#920000), color-stop(67%,#2d0408), color-stop(71%,#000000)); background: -webkit-radial-gradient(center, ellipse cover, #920000 39%,#2d0408 67%,#000000 71%); background: -o-radial-gradient(center, ellipse cover, #920000 39%,#2d0408 67%,#000000 71%); background: -ms-radial-gradient(center, ellipse cover, #920000 39%,#2d0408 67%,#000000 71%); background: radial-gradient(ellipse at center, #920000 39%,#2d0408 67%,#000000 71%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#920000', endColorstr='#000000',GradientType=1 ); } .glowing-red { position: absolute; background: #F11A08; width: 45%; height: 45%; margin:28%; border-radius: 50px; -moz-border-radius: 50px; -webkit-border-radius: 50px; box-shadow: 0 0 15px #F11A08; -moz-box-shadow: 0 0 15px #F11A08; -webkit-box-shadow: 0 0 15px #F11A08; } .glowing-yellow { background: #FFE913; width: 50%; height: 50%; margin:24%; border-radius: 50px; -moz-border-radius: 50px; -webkit-border-radius: 50px; box-shadow: 0 0 5px #FFE913; -moz-box-shadow: 0 0 5px #FFE913; -webkit-box-shadow: 0 0 5px #FFE913; }
HTML
<div class="notification"> <div class="metal"> <div class="light"> <div class="glowing-red"> <div class="glowing-yellow"></div> </div> </div> </div> </div>
Bringing HAL 9000 to Life
Now we’ve manufactured HAL 9000, let’s bring it to life by adding some animations to it. Let’s begin by making the yellow and red parts of the lens glow. As you can see in the code below, I have defined 2 animation keyframes, blink-red and blink-yellow. These keyframes will determine how the animation will behave. I have each keyframe increase and decrease the size of the yellow and red parts of the lens to give HAL 9000 a glowing effect. I’ve also made the animation to run infinitely.
Since you might want to turn this into a notification button, I’ve made these animations to be triggered only if the main “notification” div has a class called “active” in it.
You can see the example code below:
CSS
.notification { background: #2D2A2B; background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#494852), to(#2A2A30)); background-image: -webkit-linear-gradient(#494852, #2A2A30); background-image: -moz-linear-gradient(#494852, #2A2A30); background-image: -o-linear-gradient(#494852, #2A2A30); background-image: linear-gradient(#494852, #2A2A30); box-shadow: inset 0 1px 0px rgba(255, 255, 225, 0.25),0 1px 2px rgba(0, 0, 0, 0.25); -moz-box-shadow: inset 0 1px 0px rgba(255,255,225,0.25),0 1px 2px rgba(0,0,0,0.25); -webkit-box-shadow: inset 0 1px 0px rgba(255, 255, 225, 0.25),0 1px 2px rgba(0, 0, 0, 0.25); border-radius: 15px; -moz-border-radius: 15px; -webkit-border-radius: 15px; border: 1px solid #231F20; width: 100px; height: 100px; } .metal { width: 70%; height: 70%; border-radius: 50px; -moz-border-radius: 50px; -webkit-border-radius: 50px; box-sizing: border-box; background: #417d9f; background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#43637c), to(#2c3c4b)); background-image: -webkit-linear-gradient(#43637c, #2c3c4b); background-image: -moz-linear-gradient(#43637c, #2c3c4b); background-image: -o-linear-gradient(#43637c, #2c3c4b); background-image: linear-gradient(#43637c, #2c3c4b); border-top: 2px solid #b8ccd7; margin: 15%; padding: 5px; box-shadow: 0 2px 0 #21262c, 0 4px 0 #232429, 0 6px 0 #040003, 0 0 20px #000, 0 5px 20px #000, 0 -2px 0 #6d93a6; -moz-box-shadow: 0 2px 0 #21262c, 0 4px 0 #232429, 0 6px 0 #040003, 0 0 20px #000, 0 5px 20px #000, 0 -2px 0 #6d93a6; -webkit-box-shadow: 0 2px 0 #21262c, 0 4px 0 #232429, 0 6px 0 #040003, 0 0 20px #000, 0 5px 20px #000, 0 -2px 0 #6d93a6; } .light { position: relative; border-radius: 50px; -moz-border-radius: 50px; -webkit-border-radius: 50px; width: 100%; height: 100%; box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; -moz-box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; -webkit-box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; background: #ffe913; background: #920000; /* Old browsers */ background: -moz-radial-gradient(center, ellipse cover, #920000 39%, #2d0408 67%, #000000 71%); /* FF3.6+ */ background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(39%,#920000), color-stop(67%,#2d0408), color-stop(71%,#000000)); /* Chrome,Safari4+ */ background: -webkit-radial-gradient(center, ellipse cover, #920000 39%,#2d0408 67%,#000000 71%); /* Chrome10+,Safari5.1+ */ background: -o-radial-gradient(center, ellipse cover, #920000 39%,#2d0408 67%,#000000 71%); /* Opera 12+ */ background: -ms-radial-gradient(center, ellipse cover, #920000 39%,#2d0408 67%,#000000 71%); /* IE10+ */ background: radial-gradient(ellipse at center, #920000 39%,#2d0408 67%,#000000 71%); /* W3C */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#920000', endColorstr='#000000',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */ } .glowing-red { position: absolute; background: #F11A08; width: 45%; height: 45%; margin:28%; border-radius: 50px; -moz-border-radius: 50px; -webkit-border-radius: 50px; box-shadow: 0 0 15px #F11A08; -moz-box-shadow: 0 0 15px #F11A08; -webkit-box-shadow: 0 0 15px #F11A08; } .glowing-yellow { background: #FFE913; width: 50%; height: 50%; margin:24%; border-radius: 50px; -moz-border-radius: 50px; -webkit-border-radius: 50px; box-shadow: 0 0 5px #FFE913; -moz-box-shadow: 0 0 5px #FFE913; -webkit-box-shadow: 0 0 5px #FFE913; } /* Defining Button Active State */ .notification.active .light{ /* Adding animation to Hal9000 */ animation: blink-red-shadow 2s infinite ease-in-out; -moz-animation: blink-red-shadow 2s infinite ease-in-out; -o-animation: blink-red-shadow 2s infinite ease-in-out; -webkit-animation: blink-red-shadow 2s infinite ease-in-out; } .notification.active .light .glowing-red{ /* Adding animation to Hal9000 */ animation: blink-red 2s infinite ease-in-out; -moz-animation: blink-red 2s infinite ease-in-out; -o-animation: blink-red 2s infinite ease-in-out; -webkit-animation: blink-red 2s infinite ease-in-out; } .notification.active .light .glowing-yellow{ /* Adding animation to Hal9000 */ animation: blink-yellow 2s infinite ease-in-out; -moz-animation: blink-yellow 2s infinite ease-in-out; -o-animation: blink-yellow 2s infinite ease-in-out; -webkit-animation: blink-yellow 2s infinite ease-in-out; } /* Defining Hal9000 blinking animation */ @-webkit-keyframes blink-red { from { box-shadow: 0 0 5px #F11A08; -moz-box-shadow: 0 0 5px #F11A08; -webkit-box-shadow: 0 0 5px #F11A08; width: 45%; height: 45%; } 50% { box-shadow: 0 0 25px #ff6b5f; -moz-box-shadow: 0 0 25px #ff6b5f; -webkit-box-shadow: 0 0 25px #ff6b5f; width: 70%; height: 70%; margin:17%; } to { box-shadow: 0 0 5px #F11A08; -moz-box-shadow: 0 0 5px #F11A08; -webkit-box-shadow: 0 0 5px #F11A08; width: 45%; height: 45%; } } @-webkit-keyframes blink-red-shadow { from { box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; -moz-box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; -webkit-box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; } 50% { box-shadow: inset 0 3px 0px #52352E, inset 0 5px 0 #312A25; -moz-box-shadow: inset 0 3px 0px #52352E, inset 0 5px 0 #312A25; -webkit-box-shadow: inset 0 3px 0px #52352E, inset 0 5px 0 #312A25; } to { box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; -moz-box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; -webkit-box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; } } @-webkit-keyframes blink-yellow { from { box-shadow: 0 0 5px #ffeb1c; -moz-box-shadow: 0 0 5px #ffeb1c; -webkit-box-shadow: 0 0 5px #ffeb1c; } 50% { box-shadow: 0 0 25px #fff; -moz-box-shadow: 0 0 25px #fff; -webkit-box-shadow: 0 0 25px #fff; } to { box-shadow: 0 0 5px #ffeb1c; -moz-box-shadow: 0 0 5px #ffeb1c; -webkit-box-shadow: 0 0 5px #ffeb1c; } }
HTML
<div class="notification active"> <div class="metal"> <div class="light"> <div class="glowing-red"> <div class="glowing-yellow"></div> </div> </div> </div> </div>
HAL 9000 Interaction
Now that our HAL 9000 is alive, let’s create some interactive animation. Let’s add a cool reflective animation when someone hovers over HAL 9000. In order to create a hover effect that resembles the reflection of lights on a shiny surface, I’ve added a new div called “hover-effect” to perform this effect.
You can see in the demo or from the code below that I exploited the transition of a border-width style by shrinking the border-width from 15 pixels to 0 to create a reflective-like animation.
You can see the code below:
CSS
.notification { background: #2D2A2B; background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#494852), to(#2A2A30)); background-image: -webkit-linear-gradient(#494852, #2A2A30); background-image: -moz-linear-gradient(#494852, #2A2A30); background-image: -o-linear-gradient(#494852, #2A2A30); background-image: linear-gradient(#494852, #2A2A30); box-shadow: inset 0 1px 0px rgba(255, 255, 225, 0.25),0 1px 2px rgba(0, 0, 0, 0.25); -moz-box-shadow: inset 0 1px 0px rgba(255,255,225,0.25),0 1px 2px rgba(0,0,0,0.25); -webkit-box-shadow: inset 0 1px 0px rgba(255, 255, 225, 0.25),0 1px 2px rgba(0, 0, 0, 0.25); border-radius: 15px; -moz-border-radius: 15px; -webkit-border-radius: 15px; border: 1px solid #231F20; width: 100px; height: 100px; position: relative; } .metal { width: 70%; height: 70%; margin: 15%; border-radius: 50px; -moz-border-radius: 50px; -webkit-border-radius: 50px; box-sizing: border-box; background: #417d9f; background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#43637c), to(#2c3c4b)); background-image: -webkit-linear-gradient(#43637c, #2c3c4b); background-image: -moz-linear-gradient(#43637c, #2c3c4b); background-image: -o-linear-gradient(#43637c, #2c3c4b); background-image: linear-gradient(#43637c, #2c3c4b); border-top: 2px solid #b8ccd7; padding: 5px; box-shadow: 0 2px 0 #21262c, 0 4px 0 #232429, 0 6px 0 #040003, 0 0 20px #000, 0 5px 20px #000, 0 -2px 0 #6d93a6; -moz-box-shadow: 0 2px 0 #21262c, 0 4px 0 #232429, 0 6px 0 #040003, 0 0 20px #000, 0 5px 20px #000, 0 -2px 0 #6d93a6; -webkit-box-shadow: 0 2px 0 #21262c, 0 4px 0 #232429, 0 6px 0 #040003, 0 0 20px #000, 0 5px 20px #000, 0 -2px 0 #6d93a6; } .light { position: relative; border-radius: 50px; -moz-border-radius: 50px; -webkit-border-radius: 50px; width: 100%; height: 100%; box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; -moz-box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; -webkit-box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; background: #ffe913; background: #920000; /* Old browsers */ background: -moz-radial-gradient(center, ellipse cover, #920000 39%, #2d0408 67%, #000000 71%); /* FF3.6+ */ background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(39%,#920000), color-stop(67%,#2d0408), color-stop(71%,#000000)); /* Chrome,Safari4+ */ background: -webkit-radial-gradient(center, ellipse cover, #920000 39%,#2d0408 67%,#000000 71%); /* Chrome10+,Safari5.1+ */ background: -o-radial-gradient(center, ellipse cover, #920000 39%,#2d0408 67%,#000000 71%); /* Opera 12+ */ background: -ms-radial-gradient(center, ellipse cover, #920000 39%,#2d0408 67%,#000000 71%); /* IE10+ */ background: radial-gradient(ellipse at center, #920000 39%,#2d0408 67%,#000000 71%); /* W3C */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#920000', endColorstr='#000000',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */ } .glowing-red { position: absolute; background: #F11A08; width: 45%; height: 45%; margin:28%; border-radius: 50px; -moz-border-radius: 50px; -webkit-border-radius: 50px; box-shadow: 0 0 15px #F11A08; -moz-box-shadow: 0 0 15px #F11A08; -webkit-box-shadow: 0 0 15px #F11A08; } .glowing-yellow { background: #FFE913; width: 50%; height: 50%; margin:24%; border-radius: 50px; -moz-border-radius: 50px; -webkit-border-radius: 50px; box-shadow: 0 0 5px #FFE913; -moz-box-shadow: 0 0 5px #FFE913; -webkit-box-shadow: 0 0 5px #FFE913; } /* Defining Button Active State */ .notification.active .light{ /* Adding animation to Hal9000 */ animation: blink-red-shadow 2s infinite ease-in-out; -moz-animation: blink-red-shadow 2s infinite ease-in-out; -o-animation: blink-red-shadow 2s infinite ease-in-out; -webkit-animation: blink-red-shadow 2s infinite ease-in-out; } .notification.active .light .glowing-red{ /* Adding animation to Hal9000 */ animation: blink-red 2s infinite ease-in-out; -moz-animation: blink-red 2s infinite ease-in-out; -o-animation: blink-red 2s infinite ease-in-out; -webkit-animation: blink-red 2s infinite ease-in-out; } .notification.active .light .glowing-yellow{ /* Adding animation to Hal9000 */ animation: blink-yellow 2s infinite ease-in-out; -moz-animation: blink-yellow 2s infinite ease-in-out; -o-animation: blink-yellow 2s infinite ease-in-out; -webkit-animation: blink-yellow 2s infinite ease-in-out; } /* Defining Hal9000 blinking animation */ @-webkit-keyframes blink-red { from { box-shadow: 0 0 5px #F11A08; -moz-box-shadow: 0 0 5px #F11A08; -webkit-box-shadow: 0 0 5px #F11A08; width: 45%; height: 45%; } 50% { box-shadow: 0 0 25px #ff6b5f; -moz-box-shadow: 0 0 25px #ff6b5f; -webkit-box-shadow: 0 0 25px #ff6b5f; width: 70%; height: 70%; margin:17%; } to { box-shadow: 0 0 5px #F11A08; -moz-box-shadow: 0 0 5px #F11A08; -webkit-box-shadow: 0 0 5px #F11A08; width: 45%; height: 45%; } } @-webkit-keyframes blink-red-shadow { from { box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; -moz-box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; -webkit-box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; } 50% { box-shadow: inset 0 3px 0px #52352E, inset 0 5px 0 #312A25; -moz-box-shadow: inset 0 3px 0px #52352E, inset 0 5px 0 #312A25; -webkit-box-shadow: inset 0 3px 0px #52352E, inset 0 5px 0 #312A25; } to { box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; -moz-box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; -webkit-box-shadow: inset 0 3px 0px #2e4452, inset 0 5px 0 #392c33; } } @-webkit-keyframes blink-yellow { from { box-shadow: 0 0 5px #ffeb1c; -moz-box-shadow: 0 0 5px #ffeb1c; -webkit-box-shadow: 0 0 5px #ffeb1c; } 50% { box-shadow: 0 0 25px #fff; -moz-box-shadow: 0 0 25px #fff; -webkit-box-shadow: 0 0 25px #fff; } to { box-shadow: 0 0 5px #ffeb1c; -moz-box-shadow: 0 0 5px #ffeb1c; -webkit-box-shadow: 0 0 5px #ffeb1c; } } /* Interactive Effect on Hover */ .notification.active { cursor: pointer; } .notification.active .hover-effect { -webkit-transition-duration:0.5s; -moz-transition-duration:0.5s; -ms-transition-duration:0.5s; -o-transition-duration:0.5s; transition-duration:0.5s; border-radius: 50px; -moz-border-radius: 50px; -webkit-border-radius: 50px; box-sizing: border-box; border:15px solid rgba(184, 204, 215, 0); width: 100%; height: 100%; position: absolute; top: 0; left: 0; } .notification:hover .hover-effect { border-radius: 15px; -moz-border-radius: 15px; -webkit-border-radius: 15px; border:0 solid rgba(184, 204, 215, 0.5) }
HTML
<div class="notification active"> <div class="hover-effect"></div> <div class="metal"> <div class="light"> <div class="glowing-red"> <div class="glowing-yellow"></div> </div> </div> </div>
[tut demo=”https://onextrapixel.com/examples/hal-9000-with-pure-css/” download=”https://onextrapixel.com/examples/hal-9000-with-pure-css/hal-9000-with-pure-css.zip”]
Conclusion
That’s it, you’ve built yourself an artificial intelligence for your website. With the combination of reflective animation and a glowing effect, HAL 9000 would make a hell of an awesome notification button for web apps. I hope you guys enjoyed this tutorial as much as I did.
Let me know what you think about this tutorial in the comments below.