Supporting IE – Part One: Providing basic CSS Grid support.


This post is part one of a three-part series about providing support for IE11 when working with CSS Grid.

Part Two – Finding ways to use CSS Grid Properties that are not supported.
Part Three – The last resort! CSS Grid tips, hacks and workarounds.

There is one question, as frontend developers, that we all dread and that is “will it work in IE11?” 

This is especially true when using CSS Grid. Last year, I spent a lot of time talking about CSS Grid and every conference or meetup I spoke at, I was always asked this question.

I’ve worked with CSS Grid on production sites for 2-3 years now to varying degrees, and where needed, all of them work in IE11 as well. There are times where the experience created for IE11 does not exactly match what has been built for modern browsers, some of the time I’ve written the CSS with progressive enhancement in mind and other times, I’ve had to retrofit my CSS to support IE11 afterwards. Each approach provides its own challenges,  so I thought it would be useful to share some of the techniques I’ve used on different projects in a series of blog posts.

(This article assumes a reasonable knowledge of CSS and some understanding of using CSS Grid.)

CSS Grid is supported in IE11.

A lot of people immediately assume that CSS Grid is not supported in IE11 at all or you need polyfills to make it work. However, an early version of the CSS Grid specification does work in both IE10 and IE11. 

Some of the syntax is different and with some properties, it’s not quite as easy as adding a prefixed version as well, so it is important to understand what is different, but it is possible to build a site using CSS Grid and have it work in IE11. 

Possibly the most useful article I’ve ever read on this and I still refer to it often is Rachel Andrew’s Should I try to use the IE implementation of CSS Grid? It features a really useful table showing the Level 1 Specification of many of the commonly used properties, whether there is an IE version available for that property, and also whether Autoprefixer will recognise it or not.

The Autoprefixer column is out of date now, but I find the direct comparisons between each spec in the table to be really useful still.

Note: After initially posting this article Rachel Andrew pointed me to her follow up article Should I try to use the IE version of Grid Layout? Revisited for 2018.

In it, she discusses whether you should try to support IE11 when using CSS Grid. This is a very valid question and it is perfectly ok not to support CSS Grid in older browsers, however, this series of posts isn’t aiming to tackle that question, it is a series of tips for those times when you do find you have to support it.

Getting Started.

Whenever I think about support for IE11, I look at three key areas:

  1. The display property,
  2. Defining the grid itself and
  3. Placing items within the grid.

If we can make sure all three of these are working as expected within IE11, then you can be confident that 90% of the work is done, the rest is usually small tweaks and edge cases.

From looking at Rachel’s article you would be forgiven for thinking that Autoprefixer is most definitely not the answer, there is a lot it can do for us now. But…

Should we rely on Autoprefixer?

The newer versions of Autoprefixer can create a lot of fallbacks, however, it can’t do all of the hard work for us, there are some limitations still. If you are interested in reading more about what it can and can’t do I would recommend reading CSS Grid in IE: CSS Grid and the new Autoprefixer.

There could also be situations where your build process has to use an older version that cannot do all of this, or the auto-prefixed version creates unexpected changes in your layouts or a myriad of other reasons.

Therefore, I believe it is worth taking the time to fully understand the differences between the Level 1 spec and the modern specification and not rely on Autoprefixer to automatically fix it for us.

Using display: grid;

In order to use CSS Grid on a selector we first need to set the display property to grid, like this: 

 display: grid;

However, the prefixed equivalent for IE is a little different and looks like:

display: -ms-grid;

Note the prefix is applied to the value and not the property itself. 

To define the grid in IE and modern browsers we need to include both lines in our CSS so that it looks like:

display: -ms-grid;
display: grid;

This way IE will see the CSS specifically for that and modern browsers will skip over it and use the newer specification below.

TIP: Often, I will extract both of these display settings into a SASS mixin so that I can always ensure that the -ms- prefix is applied.

I find this helpful, especially when using CSS Grid in multiple places, because even though I could add these two lines to bigger grid mixins (i.e. if I’m defining a layout of posts or a footer layout etc.) there will always be times it is needed outside of other mixins.

There are a number of other subtle differences in how the properties are used as well. 

Using the grid-template-columns and grid-template-rows properties.

Now that we have set the display property to grid, we need to set how many columns and/or rows there will be inside of it. One way to do this is using the grid-template-columns and grid-template-rows properties. 

