CSS Grid in IE: Debunking Common IE Grid Misconceptions

Avatar of Daniel Tonon
Daniel Tonon on (Updated on )

📣 Freelancers, Developers, and Part-Time Agency Owners: Kickstart Your Own Digital Agency with UACADEMY Launch by UGURUS 📣

This is the first in a three-part series all about how to use CSS grid in a way that will work not only in modern browsers but also in Internet Explorer (IE). Imagine writing CSS grid code without having to write a fallback layout! Many of us think that this is some far off future that is many years away. If the only thing holding you back from that reality is IE11 (check caniuse.com), then you’re in luck! That day is today! Or at least it will be when you finish reading this series. 😉

Article Series:

  1. Debunking common IE Grid misconceptions (This Post)
  2. CSS Grid and the new Autoprefixer
  3. Faking an auto-placement grid with gaps
  4. Duplicate area names now supported!

To start off, this first part is going to debunk some common misconceptions around IE11’s native grid implementation.

In Part 2, I’m going to blow the lid off the myth that using CSS grid in IE11 is super hard. No more crappy fallback layouts for IE11!

In Part 3, I’ll show you a cool flexbox technique that I use for creating simple auto-placement grids. These fake auto-placement grids have fixed pixel-based grid gaps that line up perfectly with ones created using real CSS grid. They work perfectly in IE11, are fully responsive, and updating their column count based on screen width only requires changing a single width value in a media query.

That’s enough intro’s lets get started on these misconceptions!

IE does have an implicit grid

In CSS grid, the explicit grid is the one that you manually define with all of the grid-template-* properties. The implicit grid is how the browser handles the placement of cells that are placed outside of the explicit grid.

When using CSS grid in modern browsers, the implicit grid is pretty obvious since the grid will continue to create and place grid cells automatically on new rows without having to define them. IE doesn’t have auto-placement, so it’s easy to assume that IE doesn’t have an implicit grid. It does though — you just need to be a bit more explicit when it comes to using it.

See the Pen Explicit vs implicit grid by Daniel Tonon (@daniel-tonon) on CodePen.

The most common use case for using IE’s implicit grid is using it to generate your rows for you. If you want all the rows in the grid to have their height dictated by the height of their content, you do not need to bother defining -ms-grid-rows (the IE version of grid-template-rows). The rows will automatically be generated for you in IE when placing your grid cells.

An important thing to note though is that modern browsers have access to the properties grid-auto-rows and grid-auto-columns. These properties allow you to control how the browser handles the size of rows and columns in the implicit grid. IE has no concept of these properties. IE’s implicit rows and columns can only ever be sized as auto.

IE has repeat functionality

Do not fear! There is no need to write out 1fr 20px 12 times for your precious 12-column grid (IE doesn’t have native grid-gap support). IE comes pre-packaged with full repeat() functionality. It’s just hiding behind a different syntax.

The modern syntax for repeating values in columns and rows is repeat(12, 1fr 20px) meaning, “repeat the 1fr 20px pattern 12 times.” The IE version of the syntax is (1fr 20px)[12]. The IE version has identical functionality, just a different syntax.

/* This grid... */
.grid-one {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 1fr 20px 1fr 20px 1fr 20px 1fr;
  grid-template-columns: 1fr 20px 1fr 20px 1fr 20px 1fr;
}

/* ...is exactly the same as this grid: */
.grid-two {
  display: -ms-grid;
  display: grid;

  /* IE repeat syntax */
  -ms-grid-columns: 1fr (20px 1fr)[3];

  /* Modern repeat syntax */
  grid-template-columns: 1fr repeat(3, 20px 1fr);
}

Other than syntax, there is only one difference between the way modern browsers and IE implement the repeat() function. Modern browsers added the auto-fit and auto-fill keywords to the function. Since IE doesn’t support auto-placement, those keywords are pretty meaningless to IE so avoid using them.

minmax() is natively supported in IE

minmax() is a CSS sizing function that is exclusive to CSS grid (at the moment, anyway). Its functionality is pretty self explanatory. You provide it a minimum value in the first parameter and a maximum value in the second parameter. The column or row that this is applied to is then able to shrink and grow between those two values as the space available to it increases and decreases. Try resizing the codepen below to see it in action.

See the Pen minmax() demo by Daniel Tonon (@daniel-tonon) on CodePen.

