Chrome Grid Bug Update

Comments Off on Chrome Grid Bug Update

I mentioned late last week, in my post about Chrome 57 having landed Grid layout, that there is a bug that affects some people.  Well, further investigation has revealed that the bug doesn’t seem to be in the Grid layout engine.  Instead, disabling selected extensions makes the bug go away.

The odd part is that the extension seems to vary.  In my case, disabling Window Resizer fixed the problem.  Before you think it’s all their fault, though, Rachel Andrew discovered that disabling Window Resizer in her copy of Chrome did not solve the problem.  For her, it was disabling the LastPass extension that did it.  I don’t even have the LastPass extension installed on my machine, in any browser.

So: if you run into this problem, try disabling extensions to see if that fixes it.  If so, you can enable them one at a time and test to see which one triggers the bug.  With any luck, a fix will be found soon and deployed via auto-updating.  And if you find out anything else, please let us know on the bug report!

March 14th 2017 browsers, CSS

Doubled Grids

Comments Off on Doubled Grids

Chrome 57 released yesterday, not quite a week ahead of schedule, with Grid support enabled.  So that’s two browsers with Grid support in the space of two days, including the most popular browser in the world right now.  Safari has it enabled in Technology Preview builds, and just blogged an introduction to Grid, so it definitely feels like it’ll be landing there soon as well.  No word from Edge, so far as I know.

I did discover a Chrome bug in Grid this morning, albeit one that might be fairly rare.  I filed a bug report, but the upshot is this: most or all of an affected page is rendered, and then gets blanked.  I ran into a similar bug earlier this year, and it seemed to affect people semi-randomly—others with the same OS as me didn’t see it, and others with different OSes did see it.  This leads me to suspect it’s related to graphics cards, but I have no proof of that at all.  If you can reproduce the bug, and more importantly come up with a reliable way to fix it, please comment on the Chromium bug!

March 11th 2017 browsers, CSS

Grid Inspection

Comments Off on Grid Inspection

I said yesterday I would write up the process of adding Grid to meyerweb, and I did.  I started it last night and I finished it this morning, and when I was done with the first draft I discovered I’d written almost four thousand words.

So I pitched it to an online magazine, and they accepted, so it should be ready in the next couple of weeks.  Probably not long after Chrome ships its Grid implementation into public release, in fact.  I’ll certainly share the news when it’s available.

In the meantime, you can inspect live grids for yourself, whether here or at Grid by Example or The Experimental Layout Lab of Jen Simmons or wherever else.  All you need is Firefox 52, though Firefox Nightly is recommended for reasons I’ll get to in a bit.

In Firefox 52, if you inspect an element that has display: grid assigned to it, you’ll get a little waffle icon in the inspector, like so:

Mmmmmm, waffles.

Click it, and Firefox will draw the grid lines on the page for you in a lovely shade of purple.  It will even fill in grid gaps (which are a thing) with a crosshatch-y pattern.  It’s a quick way to visualize what the grid’s template values are creating.

If you have Firefox Nightly, there’s an even more powerful tool at your disposal.  First, go into the inspector’s settings, and make sure “Enable layout panel” is checked.  You may or may not have to restart the browser at this point—I did, but YEMV—but once it’s up and running, there will be a “Layout” panel to go with the other panels on the right side of the Inspector.  There you get the box model stuff, as well as a checklist of grids on the current page.

The Layout panel

For each grid on the page—not just the element you’re inspecting—you can set your own color for the gridlines, though those color choices do not currently persist, even across page reloads.  You can also turn on number labels for the grid lines, which are currently tiny and black no matter what you do.  And if you allow grid lines to extend into infinity, you can turn the page into a blizzard of multicolored lines, assuming there are several grids present.

This panel is very much in its infancy, so we can expect future enhancements.  Things like color persistence and better grid line labels are already on the to-do list, I’m told, as well as several more ambitious features.  Even as it is, I find it valuable in constructing new grids and diagnosing the situation when things go sideways.  (Occasionally, literally sideways: I was playing with writing-mode in grid contexts today.)