Autoprefixer can automatically update these for us. So

grid-template-columns: 1fr 1fr 1fr 1fr;

Would become:

-ms-grid-columns: 1fr 1fr 1fr 1fr;

Which is pretty nice and can save us a job! 

The problem here though is that if all of the columns are the same width, you wouldn’t manually write out the value for each column, you would use the repeat() function that was introduced as part of the CSS grid spec instead. Like this:

grid-template-columns: repeat( 4, 1fr );

Autoprefixer would then update that to:

-ms-grid-columns: repeat( 4, 1fr );

Which unfortunately is invalid. This is because although Autoprefixer can fix the grid columns property, but the syntax for repeat() is different. You could write out the values for the columns manually instead.

For example: 

grid-template-columns: repeat( 4, 1fr );

Would have to become:

-ms-grid-columns: 1fr 1fr 1fr 1fr 1fr;

But, if you have a twelve column grid or something even bigger, the gets messy and is pretty laborious. Instead you could use the IE syntax, which would look like:

-ms-grid-columns: 1fr[4];

Instead of using repeat(), we use [ ] and specify the number of times we wish to repeat 1fr. Which is much nicer!

Using the `grid-column` and `grid-row` properties

There is now only one key area left to address, and that is placing items in the grid.

We can do this using the grid-column-start, grid-column-end, grid-row-start and grid-row-end properties, or by using the shorthand properties grid-column and grid-row. For example:

grid-column: 2 / 4;

Or 

grid-column: 2 / span 2;

This tells a content item within the grid to start on column track line number 2 (see further reading if you are unsure of what grid track lines are) and end at track line number 4 and therefore spanning 2 columns.

However, the prefixed version -ms-grid-column only requires and applies a start value. If you rely on Autoprefixer to fix this, you will end up with an invalid property because it would get updated to:

-ms-grid-column: 2 / 4;

when it should actually be 

-ms-grid-column: 2;

This still only goes part of the way to solving the problem of providing a fallback, we have now set a start point, but we still need to tell the grid item that it needs to span 2 columns. In the original property we did that by setting the endpoint to 4 or setting span 2, for IE we need to set a span number using a different property instead like this:

-ms-grid-column-span: 2;

This would make our property and our IE fallback look like:

-ms-grid-column: 2;
-ms-grid-column-span: 2;
grid-column: 2 / 4;

If you wanted your grid item to only span one column you can omit the -ms-grid-column-span property but it still looks pretty ugly.

Add in some row information as well, for example: 

-ms-grid-column: 2;
-ms-grid-column-span: 2;
grid-column: 2 / 4;

-ms-grid-row: 1;
-ms-grid-row-span: 3;
grid-row: 1 / 4;

And suddenly you have a lot of lines of CSS. This is pretty ugly, so I always like to add the  😢🔥🗑emojis in a comment to pretty it up again..

Of course, you don’t have to use the shorthand properties, you could use the longhand versions, but autoprefixer still wouldn’t be able to fix these. -ms-grid-column isn’t a prefixed version of grid-column-start and -ms-grid-column-span sets how many columns to span rather than the column track line to end on. You would end up with even more lines of code:

-ms-grid-column: 2;
grid-column-start: 2;
-ms-grid-column-span: 2;
grid-column-end: 4;

Which, when you add in the row information as well, makes it look even more like code soup:

-ms-grid-column: 2;
grid-column-start: 2;
-ms-grid-column-span: 2;
grid-column-end: 4;

-ms-grid-row: 1;
grid-row-start: 1
-ms-grid-row-span: 3;
grid-row-end: 4;

Using the shorthand version and then providing IE11 fallbacks, may only save one line of code per property but I like to think that every line of code saved, saves a kittens life somewhere in the world!

Finished?

For simple CSS Grid layouts, this is pretty much the extent of what you need to do to ensure they display as expected in IE11. There are no hacks (depending on whether you consider prefixes hacks) and no polyfills needed.

Providing support for IE11 can be tricky but in most cases, many of the problems can be avoided simply by not relying on Autoprefixer to fix it for you. Once you know and understand the differences between the current specification and the IE10 & IE11 specification providing support for older browsers becomes much easier to achieve.


Further Reading:


2 thoughts on “Supporting IE – Part One: Providing basic CSS Grid support.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s