Last week, we started Code Challenge #3. The goal was to build these CSS Lightsabers:
Let's take a look at the solution and build these with pure CSS. After we're all done, we'll add in some JavaScript to add the lightsaber sounds for when we click the lightsaber.
Table of Contents
Video!
For those that like videos, we're starting to put our more video content. Check out our YouTube channel
The HTML
We'll start with the HTML for just one of the lightsabers. This will be fairly simple and will use some BEM Classes.
<div class="lightsaber">
<label>Yoda</label>
<input type="checkbox" checked>
</div>
That will be the base for our lightsaber. We also want to make sure that we can check/uncheck the checkbox
when we click the label
. To do this, HTML let's us add a for
attribute to the label
and an id
to the checkbox
:
<div class="lightsaber">
<label for="yoda">Yoda</label>
<input id="yoda" type="checkbox" checked>
</div>
Now when we click on the label, this will check and uncheck the checkbox.
The Technique
The technique we'll use here is a simple one. This is the technique used when you see all the styled out radio and checkboxes across the web. We're going to style the label
as our lightsaber and we'll hide the checkbox
.
Hide the checkbox. Use the label to toggle the checkbox.
Since we are able to use the label
to toggle our checkbox, we don't actually need the checkbox
itself. Checkboxes are harder to style out anyway since they come with their own set of base styles per browser.
Adding a Container for the Saber
We'll style the label
as the hilt of our lightsaber and we'll add another div to house the actual plasma/colored part.
<div class="lightsaber">
<label for="yoda">Yoda</label>
<input id="yoda" type="checkbox" checked>
<div class="plasma"></div>
</div>
We'll also add a class to this lightsaber so that we know its the Yoda version:
<div class="lightsaber lightsaber--yoda">
<label for="yoda">Yoda</label>
<input id="yoda" type="checkbox" checked>
<div class="plasma"></div>
</div>
IMAGE HERE
The BEM style of classes let us know with the double dashes that this is a modifier to the main .lightsaber
class. Our lightsaber looks nothing like a lightsaber just yet. The next bit of magic will happen in the CSS.
The CSS
Now that our HTML is ready, let's move on to the CSS part. We'll set some base styles for the hilt/label first:
/* make sure that all things are positioned relative to the parent lightsaber */
.lightsaber {
position: relative;
}
.lightsaber label {
position: absolute;
width: 15px;
height: 50px;
background: #DDD;
}
This next part is optional but adds that extra bit of depth to our lightsaber hilt. We'll use a CSS gradient for our hilt:
.lightsaber label {
position: absolute;
width: 15px;
height: 50px;
background: #DDD;
/* gradient goes here */
}
Hiding the Checkbox
We don't need to the checkbox to be visually available. We'll hide it using the opacity
:
.lightsaber input[type="checkbox"] {
opacity: 0;
}
Styling the Plasma
We have our .plasma
div that we need to style next. This is the piece that we will show and hide when the checkbox is toggled. This will be the green glowing part for our Yoda saber. Since we already have our HTML checkbox set to the checked
state, we'll style it as if it was on already.
.lightsaber .plasma {
transition: height 0.3s;
position: absolute;
width: 10px;
height: 0;
filter: blur(1px); /* neat css trick to get that glow */
}
Notice that we have added a transition
to the height. This is what will get transitioned from 0 height to full height. That's how we get the lightsaber opening and closing effect.
The Yoda Styling
We want this saber to be for Yoda and we have a class specifically for that purpose. We'll use that to style the green saber.
.lightsaber--yoda .plasma {
background: rgb(135, 220, 90);
background: linear-gradient(
to right,
rgb(135, 220, 90) 0%,
rgb(254, 254, 254) 30%,
rgb(254, 254, 254) 50%,
rgb(254, 254, 254) 70%,
rgb(135, 220, 90) 100%
);
}
.lightsaber--vader .plasma {
background: rgb(229, 17, 21);
background: linear-gradient(
to right,
rgba(229, 17, 21, 1) 0%,
rgba(254, 254, 254, 1) 30%,
rgba(254, 254, 254, 1) 47%,
rgba(254, 254, 254, 1) 71%,
rgba(229, 17, 21, 1) 100%
);
}
.lightsaber--windu .plasma {
background: rgb(202, 116, 221);
background: linear-gradient(
to right,
rgba(202,116,221,1) 0%,
rgba(254,254,254,1) 30%,
rgba(254,254,254,1) 47%,
rgba(254,254,254,1) 71%,
rgba(202,116,221,1) 100%
);
}
I've also added the styles for both vader and windu in there.
Toggling the Checkbox On or Off
Based on the state of the checkbox, we'll set the height of the plasma. This is how we can set height from 0px
to 50px
of the .plasma
:
.lightsaber input[type="checkbox"]:checked ~ .plasma {
height: 55px;
}
We will check if the checkbox is checked
using the checked psuedo class and then set the sibling .plasma
to full height!
Bonus: Adding Sound on Click
As a bonus, we can bring in some JavaScript to play a sound whenever this saber is opened/closed. The gist of what we will do is:
- create an
<audio>
element - set the
src
of that to our lightsaber sound file: FILE HERE - play the audio file
// grab the checkbox
const lightsaber = document.querySelector('.lightsaber input[type="checkbox"]');
lightsaber.addEventListener('change', playWhoosh);
function playWhoosh(e) {
// first check to see if this checkbox is on or off
const isOn = e.target.checked;
if (isOn) {
const whooshSound = document.createElement('audio');
whooshSound.src = 'https://scotch.io/audio/lightsaber.wav';
whooshSound.play();
}
}
Now we have this cool whoosh sound!
Conclusion
That ends the Code Challenge for this week. Hope you found that helpful and got some CSS techniques out of it. Until next week!
Like this article? Follow @chrisoncode on Twitter