I'm certainly not an expert web developer/designer, so I get excited when I discover tools that make my life easier. At the moment, I'm excited about CSS grid. I have known about CSS grid for awhile, but I just now encountered a project that gave me a real idea as to why CSS grid is so great. I'd like to share a little bit about this experience.
I do online math curriculum development (and teach math) for a living, but I recently started doing freelance web development work (because I really enjoy learning about web dev.). I started working on a project for a client, that consists of creating web-based typing lessons. Part of the requirement was to create a non-interactive on-screen keyboard where the keys light up on keystroke.
This was going to be an interesting task, because the layout of keyboards is not very "rectangular," in the sense that keys are offset and some keys are wider or taller than others. Here's what I ended up with:
I noticed that 15 "normal sized" keys fit on a single row of the keyboard, but some rows contain a mixture of "wider" keys and "normal" keys. To handle this, I ended up splitting the keyboard container (the QWERTY keyboard, left side of image above) into
15*4 + 14 = 74 tiny little columns. Each "normal" key spans 4 of these columns, each gap between keys spans 1 column, and the wider keys span a variety of columns. Each row of the keyboard spans just 1 row, whose height is 4 times as large as the width of each column. This is shown here:
To do this, I had a grid container
div#qwerty_container to place all of the keys, and then all of the keys are direct children of this container. The CSS (I'm using SASS) for this container is as follows:
$key_size: 32px #qwerty_container display: grid grid-template-columns: repeat(74, $key_size/4) grid-template-rows: repeat(5, $key_size) grid-column-gap: 0px grid-row-gap: $key_size/4
display: grid indicates that this element has a grid layout. The
grid-template-columns indicates the size of the columns, and I used the CSS
repeat() function to save myself a lot of typing. Similarly, the
grid-template-rows indicates the size of the rows.
Then, each child of this container is applied a class prefixed by
.g- to indicate how many columns it should span. As an example, a normal key would have the class
.g-4 and this class contains the following:
.g-4 grid-column: auto / span 4
That's about all it takes! The
grid-column: auto / span 4 indicates that this class shouldn't affect the starting column of the element, but the element should span 4 columns. I had my list of keys in a JS array, along with how many columns they should span, and then looped through this array and output the grid elements using Vue.JS. Pretty clean!
I'm not a CSS expert, but I think this could have been done using Flexbox, because I didn't really do anything "vertical" in nature. However, the number pad on the right side (see the first image) has keys that span multiple rows. Now, this is a place for the grid to really shine! I created the number pad in essentially the same way as the QWERTY keyboard. This is what the grid looks like for the number pad:
However, the Plus and Enter keys both span two rows. Two handle that, I merely added an id to both of those keys and added a mere three extra lines of CSS for each of those keys. For example, say the Plus key has an id of
numpad_plus. Then we could add the following to our SASS file:
#numpad_plus grid-row: auto / span 2 height: 100% justify-content: center
In this case, the
grid-row: auto / span 2 indicates that this key should start at its "normal row," e.g. we aren't changing which row it starts at, but that the key should span 2 rows. Basically, this key should span two rows (along with the gap between the rows). The
height: 100% and
justify-content: center is just for the aesthetics of the keys.
The keyboard takes up a fair amount of horizontal space, so I wanted to make sure it looked good on narrower screens. CSS Grid actually made this pretty easy to implement. I picked a few breakpoints and added a media query at each. At each break point, I chose a "scale factor," such as 0.8, and essentially scaled everything relative to the grid by that scale factor - making the keyboard about 80% of its original size. Without a whole lot of extra work, I was able to nicely "shrink" the keyboard for smaller screens.
This certainly isn't a comprehensive guide on CSS grid (I recommend CSS Tricks' article for that), but for me, this was an enlightening experience and opened my eyes to the beauty of the grid. I thought I'd share this experience with others.
I'm also aware that I barely tapped into the potential of the grid - which is pretty exciting, because that means I have plenty more to learn and experience with the grid!