There’s another, possibly simpler, way to enable the Layout panel, which I learned about courtesy Andrei Petcu.  You type about:config into the URL bar, then enter layoutview into the search field.  Double-click “devtools.layoutview.enabled” to set it to “true”, and it will be ready to go.  Thanks, Andrei!

So go ahead—inspect those grids!

March 9th 2017 browsers, CSS, Design, Tools

Welcome to the Grid

Comments Off on Welcome to the Grid

Grid is public.  It’s live right now in the latest Firefox release, Firefox 52.

It will similarly be live in the next public Chrome release, due in the next week or so.

It’s here.  I almost can’t believe it.

For well more than a decade now, when asked what CSS needs more than anything, I’ve said it needs real, actual layout.  “A layout-shaped hole at its heart” is a phrase I may have used a fair few times.

Rachel Andrew had a great article last week about “Learning CSS Grid Layout”, which charts a sensible course for getting used to grid.  It also busted a few myths about grid.  I recommend it highly.

There’s one more myth I’d like to do my best to bust, which I’ll summarize as a comment I’ve seen many times: “Ugh, tables again?”

The underlying assumption here is: grids are just tables with a new syntaxThis is entirely untrue.

I mean, yes, you can recreate 1990s-era table-based layout techniques with grid, in much the same way you can recreate the submit button with two JS libraries and a complex front-end framework.  The ability to do it doesn’t necessarily make it a good idea.

(Though you might, from time to time, find the ability useful.  Here’s what I mean: you can take a bunch of data contained in arbitrary markup someone else is producing, and lay it out in a tabular format.  It would be far preferable to have the data in actual table markup, but if that’s not an option, grid will give you a potential solution.)

I have an example of just one way grids are different than tables.  I just last Friday finished writing the last chapter of CSS: The Definitive Guide, 4th Edition, covering filters, blending, clipping, and masking.  (I finished the grid chapter late last year, so it’s already available in the early-access title.)  Almost all the figures in the book were created by building HTML+CSS pages, and taking high-resolution screen captures with Firefox’s screenshot command.  Here’s one.

Compositing masks

The way these are displayed is actually the inverse of their source order.  I wanted them to be in document source such that the compositing steps were in chronological order, so that’s how I wrote them.  Once I laid them out that way in the figure, using grid, I realized it made more sense to arrange them visually, with the bottom layer at the bottom of the figure, the next above that, all leading up to the result at the top.

So I just rearranged them on the grid, by assigning grid row numbers.  The document source wasn’t touched.  A bit simplified, the CSS to do that looked something like this:

ol li:nth-child(1) {grid-row: 4;}
ol li:nth-child(2) {grid-row: 3;}
ol li:nth-child(3) {grid-row: 2;}
ol li:nth-child(4) {grid-row: 1;}

Because the compositing examples (the “columns” in the layout) were represented as ordered lists, with the grid set up to place each image with some captioning, I could just change their order.  So yes, it looks like a table, but the underlying structure is anything but table-like.  Just to get each column of examples grouped together with tables, I’d have to nest tables, or accept a one-row table with each cell containing some other structure.  Rearranging the columns would mean doing markup surgery, instead of just reassigning their layout placement via CSS.

Instead, I was able to represent the content in the best available structure (ordered lists) and then arrange them on a grid in the best way I could visually.  For that matter, I could responsively change the layout from a six-column grid to a three-column grid to un-gridded lists as the viewport got more and more narrow.  As, in fact, I did—check it out.  If you make the window narrow enough, Grid is dropped entirely so you can see the base structure and content.

This ability to place grid items without respect to source order is a powerful tool, and like all powerful tools it can be used for good or ill.  It’s possible to assemble a visually usable layout out of the most inaccessible, horrible markup structures imaginable.  It’s also possible to assemble a visually usable layout from clean, accessible markup in ways we’ve never even dared dream.

