Why Aren't My Grid-Template-Areas With Ascii Art Not Working

Why aren't my grid-template-areas with ASCII art not working?

When it comes to using ASCII art with the grid-template-areas property, there is an important limitation currently in place: Named grid areas must be rectangular.

In other words, tetris-shaped grid areas of the same name are not allowed.

This behavior is defined in two parts of the spec.

7.3. Named Areas: the grid-template-areas

If a named grid area spans multiple grid cells, but those cells do not
form a single filled-in rectangle, the declaration is invalid.

Non-rectangular or disconnected regions may be permitted in a
future version of this module.

9. Placing Grid

Every grid item has a grid area, a rectangular set of grid cells that
the grid item occupies.

In your first example, all grid areas form rectangles. So the rule is valid.

"....... header header"
"sidebar content content";

In your second example, the header area forms a non-rectangular shape. So the rule is invalid.

"....... header header"
"sidebar header content";

(Note that a period (.) or series of connected periods (...) form an unnamed grid area, to which the rule above does not apply (spec reference).)

Fortunately, Grid provides multiple methods for laying out grid items.

Instead of grid-template-areas, you can use line-based placement.

.wrapper {  display: grid;  grid-gap: 10px;  grid-template-columns: 120px 120px 120px;  grid-auto-rows: 100px;  background-color: #fff;  color: #444;}
.header { grid-column: 2 / 4; grid-row: 1 / 3;}
.sidebar { grid-column: 1 / 2; grid-row: 2 / 3;}
.content { grid-column: 3 / 4; grid-row: 2 / 3;}
.box { background-color: #444; color: #fff; border-radius: 5px; padding: 20px; font-size: 150%;}
.header { background-color: #999;}
body { margin: 40px;}
<div class="wrapper">  <div class="box header">Header</div>  <div class="box sidebar">Sidebar</div>  <div class="box content">Content</div></div>

Grid-Template-Areas - Invalid Property Value

There are a few rules when creating CSS Grid layouts using grid-template-areas.

  1. You must describe a complete grid, i.e. every cell on your grid must be filled.
  2. You can only define each area once, meaning that you can’t use this property to copy content into two places on the grid.
  3. You can’t create a non-rectangular area, else the declaration is invalid.

Breaking these rules will result in your value being invalid and therefore the layout not working.

The reason your grid-template-areas declaration is invalid, was because it violated rule #2. You try to define each grid-area more than once and copy content into two places on the grid. You've duplicated the area o in the third, fourth and fifth rows. Once you fix that the property value becomes valid. Feel free to change up the area names if you need but always keep in mind the above rules when working with grid-template-areas.

I assume s stands for "screen", o for "operation", n for "number" and so on. If you define the second row to have every area be o like o o o o then you can't use n n n o in the next row because your violating rule #2 by defining a grid-area more than once and copying content into two places within the grid. I updated your code so the grid-template-areas declaration is valid.

html, body {
margin: 0;
padding: 0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;

#gridContainer {
border: 1px solid black;
display: grid;
grid-template-columns: 4rem 4rem 4rem 4rem;
grid-template-rows: 6rem 6rem 6rem 6rem 6rem 6rem;
"s s s s"
"O O O O"
"o n n n"
"o n n n"
"o n n n"
"z z d c";
<div id="gridContainer">
<div id="screen"></div>
<button id="clear" class="clear" type="button" value="clear">AC</button>
<button id="negativeNumber" class="negative" type="button" value="signs">+ / -</button>
<button id="percent" class="percentage" type="button" value="percent">%</button>
<button id="divide" class="operator" type="button" value="/">/</button>
<button id="seven" class="number" type="button" value="7">7</button>
<button id="eight" class="number" type="button" value="8">8</button>
<button id="nine" class="number" type="button" value="9">9</button>
<button id="multiply" class="operator" type="button" value="*">*</button>
<button id="four" class="number" type="button" value="4">4</button>
<button id="five" class="number" type="button" value="5">5</button>
<button id="six" class="number" type="button" value="6">6</button>
<button id="subtract" class="operator" type="button" value="-">-</button>
<button id="one" class="number" type="button" value="1">1</button>
<button id="two" class="number" type="button" value="2">2</button>
<button id="three" class="number" type="button" value="3">3</button>
<button id="addition" class="operator" type="button" value="+">+</button>
<button id="zero" class="number" type="button" value="0">0</button>
<button id="decimal" class="number" type="button" value=".">.</button>
<button id="equals" class="equal" type="button" value="=">=</button>

css grid-template-areas property not aligning grid items

You are trying to name multiple grid areas “blogart”, but this is invalid. You cannot name multiple grid areas with the same name.

There are several ways to define a grid, apart from using named template areas. Instead of using grid-template-areas in your inner grid, you might want to rely on the grid auto-placement algorithm.

Try something like this:

.main {
background: #33a8a5;
grid-area: main;

display: grid;

grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto;
grid-gap: 20px;

Then, each grid item in the grid will automatically lay out, one per grid cell, for three columns, until they have all been placed.


Here’s a more complete demo: https://codepen.io/keithjgrant/pen/JNGNKX

I made a few changes:

  • I removed the grid-template-rows from the outer grid. You had constrained the heights of each row; it's better to allow the contents to grow/shrink automatically as necessary.
  • I removed the grid-template-areas from the inner grid and the grid-area from its grid items. This allows them to lay out naturally, in the order they appear. Each grid item will fill one grid cell by default.
  • I added a grid-column: span 2 to the img, since you want that to span 2 columns.

Play around with that. Notice you can now add (or remove) as many “blogart” elements you want, and the layout still works.

Related Topics

Leave a reply