People often think that this awesome little feature isn’t supported in IE but it is in fact natively supported. I’m guessing this is due to at least one of these two reasons:

  1. It’s cool functionality and they think IE can’t have cool things like this because IE sucks.
  2. Everyone has seen this magical code snippet and had their dreams shattered when they realised that it wouldn’t work in IE: grid-template-columns: repeat( auto-fit, minmax(250px, 1fr) );.

(If you have never seen that snippet before, watch this short video and prepare to have your mind blown.)

Since the magic snippet doesn’t work in IE, people probably assume that nothing in the snippet is IE-friendly. In reality, the only reason why the code snippet isn’t replicable in IE is because IE doesn’t support the auto-fit keyword and auto-placement.

min-content and max-content are both 100% IE-friendly

IE has full native support for both the min-content and max-content values.

min-content is a keyword value that will shrink the column/row down to the minimum possible width that the content can shrink down to. If applied to a column, this essentially means that the column will be the width of the longest word.

See the Pen min-content demo by Daniel Tonon (@daniel-tonon) on CodePen.

max-content, on the other hand, will grow the column/row up to the maximum possible width that its content takes up, and no further. If you have ever set white-space: nowrap on a large section of text, this will appear very similar.

See the Pen max-content demo by Daniel Tonon (@daniel-tonon) on CodePen.

I wasn’t expecting IE to support these values mainly because of reason one under minmax(). I was happily surprised when I was proven wrong while researching IE11 grid support. In combination with minmax(), there aren’t many grids that a modern browser can make that IE can’t handle (as long as the grids don’t involve auto-placement).

fit-content() is not IE friendly but

fit-content() doesn’t work natively in IE. 😢

Fortunately, fit-content() is kind of a shorthand syntax and when you write it out the long way, IE does support it! 🎉

The long way to write it is by applying auto (or more specifically, minmax(min-content, max-content)) to the column/row in the grid template, then setting max-width: [value] on the child element.

Here is an example of how you might use the fit-content() function in a modern browser:

/* This is not IE-friendly */
.grid {
  display: grid;
  grid-template-columns: 100px fit-content(300px) 1fr;
}

.cell {
  grid-column: 2;
}

What fit-content() is basically saying here is, “make the middle column take up the maximum possible width of its content (i.e. its max-content value) up until it reaches 300px at which point, don’t grow any larger unless forced to.”

See the Pen fit-content() modern example 1 by Daniel Tonon (@daniel-tonon) on CodePen.

If you are reading this on mobile, view this sections Codepen demos in landscape orientation for a better understanding.

In order to make IE behave in kind of the same way, you would need to write the code like this:

/* IE-friendly `fit-content()` alternative */
.grid {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 100px auto 1fr;
  grid-template-columns: 100px auto 1fr;
}

.cell {
  -ms-grid-column: 2;
  grid-column: 2;
  max-width: 300px;
}

See the Pen fit-content IE hack by Daniel Tonon (@daniel-tonon) on CodePen.

Note that this is not a fool-proof method of replicating fit-content() in IE. If there is another grid cell that has content that takes up more width than the max-width setting of the other cell, the grid column will grow to fit the larger cell. It will not be clamped at 300px like it would with fit-content().

See the Pen Broken fit-content hack by Daniel Tonon (@daniel-tonon) on CodePen.

Compare that to the modern fit-content() function which clamps the entire column:

See the Pen fit-content() modern example by Daniel Tonon (@daniel-tonon) on CodePen.

While I’m on the subject, I should clear up a common misconception around the fit-content() function itself. The misconception is that the column (or row) that it is applied to can never exceed the value that you provided the function. This is not the case. If a column is set to a width of fit-content(300px), and a grid cell inside that column is set to a width of 400px, the column width will be 400px, not 300px as many people might expect.

See the Pen Broken modern fit-content by Daniel Tonon (@daniel-tonon) on CodePen.

IE auto != Modern auto

The auto value in IE behaves a bit differently than auto in modern browsers. In IE, auto strictly equals minmax(min-content, max-content). A column or row set to auto in IE can never shrink any smaller than min-content. It also can never grow any larger than max-content.

Modern browses treat the auto value a bit differently. For the most part, when the value is used on its own, they still treat auto like minmax(min-content, max-content). There is one small but critical difference though: auto in modern browsers is able to be stretched by the align-content and justify-content properties. IE doesn’t allow that.

When auto is used for sizing columns in a modern browser, auto behaves more like 1fr if there isn’t enough content to fill the column. IE does not. IE will always shrink the column down to the size of max-content.