Combine grids with other CSS features, and you can really create art.  Jen Simmmons has a layout lab site, and her 2016 main-page design is… well, go see it in a grid-capable browser, like today’s release of Firefox.  Realize it’s all text, no images, no scripting.  Just markup and style.

And the style is remarkably simple for what’s being accomplished.  It’s not too alien a syntax, but it will likely take some time to adjust to using it.  It’s taken me some time, as I’ve experimented and written about it.  Unlearning my float habits has taken some work, and I don’t know that I’m completely done.  I do know that it’s been worth it many times over.

I’ve done a few experiments with the layout of a local copy of meyerweb, and done some frankly goofy things to the design along the way.  I’m hoping to convert what’s up here to a simple grid layout in the next few days, make it a slightly more complex grid shortly after that, and then maybe—maybe—actually do some redesigning for the first time in over a decade, to take advantage of grid more fully.  Jen has a great six-minute video exploring a few features of grid and the grid inspection tool now built into Firefox, which I recommend to anyone curious to know more.

So if you’re thinking of grid as tables 2.0, please, stop.  Table-style layouts are the first one percent of what grid offers.  There are works of art and undiscovered techniques waiting in the other 99 percent.

March 8th 2017 browsers, CSS, Design

Scaling SVG Clipping Paths for CSS Use

Comments Off on Scaling SVG Clipping Paths for CSS Use

I’ve been working a lot with the clip-path property recently, as I write the chapter on filters, blends, clipping, and masking for CSS: The Definitive Guide’s long-delayed 4th edition (available now in early-release format!).  One of the nifty things you can do with clipping paths is define them with percentage-based coordinates.  For example, here’s a hexagon-like clipping path:

clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);

That starts at the center top (50% 0), goes to the right edge, quarter-down (100% 25%), and so on.

