CSS grid with Angular and CLI – the time is now

Today, early December 2017, is the time to begin using CSS grid for layout in Angular applications, even if they must support Internet Explorer. We can stop enduring the costs and delays of old “float” based CSS layout, and get better results with less work, using CSS Grid – even with Internet Explorer support requirements – with caveats described below.

Take a look at a running example on the browser of your choice, including both modern browsers and IE11.

https://oasisdigital.github.io/cli-css-grid-demo/

Background

If you’re not familiar with CSS grid, the best source is Rachel Andrew, the global guru of CSS grid. Either read and all of her Grid content, or peruse the links below (thanks mostly to Bill Odom, our early CSS Grid cheerleader, for gathering these). Now is a good time to read and watch, I’ll wait.

Welcome back, CSS Grid fan. Of course the big problem with Grid today is that while support is excellent among current browsers, many users (especially paying, enterprise users) are still wallowing in Internet Explorer. IE has basic support for CSS Grid, but the support is for an older spec which has both fewer features and different syntax. The syntax is irritatingly different enough that manually maintaining both is prone to error.

Fortunately, the incredible Autoprefixer does a very good job, in version 7, of papering over the syntactic differences. In many cases the benefits of Grid can be obtained even without the newer semantics.

Yak shave

Unfortunately, Angular CLI (as of version 1.6.1, as I write this) uses Autoprefixer 6, and exposes no way to adjust Autoprefixer settings. This CLI issue tracker has many open issues, and it appears the team is closely focused on core application bundling and ergonomic considerations, so it’s hard to predict when CLI team attention could turn to issues like this.

Yet here at Oasis Digital, we are ready to use Grid today, and our customers are ready to deploy software today. Therefore, a series of workarounds is in order. To see them in action and in detail, visit this demo repository:

https://github.com/OasisDigital/cli-css-grid-demo

…and for an explanation, read on.

Upgrading Autoprefixer

To use version 7 in an Angular CLI app today, a way must be found to override the Autoprefixer dependency. The traditional answer to override dependencies and settings in CLI is to “eject” – but that is a big leap, not easily reversed, and not recommended. An application based on ejected CLI presents a greater maintenance burden for developers. Instead, we generally recommend sticking with CLI but applying whatever patches are needed at run time to get the right behavior.

Unfortunately as of late 2017, it is still unduly difficult to override dependencies with NPM; searches looking for the way to do it, lead in circles toward old NPM versions. Happily, Yarn can do it quite easily, as a first-class feature. Switch to Yarn, then add a section like this to the package.json file:

"resolutions": {
  "autoprefixer": "^7.2.3"
}

Turn on grid support

Next, Angular CLI does not yet provide a way to pass options to Autoprefixer, and using Grid requires turning the support on. To work past this, the venerable approach of “monkey patch in a postinstall script” solves the problem easily. The script content is essentially just:

sed -i.bak -e 's/autoprefixer()/autoprefixer({grid:true})/' \
 node_modules/@angular/cli/models/webpack-configs/styles.js

This reaches into the relevant file inside the installed CLI code, and edits it in place. I think of this as a rough but necessary hack, to deliver value today, reaching ahead to the future when the tools will make the hack unnecessary.

Fortunately, between these two workarounds there are just a few lines of edit needed in a project. Study the repository above (especially the second commit in the commit history) to see the exact changes.

Conclusion and caveats

Of course there are caveats here, explained in depth by the Rachel Andrew page I linked above. The situation is not quite as severe as that page suggests though, because of what Autoprefixer does. With this setup, you can use today’s Grid syntax, but the subset of Grid semantics supported by IE. This means:

  • Use modern grid-column definitions etc., no need for the older “span” concept.
  • No “flow” in to grid cells – assign grid locations manually. Fortunately, for application layout Flow manual assignment is common anyway.
  • No “gaps” – leave an empty track instead. Easily done.
  • No grid-template-areas.
  • As always, remember to test on IE.

While these caveats are a bit frustrating (especially the lack of grid-template-area), this use of Grid is still an enormous improvement over legacy CSS approaches for many (or most) application screen layouts. With this approach, I see no further reason to wait to start using Grid broadly in Angular applications.

Future work

If the lack of grid-template-areas proves too frustrating, I may look at a similar approach to squeeze in support for postcss-grid-kiss; it provides syntax far beyond that offered by grid-template-areas, and also provides more semantics on IE through use of greater CSS contortions.