Columns or rows?
Since most of my learning projects have involved solitaire card games, CSS grid layout has been a natural choice. Starting out, I overcomplicated my stylesheets by including things which I subsequently learnt are best done automatically.
My first mistake was thinking I needed to specify both grid-template-columns and grid-template-rows.
Perhaps if you come from a culture with a vertical writing system, working by rows might seem natural. But to me, left to right is an obvious choice, so all I want is columns. The CSS grid module is cluttered with stuff like grid-template-areas which besides overcomplicating things, lead to not following the best practice of Visual order on the page follows DOM order.
I initially gave every grid cell its own CSS block stipulating its grid-column and grid-row. With more experience I realized if I simply set the number of columns, the tracks — ie rows if working with columns — would take care of themselves.
A 3x3 Tic-Tac-Toe grid
Let’s start with the HTML. I like to follow the convention of labeling my columns alphabetically and my rows numerically, so the ids for my nine cells would look like so:
<main class="tableau">
<div id="a1">a1</div>
<div id="b1">b1</div>
<div id="c1">c1</div>
<div id="a2">a2</div>
<div id="b2">b2</div>
<div id="c2">c2</div>
<div id="a3">a3</div>
<div id="b3">b3</div>
<div id="c3">c3</div>
</main>I like to use tableau as my wrapper name since it’s mainly for card and other games.
Containers aren’t content
A grid needs a container
(aka wrapper) defined either display: grid or
display: inline-grid. Only the direct children of this
container are seen as cells, something that tripped me up initially.
.tableau {
display: grid;
grid-template-columns: repeat(3, 1fr);
}Firefox’s inspector tool helps show what’s going on.
Sizing Cells
My next step is to make all the cells in my grid squares. Here the relatively new orientation CSS media feature along with the var help me make the most of whatever screen real estate my site appears on:
@media (orientation: landscape) {
:root {
--side: 30vh;
}
}
@media (orientation: portrait) {
:root {
--side: 30vw;
}
}
.tableau {
display: grid;
grid-template-columns: repeat(3, var(--side));
}
.tableau > div {
border: 1px solid #999999;
border-radius: 3px;
aspect-ratio: 1 / 1;
}
Horizontal Alignment
I’ve personally found the difference between justify-content, justify-items, and justify-self hard to understand.
Through trial and error, I found adding
justify-content: center; to the .tableau {}
stanza did the job of horizontally centering the 3x3 grid.
Centering the “content” as in text of the individual cells turned out
to be tricky. Rather than justify-, using text-align
by adding text-align: center; to either
.tableau {} or .tableau > div {} got me
this:
Vertical Alignment
This is done with align-content,
align-items,
and align-items,
not to be confused with text-align which works horizontally
while vertical-self
is for vetical text movement.
If, as in this case, I want to use both
justify-content: center; and
align-content: center;, there’s the shorthand
place-content: center;.
.tableau {
display: grid;
grid-template-columns: repeat(3, var(--side));
place-content: center;
}
.tableau > div {
border: 1px solid #999999;
border-radius: 3px;
aspect-ratio: 1 / 1;
text-align: center;
align-content: center;
}