So, if you have this code defining your grid:

.grid {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: auto auto;
  grid-template-columns: auto auto;
}

You will end up with this in modern browsers:

Modern browser auto width columns with little content. Columns fill the grid.

…and this in IE:

IE auto width columns with little content. Columns shrink to the content.

Ok, the modern browser one looks a lot like what we get when we use 1fr. Can we use minmax(min-content, 1fr) for IE then? That will stretch it out like it does in modern browsers won’t it?

Yes, but then we run into this issue:

.grid {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: minmax(min-content, 1fr) minmax(min-content, 1fr);
  grid-template-columns: auto auto;
}

Modern browsers:

Modern browser auto width columns with lots of content in one cell. Columns are different widths.

IE:

IE minmax(min-content, 1fr) columns with lots of content in one cell. Columns are equal widths.

FYI, minmax(min-content, 1fr) is essentially 1fr and 1fr and does not equal auto. I also tried minmax(min-content, 100%) in IE but that just resulted in the same looking grid as using 1fr. As far as I can tell, it’s not possible to replicate the modern browser auto functionality in IE.

There is another critical difference between IE and modern versions of the auto value though. Since the IE version of auto explicitly equals minmax(min-content, max-content), auto cannot be used in minmax() expressions. minmax() cannot be used inside another minmax() function so auto is disqualified.

Modern browsers are a bit more nuanced. They recognize that auto can mean different things in different contexts. If used on its own, it essentially equals minmax(min-content, max-content) but with the added ability to stretch. When used as a max value, auto is identical to max-content. When used as a min value it essentially equals min-content.

If, right now, you are vowing to never use auto in your grid templates ever again, you may want to rethink that. There are only three circumstances where auto will behave differently between modern browsers and IE. Those are:

  1. auto is being used in grid-template-columns without an fr unit in the same declaration.
  2. auto is being used in grid-template-rows without an fr unit in the same declaration and the height of the grid is greater than the height of its grid cells.
  3. auto is being used in a minmax() function.

That’s it! Those are the only times when auto will behave differently in IE to how it behaves in modern browsers. auto is much easier to write than minmax(min-content, max-content) so it’s not really worth condemning it over a few little browser inconsistencies that are easily avoidable.

(Update) IE Grid does not work on display: inline elements

If you are using <span> or <a> elements as grid cells in your grid, you will be surprised when you go to test in IE that your grid does not look as expected. All of your block level elements (eg. <p>, <div>, <ul> etc.) will appear to work in the grid as expected but your inline elements ( eg. <span>, <a>, <label> etc.) will not.

Span element works correctly in modern browsers but not in IE if using default CSS display settings.

Unfortunately IE Grid is not able to place display: inline elements into a grid correctly. Both <span> and <a> elements are set to display: inline by default in browsers. Don’t worry though, you can easily fix this issue in IE by explicitly setting the inline element to display: block.

Span element works correctly in both modern browsers and in IE if the span is set to display block.

See the Pen
inline grid items don’t work in IE
by Daniel Tonon (@daniel-tonon)
on CodePen.

By default, HTML 5 elements like <main>, <header>, and <footer> are normally set to display: block in browsers. However since these elements were released after IE11 came out, IE11 does not recognise them. Unrecognized elements revert to being the equivalent of <span> elements in nonsupporting browsers. This means that if they become grid items, they will by default not work in IE.

You can make these modern elements work as expected by explicitly setting them to display: block. Alternatively, you can add normalize.css to your project which will do this for you. It will also do a bunch of other little things that make your development experience more enjoyable.

So what have we learned?

  • IE does have an implicit grid.
  • IE supports repeat functionality.
  • minmax(), min-content and max-content are all natively supported.
  • fit-content() isn’t supported but you can work around it with auto and max-width settings.
  • IE auto is not equal to auto in modern browsers.
  • IE Grid does not work on display: inline elements.

Don’t get the grids out just yet though. There are still a lot of things that you need to know before you can start safely implementing IE grids into your websites. Make sure to stick around for Part 2! I will be showing you everything you need to know to safely build sites for both IE and modern browsers using only CSS grid. Best of all, there will be no more need for crappy fallback layouts!

Article Series:

  1. Debunking common IE Grid misconceptions (This Post)
  2. CSS Grid and the new Autoprefixer
  3. Faking an auto-placement grid with gaps
  4. Duplicate area names now supported!