Grid vs. Subgrid: An Elemental Example

Episode 1: Gridded Form

Suppose we have a form. Thought it would be nice to use Grids to make its fields and labels align all pretty. Here is the markup originally:

<form>
  <ul>
    <li><label for=name>Name:</label> <input id=name name=name>
    <li><label for=email>Email:</label> <input id=email name=email type=email>
    <li><label for=tel>Telephone:</label> <input id=tel name=tel type=tel>
    <li><label for=url>Homepage:</label> <input id=url name=url type=url>
    <li><label for=bday>Birthday:</label> <input id=bday name=bday type=date>
  </ul>
</form>

It is structured into a list with each labelled field an item, and displays fine without CSS.

To display it as a grid, however, we need to strip some of the markup, because all of the grid items (items and labels) need to be siblings. The result looks like this:

<form>
  <label for=name>Name:</label> <input id=name name=name>
  <label for=email>Email:</label> <input id=email name=email type=email>
  <label for=tel>Telephone:</label> <input id=tel name=tel type=tel>
  <label for=url>Homepage:</label> <input id=url name=url type=url>
  <label for=bday>Birthday:</label> <input id=bday name=bday type=date>
</form>

Which, let's be honest, is not great wrt accessibility, since in non-CSS/non-visual contexts, it's a jumble of text an inputs with no structure that. But nevermind, we don't care that much about the subtleties of list structuring our forms, we just want it to look good.

  form { grid-template-rows: auto 1fr; }
  label { grid-column: 1; }
  input { grid-column: 2; }
  /* auto flows into rows */

But wait! We actually wanted to have a cool (lame, because I'm a spec-writer not a designer, but you get the idea) hover/focus glowy effect when you are interacting with a "row" in the form. We need an element to represent that "row" thing. We can't put the list structure back and use the <li> because that would break our grid (siblings and all that, y'know). But we can add empty <div>s, that we can style!

<form>
  <div id=namebg></div>
  <label for=name>Name:</label> <input id=name name=name>
  <div id=emailbg></div>
  <label for=email>Email:</label> <input id=email name=email type=email>
  <div id=telbg></div>
  <label for=tel>Telephone:</label> <input id=tel name=tel type=tel>
  <div id=urlbg></div>
  <label for=url>Homepage:</label> <input id=url name=url type=url>
  <div id=bdaybg></div>
  <label for=bday>Birthday:</label> <input id=bday name=bday type=date>
</form>

Add some CSS, more grid magic (though now we have to give up auto-flow, because the <div>s and form elements need to overlap) and all those empty <div>s will look cool!

~ the end [ canonical grid-based form styling ] ~

Episode 2: Gridded Page Design

For the next episode, we're going to re-create this design from the CSS Grid 960 System's intro pages. For simplicity, we'll just focus on the middle part:

Here's the initial structural markup, before confronting CSS:

  <section id=design>
    <h2>High Quality Building Design</h2>
    <img src="design.jpg">
    <p>Lorem ipsum...
    <p><a href="design/">Read more</a>
  </section>

  <section id=research>
    <h2>Professional Research</h2>
    <img src="research.jpg">
    <p>Lorem ipsum...
    <p><a href="research/">Read more</a>
  </section>

  <section id=cgi>
    <h2>Computer Visualizations</h2>
    <img src="visualization.jpg">
    <p>Lorem ipsum...
    <p><a href="cgi/">Read more</a>
  </section>

(We'll use CSS to shift the image above the heading for visual display; but structurally, it belongs below.)

Now we plan out the visual design.

This calls for Grid Layout, because there are columns and there are rows, and both dimensions have to line up. Especially those pesky dissimilar headings!

First, we strip all the <section> elements. (And consequently shift those IDs into their respective headings.)

    <h2 id=design>High Quality Building Design</h2>
    <img src="design.jpg">
    <p>Lorem ipsum...
    <p><a href="design/">Read more</a>

    <h2 id=research>Professional Research</h2>
    <img src="research.jpg">
    <p>Lorem ipsum...
    <p><a href="research/">Read more</a>

    <h2 id=cgi>Computer Visualizations</h2>
    <img src="visualization.jpg">
    <p>Lorem ipsum...
    <p><a href="cgi/">Read more</a>

Now it's easy peasy! … As long as we know exactly how many articles we have. (Since there's no container element to keep the sub-components together, we have to be explicit about placing them, and therefore can't use auto-flow.)

Now let's add a transform on those sections, to make them “pop” when you hover over, or target them!

section:target, section:hover { transform: scale(1.1); }

Actually, nevermind. Forgot we stripped the <section> elements. Can't select and style hovered or targetted sections that are represented by imaginary elements! So scratch that idea. (Hover effects are silly anyway, aren't they?)

~ the end [ basic front-page styling ] ~