So, I recently made this pen.

I'm really happy with it. I realized, though, that people who aren't well acquainted with flexbox would be very confused by the CSS.

So here's a step by step breakdown of the proccess and what I did to make this keyboard.


I used Haml for the HTML so forgive me if you can't read it. Here's a simplified (non-Haml) version:

As you can see, it doesn't really look very much like a keyboard at the moment. That's because (obviously) we haven't given it any CSS yet!

But let's not rush in to CSS yet, let's start by breaking down the HTML.

First off, we have a div #keyboard.

  <div id="keyboard">

The purpose of this div is (I hope) pretty obvious from its ID. It contains the whole keyboard in it.

Inside of #keyboard we have 4 .rows.

  <div class="row">

Again, I hope the class makes their purpose obvious. They each contain 1 row of keys.

Inside of each row there are a few .keys.

  <div id="..." class="key">...</div>

Each key's ID corresponds to which key it is, so the A key would have the ID "a". Each key contains the word representing it, so the #esc key contains the word "esc".

Some of the keys are also .small and I'll explain what that class is for when we come to it in the CSS.

Okay! Now that we've broken down the HTML we can move on to the next step.


Now that we have our keyboard HTML structure, how do we make it look like a proper keyboard? Why, with CSS of course!

Okay, wow, that's a decent amount of CSS to take in. Let's walk through it one style rule at a time.

  #keyboard {
    font-size: 5vh;

Here we set the font-size to 5vh. We'll use vh for everything in order to allow us to scale the keyboard to any screen size.

  #keyboard .row {
    display: flex;
    height: 20vh;
    line-height: 16vh;
    text-align: center;

Here we use display: flex; to make each .row a flexbox.

We set the height to 20vh so that each .row is 1/5 the screen height.

We use line-height and text-align in order to center the text in the middle of each key.

  #keyboard .row:first-child {
    height: 10vh;
    line-height: 4vh;

Here we use the :first-child pseudo-selector to modify the first .row.

We half to height so that "esc" and the "F keys" are half the height as the rest. We also have to adjust line-height to make sure things still stay centered.

  #keyboard .row .key {
    width: 100%;
    background: #111;
    margin: 0.5vh;
    padding: 2vh;

We try to set every .key to 100% of the width of its parent. In a regular div this would do exactly that and stack the .keys vertically. This is no regular div, however, each .row is a flexbox. Instead of stacking, the .keys will all be shrunk down until they all fit horizontally.

We set a nice dark background on the .keys to distinguish them from the body.

We give each .key a margin to make a space between keys. We also add a padding to make sure the letters inside of them don't ever touch the edges of the key. (This is especially important for a later style)

  #keyboard .row .key#space {
    width: 400%;
#keyboard .row .key#backspace {
    width: 160%;
#keyboard .row .key#tab {
    width: 120%;

Here we target various keys that need to be wider than the rest and increase their width. This will result in a proportional increase in width even after the flexbox shrinks them. This is the most important part, and you can spend as long as you want fine tuning these.

When making Keyboard Debugger I used this image from Wikipedia as a reference.

Image of Keyboard Layout

  #keyboard .row .key.small {
    font-size: 75%;
    text-align: left;
    line-height: 27.5vh;

.keys that are .small should have a smaller font and have their words in the lower left. In order to do that we lower the font-size to 75%, remove the centering with text-align: left;, and adjust the line-height to place the text at the bottom rather than the middle.

  #keyboard .row:first-child .key.small {
    line-height: 7.5vh;

Remember now, the first .row is half the height, so we adjust the line-height to place those at the bottom as well. If we hadn't adjusted the line-height then the text from .small.keys in the first .row would be floating below them.

Only two more style rules to go, we're almost there!

  html, body {
  width: 100%;
  height: 100%;
body {
    margin: 0;
    color: #fff;
    background: #222;

These rules are used to set the font color to white, the background to dark grey, and to make body cover the whole screen.

We did it!

That's it. We now have a keyboard layout assembled with CSS flexbox. All the other styles on Keyboard Debugger are entirely stylistic and make no layout changes.

Learn More

Links to check out:

2,522 0 26