A Breakdown of the SNES Controller Built With CSS & HTML

Posted on:

About a month ago, I finished up my first WordPress theme, where it continues to go through the extensive manual review process with the folks at WordPress.org. I am big on building personal habits, and one of my habits is to write a minimum of 20 lines of code a day. The language doesn't matter, so long as I'm writing something. Now that I'm finished with that theme, I'm stuck with nothing to write, and that puts my habit in danger. For this, CodePen is great, because it provides you with an easy place to create code for the sake of coding, not because you're trying to make some sort of product, or anything else. You get to code because you want to code, and you can make anything that you damn well please. I didn't particularly want to start another WordPress theme until the first one is out, stable, and running, so I went ahead and jumped on CodePen and began to make an SNES controller with the help of my new found best friend, SCSS.

A Codepen...pen showing the completed controller can be found here.

For the sake of keeping this article at a reasonable length, I tried to talk about the thinking behind the elements in the code, and avoid getting too deep into a line-by-line description of what I did. I skip entire sections of the code, and focus on the parts that I feel are most-important.

The Dimensions

I come from a background in engineering, and did a lot of top-down 3D modeling in SolidWorks in my not-too-distant past. As it turns out, SCSS creates functionality that is very similar to how that method of 3D modeling works. If you take the time to build a solid foundation, with the right references, the rest of the model (or in this case, code) will come easy. I took time to create variables that would be easy to call on at a later time. Most-notably, the $controller-side-diameter variable is used in the left and right-side elements a lot. It helped center the gamepad, the circle around the gamepad, the R and L buttons, and the center reference point for the buttons to rotate around.

The Body

The body was straightforward to build: 3 elements, sized, colored, and rounded with a side of a float:left. Most of my time was spent on proportions at this point. I knew that it would be a pain to adjust the size of the controller after the fact, so I put a lot of time getting this right the first time.

The D-Pad

The D-Pad (or dpad, depending on what day of the week I was writing the code) was positioned with the help of the $controller-side-diameter variable, so if I did need to change the size of the controller, it would update the center point for the dpad, too.

D-Pad Arrows

I was very pleased with my solution for the arrows on this controller, because they ended up using a super-simple mixin that basically rotated and positioned each arrow in the correct place. All four arrows are actually made the exact same way, the only difference is that they are rotated. I found this to be a lot easier than trying to battle with the border property in 4 different ways. I'd explain how the triangle works, but I think Chris has that covered quite well. The only difference for me, was I added a tiny bit of width to the arrows so I could add a radius to the corners.

The ABXY Buttons

The positioning for the ABYX buttons used the same process for placement as the D-Pad arrows; a <ul> and four <li> tags, one for each button. The only difference, is that the <ul>'s height and width actually determined the position of the buttons. I set a width and height equal to the $controller-side-offset - 50px and used percentages on the <li> tags to place the buttons in-place, relative to the dimensions put into the <ul> tag. It sounds a little tricky in-text, but take a look and I think it'll make sense. The magic of this is it essentially puts all of the positioning of the buttons inside of a single width: and height: attribute in an easy to change place. Since the <ul> tag is centered on the right-side circle, the width: and height: changes will move the buttons closer-to, or further-from the center of the controller. That made adjusting the proportions of the buttons very easy to get right. I knew the underlay element would not be easy to dynamically move with the buttons (in fact, I didn't even try) so I made a point to get the proportions right before I added that element. This comes back to that strong foundation that I mentioned earlier.

R and L button arc

I dreaded this part, because I didn't have any idea on how I was going to make the arc on the buttons. I was plesantly surprised to find that it was easy to do with some fancy...gradient-ing. css gradient(235deg,$controller-body 0%, $controller-body 47%,#666 50%,#666 50%,transparent 50%); The key with this is the 235 deg angle and the transparent 50% at the end, because that makes the last half of the circle transparent, but keeps the rest of the arc visible. Those little arcs on the controller are actually half-circles, but the rest of the arc is hidden under the controller, so you don't see it.

Gradients, and Color

Mastering the gradient is what added the realistic punch to the controller, but I waited to do this after I was completely happy with everything else. Each layer of detail you add is another layer of complexity to the code, which makes it harder to edit. One of my most-used Chrome extensions is ColorZilla. It helps me extract colors from elements and images in my web browser quickly. To get the colors of the controller, I did a Google search for an SNES controller, and used ColorZilla to extract the colors I used for my base. I applied all of my base colors as variables in SCSS, which makes it a lot easier to adjust the color later-on if I need to.

I had a blast with this, and I can't wait to make more!