If you’re seeing this, the site behind it is likely broken!

Hi, there. I use these course sites as little sandboxes to experiment with and learn various “brand new” CSS properties—and your browser does not support (at least) one of them. Apologies. It “should” always work in current/updating Safari and Chrome!

  • Typography & Interaction

    ’25–26

  • The Syllabus

  • Our Class

  • Unit Nº 1: “Type and the Web”

    Wks. 1–6

    • Week Nº 1

      Aug. 29

    • Everything Is a “Web Page”

    • Week Nº 2

      Sep. 5

    • It’s All About Type

    • Week Nº 3

      Sep. 12

    • An Intro to HTML

    • Week Nº 4

      Sep. 19

    • An Intro to CSS

    • Week Nº 5

      Sep. 26

    • The Box Model

    • Project Nº 1: “Manuscript”

      Oct. 3

    • Week Nº 6

      Oct. 3

  • Unit Nº 2: “There Is No Perfect Layout”

    Wks. 7–10

    • Week Nº 7

      Oct. 10

    • Responsive Design

    • DevTools (Web Inspector)

    • Week Nº 8

      Oct. 17

    • Finally, Flexbox

    • And (CSS) Grid

    • From Flex to Grid

      CSS grid layout (from here on, just grid) is another, even more recent addition to CSS, continuing on from where flexbox left off. While flex is primarily a one-dimensional layout system⁠—focused on horizontal or vertical arrangements⁠—grid is two-dimensional system, integrating the two directions together.

      • A Complete Guide to Grid – CSS Tricks
        The grid version of the flexbox classic.

      • CSS Grid Layout: A New Layout Module for the Web
        WebKit (Safari’s) overview, from 2017.

      • Basic Concepts of Grid Layout - MDN
        Back to MDN.

      • Basics of CSS Grid
        From web guru Jen Simmons.

      • Flexbox vs. CSS Grid
        Jen unpacks when to use each regime.

      • Grid by Example
        Loads of examples.

      • Grid Garden
        Like the Froggy game, but for grid.

      We had some of this two-dimensionality with flex-wrap, but grid offers us much more structure and control.

      Grid is a lot like flex (this will be a running theme)⁠—a display property applied on a parent/​container element. This display: grid; tells its (immediate) children/​grid items how they should be laid out. Also like flex, there is display: inline-grid; which behaves the same internally⁠—but with the parent behaving as an inline element.

      Grid truly supplants many of the previous box model layout approaches (like float, margin-centering, etc.) and, like flex, works much closer to how we think about layouts as designers. It can still get complicated, but makes most layouts (especially responsive ones) much, much easier to implement.

      There are many novel, powerful uses for grid⁠—it is really the backbone of modern web layout. Let’s take a look.

      As in nature, systems of order govern the growth and structure of animate and inanimate matter.

      So human activity itself has, since the earliest times, been distinguished by the quest for order.

      Josef Müller-Brockmann, 1961

      Grid Terminology

      Grid introduces us to some new vocabulary:

      Line
      The dividing lines that define the grid, vertical or horizontal. (Think gutters.)
      Track
      The horizontal or vertical space between the lines. (Think rows and columns.)
      Cell
      The intersection of a horizontal and vertical track. This is different from a grid item⁠—the cell is the spot/​placement, the item is the actual element⁠—since as you’ll see, you can position items in an arbitrary cell.
      Area
      You can combine one or more adjacent grid cells into a rectangular area. Often you give these a subjective name, for convenience/​ergonomics.

      New Units and Functions

      Grid also introduces some specific new length units:

      fr

      This new unit represents a fraction of the available space in the grid container⁠—usually, inline-size (width). This is very similar to using whole numbers in flex-basis. It is very handy; you’ll use it a lot with grid:

      						.two-thirds-one-third {
      	display: grid;
      	grid-template-columns: 2fr 1fr;
      }
      
      			
      	
      min-content

      The intrinsic minimum size of an element. With text, this is the longest single word:

      						.narrow-sidebar {
      	display: grid;
      	grid-template-columns: 1fr min-content;
      }
      
      			
      	
      max-content

      Same for the maximum. With text, this is the whole sentence/​line:

      						.wider-sidebar {
      	display: grid;
      	grid-template-columns: 1fr max-content;
      }
      
      			
      	
      fit-content

      A combo of the min/​max. Uses the available space⁠—but never less than min-content and never more than max-content:

      						.fit-sidebar {
      	display: grid;
      	grid-template-columns: 1fr fit-content;
      }
      
      			
      	

      You can use these last three values in grid properties (min-, max-, and fit-content), as we’ll see below⁠—but they are also usable anywhere length units work⁠—like inline-size or block-size.

      …and also functions to use the units:

      minmax()

      A function that defines a range for a track⁠—setting a minimum and maximum length together. These are really useful for setting reasonable limits on responsive grid designs:

      						.flexible-sidebar {
      	display: grid;
      	grid-template-columns: 1fr minmax(12rem, 25rem);
      }
      
      			
      	
      repeat()

      This function repeats a track list, so you don’t have to write it over and over:

      						.twelve-columns {
      	display: grid;
      	grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
      	/* How many columns is this? 👆 */
      }
      .also-twelve-columns {
      	display: grid;
      	grid-template-columns: repeat(12, 1fr); /* Much better. */
      }
      
      			
      	

      Hand-repeating code is brittle and boring

      As a general rule: whenever you are writing the same exact code over and over, there is almost certainly a shorter way. Refactor to avoid it; Don’t repeat yourself! Stay DRY.

      Container (Parent) Properties

      Again, grid is a lot like flex⁠—primarily properties that are applied on a container/​parent element.

      grid-template-columns /​ grid-template-rows

      Setting display: grid; won’t do much until you also declare some columns or rows. You can specify grid-template-columns, grid-template-rows, or both. These properties are followed by a track list of the size for each track:

      • grid-template-columns – MDN
      • grid-template-rows – MDN
        Define your tracks.
      Notice in the second example, the items do not wrap to a new column⁠—because grid-auto-flow: row; is the default setting. The third example sets this to column to make it flow to a new one.

      Again like flex, there is similar behavior on the horizontal/​vertical axes⁠—with the defaults around horizontal/​row based behavior since width is usually our constraint (with pages scrolling vertically).

      So for many uses, you will only need to specify your column structure⁠—leaving the rows to create themselves, as needed. This is called an implicit grid (vs. an explicit grid that we set/​define):

      Drag that divider! The additional rows are automatically added, as needed. Note that they size vertically to their largest content!

      grid-auto-columns /​ grid-auto-rows

      By default, these implicit grid tracks are sized auto (the largest content), but you can also specify their size⁠—often a height for the grid-auto-rows:

      • grid-auto-columns – MDN
      • grid-auto-rows – MDN
        Lets the content create the tracks.

      The perpendicular grid-auto-columns only comes up if you force the columns to wrap with grid-auto-flow: column; as in the earlier example. Again⁠—height is usually not our main constraint, with scrolling!

      gap /​ column-gap /​ row-gap

      Grid also shares the gap, column-gap, and row-gap properties with flex⁠—to add gutters between the tracks. The syntax and behavior is the same:

      • gap – MDN
      • row-gap – MDN
      • column-gap – MDN
        The exact same as with flex!
      You rarely see a grid without a gap.

      justify-items

      Also like flex (there’s a pattern here), we can position items within the tracks⁠—but now we have control over both axes and the overall placement. To start, justify-items positions all the grid items along their row axis.

      justify-items – MDN
      This only works with grid.

      The terminology here is always a bit confusing, but think of it this way⁠—in grid, the main axis is always the horizontal row. So justify always means left/​right, and align always means top/​bottom. Easier to remember than flex! No flipping axes:

      align-items

      And align-items directly corresponds to the flex values, to position all the items vertically along their column axis:

      align-items – MDN
      Same as flex, again!

      Note that there isn’t any change on the last implicit row with the default auto/​content height.

      There are also baseline alignment values, to keep text on the same line across your columns:

      justify-content /​ align-content

      If the total size of your grid is less than the container (because of your explicit column or row sizes), you can set the overall justification and alignment within the grid container:

      • justify-content – MDN
      • align-content – MDN
        When there is extra space.
      Again, this is just like flex! Same syntax, same behavior⁠—you get the idea. Grid is like Flex+.

      Shorthand?

      Grid also has shorthand properties for many of these, like just grid, grid-template, place-items, and place-content. However just like everything else, grid is complicated enough as it is! The shorthands really obfuscate the behavior, and aren’t worth the slightly tighter syntax.

      Okay, so far this is mostly like flex! To the point where you can often use them interchangeably for some layouts. You get it.

      But now let’s look at where grid offers more specific and powerful control.

      Using repeat()

      Grid’s repeat function is very commonly used to make even-column grids. And of course, they can be made responsive with media queries and CSS variables!

      repeat() – MDN
      Remember, D.R.Y!

      The () indicates this is a function (like our friend calc() ) that you would pass arguments⁠—a common software paradigm.

      Notice that the items always stick to the grid structure⁠—independent of their content⁠—unlike our previous flex-wrap pseudo-grids.

      Flex is sometimes referred to in this way as content-out, while grid is a layout-in system.

      auto-fill /​ auto-fit

      You can also use the repeat function without specifying an exact number of columns, instead using auto-fill or auto-fit to automatically define your columns⁠—making a grid inherently responsive without any media queries! These are great for controlling an even-column layout without much overhead:

      • Auto-Sizing Columns in CSS Grid – CSS Tricks
        Better than MDN, for this.
      Drag the divider over to see the difference in auto-fill /​ auto-fit behaviors.

      grid-template-areas

      Grid is really useful for scaffolding out layouts, and sometimes it is helpful to give your grid areas qualitative/​descriptive names that reflect their usage. This also makes it possible for the grid items (children) to reference them, below.

      grid-template-areas – MDN
      These are grid’s real designer superpower.

      This is done with a bit of ASCII art to reflect the layout! Repeating the name of a grid area makes the content span those cells. The syntax itself then provides an ergonomic visualization of the grid structure (for us humans):

      You can also name grid lines with [linename] length syntax, but you don’t see this done as much.

      						section {
      	display: grid;
      	grid-template-columns: 2fr 1fr;
      	grid-template-areas:
      		"header header "
      		"main   sidebar"
      		"footer sidebar";
      }
      
      			
      	

      Item (Child) Properties

      You can really start to see the power of grid when you use these properties on the individual grid items (children) within the containers. While the container (parent) properties usually make for uniform layouts, item (child) properties allow for unique structures.

      grid-area

      If you’ve defined grid-template-areas (as above), you can then assign individual children to these areas:

      grid-area – MDN
      These go on the items/​children.

      This is the kind of common layout that was unnecessarily hard before grid! It’s so much easier now.

      grid-column /​ grid-row

      You can also control item placement in unnamed (and implicit) grid areas with the grid-column and grid-row properties.

      • grid-column – MDN
      • grid-row – MDN
        Where should the item go?

      These take two values, divided with a / (because CSS is inconsistent), which specify the start line and end line. There is also a span value for bridging across tracks:

      Notice that we can leave off the end line if it doesn’t span multiple tracks, and also that you either add a span or a specific end line number.

      These are technically shorthand properties, but we’ll allow it here⁠—they are easier to read!

      You can also leave off the start line if you just want to specify a span, regardless of where the item falls in the grid:

      We’ve added grid-auto-flow: dense; to the container⁠—allowing the seventh item to scoot up “before” the bigger one.

      And if you specify non-contiguous rows or columns, grid will dutifully create as many implicit tracks as it needs to accommodate them⁠—even if they are empty. Not every cell or track must be filled:

      Note that just like order in flex, this arrangement is only visual! Keep your DOM in a logical, semantic sequence.

      Keep in mind that with both grid-area and grid-column /​ grid-row, you are able to tell multiple grid items to land in the same cell⁠—there isn’t any kind of fancy/​automatic collision-prevention. If this is what you want, you can use z-index to specify which one is visually in front!

      justify-self /​ align-self

      Finally, just like flex⁠—you can position individual grid items within their tracks using justify-self and align-self. The syntax is the same as align in flex, again⁠—but as with justify-items /​ align-items above, you don’t have to flip axes:

      • justify-self – MDN
        Just for grid.
      • align-self – MDN
        Same as in flex!
      You can mix and match these justify/​align values, of course!

      The grid system is an aid, not a guarantee.

      It permits a number of possible uses and each designer can look for a solution appropiate to [their] personal style.

      But one must learn how to use the grid; it is an art that requires practice.

      Josef Müller-Brockmann, 1961

    • Week Nº 9

      Oct. 24

    • Some Additional, Advanced CSS

    • Project Nº 2: “Spread”

      Oct. 31

    • Week Nº 10

      Oct. 31

  • Unit Nº 3: “Typography as Interface”

    Wks. 11–15

    • Week Nº 11

      Nov. 7

    • Working with Images

    • Week Nº 12

      Nov. 14

    • Week Nº 13

      Nov. 21

    • Thanksgiving Week

    • Project Nº 3: “Binding”

      Dec. 5

    • Week Nº 14

      Dec. 5

    • Week Nº 15

      Dec. 12

  • Winter Break

  • Unit Nº 4: “Interface as Interface”

    Wks. 16–21

    • Week Nº 16

      Jan. 21

    • Week Nº 17

      Jan. 28

    • An Intro to JavaScript

    • Week Nº 18

      Feb. 4

    • Some More JavaScript

    • Week Nº 19

      Feb. 11

    • Week Nº 20

      Feb. 18

    • Project Nº 4: “Links”

      Feb. 25

    • Week Nº 21

      Feb. 25

  • Unit Nº 5: “If All You Have Is a Hammer, Everything Looks like a Nail”

    Wks. 22–30

    • Week Nº 22

      Mar. 4

    • Putting a (Link/​Meta) Bow on It

    • Week Nº 23

      Mar. 11

    • Spring Break

    • Week Nº 24

      Mar. 25

    • Week Nº 25

      Apr. 1

    • Week Nº 26

      Apr. 8

    • Week Nº 27

      Apr. 15

    • Project Nº 5: “Functions”

      Apr. 22

    • Week Nº 28

      Apr. 22

    • Week Nº 29

      Apr. 29

    • Week Nº 30

      May 6

    • “Everything Else”

    • The end