When I got to SVG-based clipping, which you can use with the CSS pattern clip-path: url(#pathID), I tried and failed with this:

<clipPath id="hexlike">
  <polygon points="50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%" />

It didn’t work because, as I discovered to my horror, SVG does not allow percentage coordinates.  I could just strip all the percent signs out, but that would be the same as saying this in CSS:

clip-path: polygon(50px 0, 100px 25px, 100px 75px, 50px 100px, 0 75px, 0 25px);

I didn’t want pixels, though.  I want percentages, darn it all!

So I asked around on Twitter, and Markus Stange pointed me to the solution: converting all the SVG coordinates to the range 0–1 and using the clipPathUnits attribute.  The working version looks like this:

<clipPath id="hexlike" clipPathUnits="objectBoundingBox">
  <polygon points="0.5 0, 1 0.25, 1 0.75, 0.5 1, 0 0.75, 0 0.25"/>
A hexlike clipping path.

That yields the same result as the polygon() CSS shape with the percentages I showed before.

All that is great if you’re writing your own SVG shapes and can make sure you set it up properly, but what if someone hands you a shape to be used as a clip path and it’s in absolute coordinates like 100 75?  If you’re really lucky, the shape has a viewbox of 0 0 100 100 (or all the coordinate points are in that range) and you can just divide all the coordinate points by 100 to get the proper values.  But that’s really tedious for any but the simplest of shapes, and besides, what if it has some other viewbox?  That’s where the transform attribute saves the day.

For example, suppose you get an SVG file that looks like this (with the actual path coordinates removed because there are a lot of them):

<svg version="1.1" xmlns=""
  xmlns:xlink="" viewBox="0 0 329.6667 88">
  <clipPath id="cloud02">
    <path d="…(coordinates go here)…"/>

First, add the clipPathUnits attribute to the <clipPath> element:

<svg version="1.1" xmlns=""
 xmlns:xlink="" viewBox="0 0 329.6667 86">
  <clipPath id="cloud02" clipPathUnits="objectBoundingBox">
    <path d="…(coordinates go here)…"/>

Next, look at the viewBox attribute on the <svg> element itself.  The value there is 329.6667 86.  That means 329.6667 coordinate units horizontally, and 86 units vertically.  So all you need to do now is divide all the horizontal values by 329.6667, and the vertical values by 86.  Which would be super tedious, except we have scaling transforms at our disposal:

<svg version="1.1" xmlns=""
  xmlns:xlink="" viewBox="0 0 329.6667 86">
  <clipPath id="cloud02" clipPathUnits="objectBoundingBox"
   transform="scale(0.003033 0.0116279)">
    <path d="…(coordinates go here)…"/>

Those two values are 1/329.6667 and 1/86, respectively, and they effectively scale every point in the d attribute to fit into the needed 0–1 range.  (That’s not precisely what happens, but the outcome is the same.)  Thus we have an SVG clipping path that scales with the element and fits to its dimensions!

This works just as well for other markup patterns.  To return to the hexlike path from before, assume it was written like this:

<svg version="1.1" xmlns=""
 xmlns:xlink="" viewBox="0 0 100 100">
  <clipPath id="hexlike">
    <polygon points="50 0, 100 25, 100 75, 50 100, 0 75, 0 25" />

If that were applied as-is, via clip-path: url(#hexlike), it would create a hex-like clipping path that fits a 100px by 100px box, positioned in the top left of the element (in left-to-right languages, I presume).  The quick fix:

<svg version="1.1" xmlns=""
 xmlns:xlink="" viewBox="0 0 100 100">
  <clipPath id="hexlike" clipPathUnits="objectBoundingBox"
    <polygon points="50 0, 100 25, 100 75, 50 100, 0 75, 0 25" />

Bingo bango bongo, it will now scale to the element’s dimensions, whatever those turn out to be.

Of course, if you apply that to something like a short paragraph, it will be verrrrry stretched out, but the same would be true with a percentage-based polygon() shape.  The beauty here is that you can scale any coordinate set, so if you have a tiny path that you want to blow up, or a huge path you want to shrink down, you can transform it without using clipPathUnits to stretch it over the bounding box.  Something like this:

<svg version="1.1" xmlns=""
 xmlns:xlink="" viewBox="0 0 100 100">
  <clipPath id="hexlike" transform="scale(4)">
    <polygon points="50 0, 100 25, 100 75, 50 100, 0 75, 0 25" />

That gets you a hexlike shape that fits a 400px by 400px box, for example.

Now all CSS needs is the ability to size and position clipping paths in a manner similar background images, and we’ll be in clover.  I hope such properties are in the WG’s mind, because I’d love to be able to just point an at SVG clipping path, and then say something like clip-path-position: center; clip-path-size: contain;.  That would remove the need for fiddling with SVG attributes altogether.

Thanks to Markus Stange for the technique and his invaluable assistance in proofreading this article.

February 25th 2017 browsers, CSS

Four levels of accessibility customisation

Comments Off on Four levels of accessibility customisation

There are some interesting discussions on customisation going on with the work on WCAG 2.1, the much anticipated (I hope) update to the Web Content Accessibility Guidelines. This is a little inside-baseball, but I’ve tried to make it understandable for a wider accessibility-audience.

Disclaimer: I am a member of the Accessibility Guidelines Working Group, but these are purely my thoughts and do not represent the group.

When trying to make websites more accessible to more people, you run into issues working out who is responsible for what. Is it the browser, the site, or a bit of both?

For example, someone who needs to make things bigger can use the browser controls to increase the size of things by 200% fairly easily. At the other end of the scale a website could provide controls to simplify the layout and add easy-read icons to specified areas.

I won’t be making a judgement on whether or how much WCAG should require adaptation or personalisation, but I do want to work through what it means in practice.

Key terms if you are new to this level of accessibility nerdery:

User-agent (UA):
What a person uses to access a website, usually a browser but it can include plugins or assistive technology such as screenreaders.
The person(s) who make the website. A catch-all for designers, developers, website owners etc.
Success Criteria, the testable statements within the accessibility guidelines. Most people just think of these as “the guidelines”, but it’s a level down.

I think there are four broad levels of user-adaptation that impact the effort required from authors.

1. Within the author’s default styles

Some adaptations easily work within the site’s styles with very little effort from site authors. The main one is to zoom in (or out). It is built into the browser interface, and generally works regardless of what the author does. It may not work well if it is not a responsive design, but it doesn’t break the layout.

Supporting this level of adaptation takes near zero effort on behalf of the author (if you cater to small-screen devices already). There is a potential new SC about supporting a 400% increase in the size of content which would push up the level of effort in some cases.

2. Overriding author styles without impacting layout

Some adaptations override the author styles but do not (generally) impact the layout, such as changing colors, font-family and spacing around text (up to a quite limited point). The font & colour adaptations are available in most browsers, but more hidden, somewhere in the settings.

You might think that overriding the font-family works easily, but there are challenges. For example, it is easy to turn into comic-sans, but the weather icons disappear:

Two versions of a BBC weather widget, the default and one with comic sans but no icons.

Default view at the top, and comic-sans version underneath.

The CSS for one of those icons is:
.icon-cloud:before {
content: 'F402';

I’m assuming this is an font icon, so overriding the fonts on the page kills them. Potential solutions are to either:

  • Recommend people use SVG instead (and there are good reasons for that besides accessibility), or
  • To come up with a way of identifying font-icons so they can be ignored when overriding fonts.

I am not sure what the answer is in that case, yet. There is a potential new SC for adapting text but the next step will be to work through those issues and figure out what can be done on the user-agent end, and what needs to be done by the authors.

Supporting this level of adaptation is essentially avoiding certain front-end web development techniques that prevent users from overriding styles. There is some effort involved, but it is certainly in the same league as current WCAG 2.0 SCs.

3. Overriding layout styles

For users who need more than a 400% increase in size, author styles simple don’t cut it. Even mobile-optimised navigation bars tend to overlap or cause horizontal scrolling when you get up to 600%. Large increases in spacing around text are also likely to break layouts.

The practical outcome from overriding the layout is that you pretty much override all the layout styles. My initial script to test this basically did this:

  • Turn off all floats.
  • Set a max-width & height of 100% on everything except data tables.
  • Gather all the visible block elements and:
    • Set position static, width & height auto, margin to 0, text alignment to left.
    • Linearise flexbox elements.
  • Wrap data-tables in a div and set them to horizontally scroll within that div if they are too wide.

It works well on a test page, but there is much more work to do in testing this!

The support required from the site authors is difficult to establish at the moment. When testing the script it works well on some pages, but falls apart on others. Layouts which involve heavy scripting seem to be a major problem, but it is possible there is a simple solution within the script. Or it might be a case of requiring people to keep layout in the CSS?

There is a new potential SC about letting people linearise a page.

4. Customisation

For an accessibility scenario I’m defining customisation as where the user sets their preferences in the user-agent, and the site provides different content, layout or functionality based on those choices.

NB: Personalisation and Customisation are often used interchangeably, my understanding is that customisation is where the user sets things explicitly (as is the case here), and personalisation is accomplished by the site based on behaviour, it ‘just happens’ without the user asking for it.

The preferences and customisations based on those preferences need to happen in a pre-agreed fashion, otherwise it will simply not work. However, it could be quite granular, a website could provide customisations for layout (e.g. a one-column view), but not for other preferences.

There is already some work on this, starting with cognitive issues in coga.personalisation demo.

Two screenshots, the first with a default view, the  second reduced in complexity.

Two views of the same page, the second with customisations applied.

Whether a site has a widget on the screen to apply the customisations is not the issue in terms of work needed, that ‘just’ affects the design. The main work is putting the structure in place to support the customisations. For a site of any complexity, it adds another level to browser testing.

I haven’t delved in deeply yet, but the nature of those customisations appears to be adding attributes to particular links and (importantly) allowing for layout variations when icons are added, options reduced and elements spaced differently.

The support required from authors is difficult for me to assess so far, there are several potential SCs to do with personalisation, such as support personalisation. Adding meta data is not a big deal, but I suspect that making the layout so flexible will be very difficult for more complex sites and applications.

So that’s my outline of the levels of effort required for customisation/adaptation by users. If you have any further comments or examples, or anything I can take back to the working group please comment below or ping me on twitter.

February 17th 2017 browsers

Element Dragging in Web Inspectors

Comments Off on Element Dragging in Web Inspectors

Yesterday, I was looking at an existing page, wondering if it would be improved by rearranging some of the elements.  I was about to fire up the git engine (spawn a branch, check it out, do edits, preview them, commit changes, etc., etc.) when I got a weird thought: could I just drag elements around in the Web Inspector in my browser of choice, Firefox Nightly, so as to quickly try out various changes without having to open an editor?  Turns out the answer is yes, as demonstrated in this video!

Youtube: “Dragging elements in Firefox Nightly’s Web Inspector”

Since I recorded the video, I’ve learned that this same capability exists in public-release Firefox, and has been in Chrome for a while.  It’s probably been in Firefox for a while, too.  What I was surprised to find was how many other people were similarly surprised that this is possible, which is why I made the video.  It’s probably easier to understand to video if it’s full screen, or at least expanded, but I think the basic idea gets across even in small-screen format.  Share and enjoy!

January 19th 2017 browsers, Tools


Comments Off on Workshopping

I’m criminally behind in sharing this with everyone, so I’m jumping straight to the bottom line here: I’m teaching a workshop on advanced CSS layout techniques in October, and co-teaching another workshop on CSS animation in November with the inestimable Val Head.  Both are courtesy O’Reilly & Associates, and will be conducted at their offices in Boston.

A few more details:

  • New CSS Layout (October 17-18) is two days of deep diving into flexbox, multicolumn, grid, and related technologies.  There will be a heavy emphasis on Things You Can Use Today, including bugs and how to handle them, with a keen focus on using everything in a progressively enhancing way.  In other words, you should walk away knowing how to use new technologies right away, without leaving behind users of older browsers, and have a good sense of what you’ll be able to do in the next 6-12 months.  This will be hands-on, interactive, and very much a dialogue with technical instruction.  If you’re looking for two days of watching me drone in front of a slide show, this is not that.  I’m not even sure I’ll have any slides at all—I’ll probably spend the entire time in BBEdit and a browser instead.  The class size is limited to 40 people.
  • CSS Animation (November 17-18) is another two days of diving deep into the topic.  For this one, I’ll spend the first day going through every last piece of CSS transition and animation syntax, with generous helping of transform.  On the second day, Val will show how to put that syntax to use in a way that serves and strengthens your design, instead of undermining it.  It’s basically a day of learning how the tools work, and a day of learning how to properly use the tools.  Again, class size of 40; and again, very much hands-on and interactive.

So that’s what’s up.  Looking for ways to seriously expand your skills in layout or animation or both?  Come, join us!

September 29th 2016 browsers, CSS

Fixing outlines on click

Comments Off on Fixing outlines on click

It is a small thing in someways, but it can trigger nasty effects for keyboard users: Lack of an outline (or other indicator) on links when tabbing through a web page. Unfortunately some browsers in some situations will display the outline when you click the link as well.

The general advice is easy: Make sure there is a clear focus indicator for each link (and other interactive items), whether it is the default outline that browsers add, or something you specify.

Lack of focus indicator is a problem I come across quite often, and it is often the result of a conversation like this:

Project manager:
The client has said / filed a bug that you get a weird outline when clicking on some links, can you get rid of it?
But we need that for accessibility, otherwise some people can’t see where the focus is.
Project manager:
It looks odd, get rid of it.

NB: If you’re client only uses Safari, you won’t have this conversation! More on the browser differences later.

As an example of the oddness, use the tab key (on desktop/laptop) to get to this set of fake links:

The link is set to display:block (useful for creating large hit targets), and near some floated content. As the floated content overlaps with the empty part of the block, the outline appears over the nearby content.

There are many solutions to this, but the one people tend to reach for is removing the outline on focus.

Browser differences

There is a variety of behaviours for focus when clicking, from looking at the spec it says:

The :focus pseudo-class applies while an element has the focus (accepts keyboard or mouse events, or other forms of input).

However, I think there are some defaults to account for as well. Browsers have a default outline for keyboard focus, but that isn’t necessarily the same thing as a:focus {outline:..}. For example, Firefox’s default focus comes from it’s user-agent stylesheet:
*|*:-moz-any-link:-moz-focusring {outline: 1px dotted;}

From a little testing:

  • Without changes to CSS, all browsers show a focus outline when using the keyboard (as expected).
  • Without changes to CSS, no browsers show a focus outline when clicking with a mouse (except Firefox if you’ve been tabbing through first).
  • If you add an outline to a:focus, all browsers show the focus outline onclick, except Safari.
  • Using active can remove the focus onclick in Firefox, but other browsers will still show the outline on mouse-up or dragging the link.
  • Using a:focus:hover works across browers* to remove the outline when using the mouse (only).

Update & credit: The last test example came from a link to a Sitepoint Article via Patrick Lauke. James Edwards used a:focus:not(:hover) { outline:none; } as a (bad) example, but considering it, I thought a:focus:hover might work, and it seems to.

* See the full results table for the browsers tested, please comment or ping me if you get different results or can test other browsers.

So there is a zen approach: Don’t remove or apply any outline to links, then it won’t add an outline onclick. Use foreground/background colours to highlight the current focus.

If you do need to remove the outline for mouse clicks (only), then use:

a.specific-class:focus:hover { outline: none; }

I do wonder though, what is the use-case for showing focus on mouse-click? Is this something the browsers should change to match Safari’s behaviour?

September 25th 2016 browsers

Subgrids Considered Essential

Comments Off on Subgrids Considered Essential

Grid layout is a pretty darned fantastic thing.  I’ve been digging into it as I write the grid layout chapter of CSS:TDG4e, and there are more things in here than have been dreamt of in our layout philosophies.  One of the things I’ve recently come to realize is the power and necessity of subgrids.

To understand why, let’s explore a use case, which you can see in various forms on this test page.  I cribbed this use case pretty directly from Fantasai, but I’m going to be analyzing it a little differently.  The basis is a form with the various fields and labels in unordered list items, to help with accessibility and to be basically readable and usable if the CSS somehow fails to be applied.  The markup looks like this:

<form method="post" action="script.cgi">
    <li><label for=name>Name:</label>
        <input id=name name=name></li>
    <li><label for=email>Email:</label>
        <input id=email name=email type=email></li>
    <li><label for=tel>Telephone:</label> 
        <input id=tel name=tel type=tel></li>
    <li><label for=url>Homepage:</label>
        <input id=url name=url type=url></li>
    <li><label for=bday>Birthday:</label>
        <input id=bday name=bday type=date></li>

The basic form with no grids.

Ideally, we’d like the form fields to all line up into a column, and the labels to be in another column.  Furthermore, we’d like the label column to be only as wide as the widest label’s element box, and no more; the rest of the grid can be taken up by the input column.

This seems like a case tailor-made for grid layout, but there’s a problem.  Because grid items are only ever the child elements of a grid container, we can’t just apply a grid to the ul element and go from there.  Instead, we have to make each li element a grid container, in order to make each label and input element a grid item.  But that means each list item’s grid affects its children, with no reference to the other list items’ grids.  We can write the template we want, like so:

form ul li {display: grid;
  grid-template-columns: [start label] max-content [input] 1fr [end];}

Each list item a grid, but to what end?

That will get us a result almost precisely as if we’d applied no grids at all.  The only difference is that the input elements will all be as wide as their columns, according to the CSS Grid specification.  Chrome fails to do this last bit correctly, whereas Firefox Nightly gets it right, but otherwise the layout is essentially the same.  You can see this in the #form1 example on the test page.  (Remember, you have to have a current grid-supporting browser for the examples to correspond to what I’m talking about here.)

We can get closer to our goal by experimenting with a fixed-width grid column for the labels, figuring out the width of the widest label, and then just making all the label columns be that wide.  That would be written something like this:

form ul li {display: grid;
  grid-template-columns: [start label] 7em [input] 1fr [end];}

Using fixed-width columns to simulate a single column.

That works pretty well so long as none of the labels ever change—if a label is added (or edited) to be wider, it will wrap to multiple lines.  Alternatively, if the longest label is dropped or edited to be shorter, the label column won’t resize down.  It will just stay the same dumb fixed width until someone hand-adjusts it.  And honestly, at that point I may as well be using flexbox, which would do this version of the layout just as well, and would be more widely supported for the near to intermediate future.  At any rate, you can see the grid version of this in the #form2 example on the test page.

But what if we could set a grid on the ul element, and then make all the li elements grids that use their parents’ grid for the layout of their children?  That’s exactly what subgrids do.  This is the solution we’ve been seeking, in basic form:

form ul {display: grid;
  grid-template-columns: [start label] max-content [input] 1fr [end];}
form ul li {display: grid; grid: subgrid; grid-column: start / end;}

Here the list items establish grid containers, thus making the label and input elements into grid items like before, but are stretched across the two columns of the ul while using those very grid lines for laying out their child elements, plus those children influence the placement of their grandparent’s grid lines.  Thus, we can specify things like max-content for the label column size and have it Just Work™.

Or it would Just Work™, except that as I write this, none of the grid implementations have subgrid support.  Authors who want to create the kind of layout we’re after have to compromise in one way or another—either by faking the content-sizing with a fixed-width column, or by stripping down the markup until there’s barely anything left—thus sacrificing accessibility, progressive enhancement, and general best practices, as Fantasai illustrated in her article.

You can probably see a lot of other ways in which subgrids would be useful.  Take defining a full-page grid, the kind with a bunch of regularly repeating grid lines onto which various elements can be attached, like this one or this one.  In this scenario, being able to designate each section of the page a subgrid would let you have all the pieces inside that section participate in, and lay out in relation to, the overall page grid.  Without subgrids, you’d either have to make every element you want to lay out a child of the body element (or whatever you used to create the page grid), or you’d have to recreate segments of the page grid in each nested grid, and give up any hope of columns that can flex with the contents of multiple page sections.  Neither solution is appealing.

This is why I’ve come to the same conclusion other grid experts (like Rachel) already have: subgrids are a major component of grid layout, and should be a part of any grid layout implementation when it emerges from developer-preview status.  If that means delaying the emergence of grids, I think it’s worth it.

I say that because our field has a tendency to glom onto the first iteration of a technology, learn it inside out, hack around its limitations, and then ignore any future improvements unless somehow forced to do so.  If grid layout is released without subgrid support, we’re risking shoving subgrids into the back of the author-practices cupboard for a long time to come.  And along with it, potentially, grids themselves.  The frustration of trying to build layouts without subgrids will quickly become overwhelming for all but the simplest cases, leading authors to try and then discard grids as a serious tool.

First impressions matter.  CSS itself suffered for years from the initial impressions designers formed of “boring, boxy” layouts, and it still suffers from the handicap of being a presentation system without a layout engine at its core.  Grid layout is the first serious candidate to fill that hole in the past two decades, and I don’t want to see them hamstrung from the outset.  Subgrids are essential to the adoption of grids.  I hope they’ll be implemented as soon as possible, and before grids are pushed into public release channels.

January 16th 2016 browsers, CSS, Design