23

Is there a way to use both or either display: grid/-ms-grid into one style sheet or do I have to use an HTML hack or JavaScript to query what type of browser a page is being viewed with grid layout?

Example:

The following styling doesn't seem to work

.container {
  display: grid -ms-grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(150px, 50px);
  grid-gap: 1vw;
  -ms-grid-columns: repeat(4, 1fr);
  -ms-grid-rows: repeat(150px, 50px);
  -ms-grid-gap: 1vw;
}
6
  • Just like to add to this. Microsoft have updated Edge with the Windows 10 Creator's Fall Update to 16, which supports the universal CSS Grid layout. Not too sure about IE11, which still receives security updates
    – Richie
    Commented Dec 21, 2017 at 1:31
  • 4
    IE11 will never get upgraded. It just receives security updates.
    – kumarharsh
    Commented Apr 25, 2018 at 13:48
  • It has been updated, so now you don't need to use the -ms-grid-columns, just plain grid-template will do, unless you haven't updated Windows 10
    – Richie
    Commented Apr 26, 2018 at 23:19
  • I haven't seen this update mentioned for IE anywhere. It's also not visible on my PC (latest FCU updates are installed). Are you referring to Edge?
    – kumarharsh
    Commented Apr 30, 2018 at 7:37
  • Also, grid-template won't be very helpful for IE anyways, due to the requirement of specifying explicit grid-row and grid-column numbers for children in IE.
    – kumarharsh
    Commented Apr 30, 2018 at 7:38

4 Answers 4

39

Transforming new CSS Grid layout syntax to outdated IE's is really a challenge. It's not just a matter of adding some vendor prefixes.

IE has very limited support of what is present in the new version of CSS Grid Layout. There is no IE support of

  • auto-placement and selecting its flow (grid-auto-flow CSS property);
  • repeated columns/rows (repeat function and some special values like auto-fill and auto-fit). In some cases this mean that you'll just have to replace with explicit values, like in your case, you can replace grid-template-columns: repeat(4, 1fr) with -ms-grid-columns: 1fr 1fr 1fr 1fr and this will work perfectly. But if you have something like grid-template-columns: repeat(auto-fill, 1fr) it's impossible to implement this in IE;
  • grid cell gaps (grid-row-gap, grid-column-gap, grid-gap CSS properties). Gaps can be faked using additional grid tracks;
  • automatically generated tracks (grid-auto-columns, grid-auto-rows CSS properties);
  • named grid areas (grid-area, grid-template-areas CSS properties).

You just have to forget about this possibilities for IE.

Also some values of supported IE properties are not supported

Autoplacement

There is no auto-placement behavior in IE implementation. This means that you have to position everything rather than use the auto-placement ability of grid.

If you don’t position items they will stack up in the first cell of the grid. That means that you have to set a position explicitly for every single grid item or it will reside in the first cell. If you have markup like this:

.wrapper {
  display: -ms-grid;
  display: grid;
  grid-gap: 10px;
  -ms-grid-columns: 50px 50px;
  grid-template-columns: 50px 50px;
  -ms-grid-rows: 50px 50px;
  grid-template-rows: 50px 50px;
  background-color: #fff;
  color: #444;
}

.box {
  border-radius: 5px;
  padding: 20px;
  font-size: 150%;
}
<div class="wrapper">
  <div class="box a">A</div>
  <div class="box b">B</div>
  <div class="box c">C</div>
  <div class="box d">D</div>
</div>

You'll see something this in IE

IE grid demo


So basically you have two options (methodologies) when developing CSS Grid for IE (if you know that the layout in your case can be transformed):

  • Generate different markup for IE browser and other browsers. In this case you don't care about markup similarity (by the way your value of grid-template-rows: repeat(150px, 50px) is invalid, so I assume you wanted grid-template-rows: 150px 50px). Demo for your case

    .container {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      grid-template-rows: 150px 50px;
      grid-gap: 1vw;
      
      display: -ms-grid;
      /* also faking 1vw grid-gap */
      -ms-grid-columns: 1fr 1vw 1fr 1vw 1fr 1vw 1fr;
      /* also faking 1vw grid-gap */
      -ms-grid-rows: 150px 1vw 50px;
    }
    
    .grid-item {
      /* style just for demo */
      background-color: yellow;
    }
    
    /* Explicit placement for IE */
    /* Omitting default value of -ms-grid-column: 1 and -ms-grid-row: 1 where possible */
    .grid-item:nth-child(2) {
      -ms-grid-column: 3;
    }
    
    .grid-item:nth-child(3) {
      -ms-grid-column: 5;
    }
    
    .grid-item:nth-child(4) {
      -ms-grid-column: 7;
    }
    
    .grid-item:nth-child(5) {
      -ms-grid-row: 3;
    }
    
    .grid-item:nth-child(6) {
      -ms-grid-row: 3;
      -ms-grid-column: 3;
    }
    
    .grid-item:nth-child(7) {
      -ms-grid-row: 3;
      -ms-grid-column: 5;
    }
    
    .grid-item:nth-child(8) {
      -ms-grid-row: 3;
      -ms-grid-column: 7;
    }
    <div class="container">
      <div class="grid-item">1,1</div>
      <div class="grid-item">1,2</div>
      <div class="grid-item">1,3</div>
      <div class="grid-item">1,4</div>
      <div class="grid-item">2,1</div>
      <div class="grid-item">2,2</div>
      <div class="grid-item">2,3</div>
      <div class="grid-item">2,4</div>
    </div>

  • Generate very similar markup for IE browsers. In this case, markup for all browsers will look very similar. This might be more maintainable because you shouldn't care about different approaches. Demo for your case:

    .container {
      display: -ms-grid;
      display: grid;
      /* also faking 1vw grid-gap */
      -ms-grid-columns: 1fr 1vw 1fr 1vw 1fr 1vw 1fr;
      grid-template-columns: 1fr 1vw 1fr 1vw 1fr 1vw 1fr;
      /* also faking 1vw grid-gap */
      -ms-grid-rows: 150px 1vw 50px;
      grid-template-rows: 150px 1vw 50px;
    }
    
    .grid-item {
      /* style just for demo */
      background-color: yellow;
    }
    
    .grid-item:nth-child(2) {
      -ms-grid-column: 3;
      grid-column: 3;
    }
    
    .grid-item:nth-child(3) {
      -ms-grid-column: 5;
      grid-column: 5;
    }
    
    .grid-item:nth-child(4) {
      -ms-grid-column: 7;
      grid-column: 7;
    }
    
    .grid-item:nth-child(5) {
      -ms-grid-row: 3;
      grid-row: 3;
    }
    
    .grid-item:nth-child(6) {
      -ms-grid-row: 3;
      grid-row: 3;
      -ms-grid-column: 3;
      grid-column: 3;
    }
    
    .grid-item:nth-child(7) {
      -ms-grid-row: 3;
      grid-row: 3;
      -ms-grid-column: 5;
      grid-column: 5;
    }
    
    .grid-item:nth-child(8) {
      -ms-grid-row: 3;
      grid-row: 3;
      -ms-grid-column: 7;
      grid-column: 7;
    }
    <div class="container">
      <div class="grid-item">1,1</div>
      <div class="grid-item">1,2</div>
      <div class="grid-item">1,3</div>
      <div class="grid-item">1,4</div>
      <div class="grid-item">2,1</div>
      <div class="grid-item">2,2</div>
      <div class="grid-item">2,3</div>
      <div class="grid-item">2,4</div>
    </div>

1
  • You can benefit of nth-child(xn+ y) syntax here: .grid-item:nth-child(4n+2){ -ms-grid-column: 3;} , .grid-item:nth-child(4n+3){ -ms-grid-column: 5;}, .grid-item:nth-child(4n+4){ -ms-grid-column: 5;} . You may use it for rows too: .grid-item:nth-child(n+5){-ms-grid-row:3;}, .grid-item:nth-child(n+9){-ms-grid-row:5;} and so on (n+5 means fifth and following). Seen here: nthmaster.com
    – Fanky
    Commented Aug 29, 2018 at 16:34
9

Your display rule needs to be structured correctly. What you have is invalid.

display: grid -ms-grid;

Also, your grid-template-rows rule is invalid. The first argument is supposed to be an integer that specifies the number of repetitions.

grid-template-rows: repeat(150px, 50px);

Also, I don't believe the repeat() notation existed in the older specs. It looks like it was introduced in the current spec, so IE wouldn't support it.

-ms-grid-columns: repeat(4, 1fr);
-ms-grid-rows: repeat(150px, 50px);

Lastly, it's best to put the official (W3C) properties after the prefixed versions so they are given priority in the cascade (more details).

Try this:

.container {
  display: -ms-grid; 
  display: grid;

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

  -ms-grid-rows: 150px 50px;
  grid-template-rows: 150px 50px;

  -ms-grid-gap: 1vw;
  grid-gap: 1vw;
}
1
  • 8
    Nice answer, with links to W3C. But -ms-grid-gap/grid-gap is not working for IE/Edge and has never been. Commented Jul 16, 2017 at 17:21
3

This is what I used for IE:

I added an @supports() for all current browser support. If you use @supports() pass in a new grid property such as @supports(grid-area: auto) to be sure a modern browser will pick it up. Do not use @suppports(display: grid) because IE will recognize display:grid and will then use the modern grid properties that it does not have. I had to use a 1px margin to mimic the grid-gap in IE though

* {
    box-sizing: border-box;
}

.item-bg {
    background-color: rgb(92, 182, 205);
    border-radius: 6px;
    margin: 1px;
}

.container {
    display: -ms-grid;
    
   width: 800px;
    height: 600px;
    -ms-grid-columns: 200px 1fr 1fr;
    -ms-grid-rows: 80px 1fr 1fr 100px;
    
    
    
    }


.header {
    -ms-grid-row: 1;
    -ms-grid-row-span: 1;
    grid-row: 1/2;
    -ms-grid-column: 1;
    -ms-grid-column-span: 3;
    grid-column: 1/4;

}
.sidebar {
    -ms-grid-row: 2;
    -ms-grid-row-span: 2;
    grid-row: 2/4;
    -ms-grid-column: 1;
    -ms-grid-column-span: 1;
    grid-column: 1/2;

}
.content-1 {
    -ms-grid-row: 2;
    -ms-grid-row-span: 1;
    grid-row: 2/3;
    -ms-grid-column: 2;
    -ms-grid-column-span: 2;
    grid-column: 2/4;

}
.content-2 {
    -ms-grid-row: 3;
    -ms-grid-row-span: 1;
    grid-row: 3/4;
    -ms-grid-column: 2;
    -ms-grid-column-span: 1;
    grid-column: 2/3;

}
.content-3 {
    -ms-grid-row: 3;
    -ms-grid-row-span: 1;
    grid-row: 3/4;
    -ms-grid-column: 3;
    -ms-grid-column-span: 1;
    grid-column: 3/4;
}
.footer {
    -ms-grid-row: 4;
    -ms-grid-row-span: 1;
    grid-row: 4/5;
    -ms-grid-column: 1;
    -ms-grid-column-span: 3;
    grid-column: 1/4;
}
@supports(grid-area: auto){
    .item-bg {
        background-color: indianred;
        border-radius: 6px;
        margin: 0;
    }
    
    .container {
        display: grid;
        width: 750px;
        height: 600px;
        grid-template-columns: 200px 1fr 1fr;
        grid-template-rows: 80px 1fr 1fr 100px;
        grid-gap: 2px;
        }
    .header {
        grid-row: 1/2;
        grid-column: 1/4;
    
    }
    .sidebar {
        grid-row: 2/4;
        grid-column: 1/2;
    
    }
    .content-1 {
        grid-row: 2/3;
        grid-column: 2/4;
    
    }
    .content-2 {
        grid-row: 3/4;
        grid-column: 2/3;
    
    }
    .content-3 {
        grid-row: 3/4;
        grid-column: 3/4;
    }
    .footer {
        grid-row: 4/5;
        grid-column: 1/4;
    }
}

The html is

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Basic Layout</title>
        <link rel="stylesheet" href="basiclayoutie.css" type="text/css">
    </head>
    <body>
        <div class="container">
            <div class="header item-bg">header</div>
            <div class="sidebar item-bg">sidebar</div>
            <div class="content-1 item-bg">Content-1</div>
            <div class="content-2 item-bg">Content-2</div>
            <div class="content-3 item-bg">Content-3</div>
            <div class="footer item-bg">Footer</div>
        </div>
    </body>
</html>
1

The answer by Vadim is pretty much what you should do. But there are a few more CSS tricks you can use to ease your pain.

0. Be sure to read this blog post to decide whether you want to use grids for websites which support IE: https://rachelandrew.co.uk/archives/2016/11/26/should-i-try-to-use-the-ie-implementation-of-css-grid-layout/

If your answer to the previous question is "Yes", read on:

  1. Use autoprefixer. It will replace some of the CSS-grid properties to their IE equivalent. But given how complex the grid properties can be (repeats, minmax, spans, etc), autoprefixer can't cover all cases.
  2. A very trusty companion in cases when you want to write spec-compliant CSS, but still support IE is the @supports() at-rule. I use it to use the more advanced grid properties such as grid-gaps, etc:

    .card-list {
      grid-row: 4;
      grid-column: 1 / 3;
      padding: 1.5vh 1vh;
      display: grid;
      grid-template-rows: 1fr 1fr;
      grid-template-columns: 1fr 1fr;
    }
    .card {
      margin-bottom: 1vh;
    }
    .card:nth-of-type(odd) {  /* takes care of IE */
      margin-right: 1vh;
      grid-column: 1;
    }
    .card:nth-of-type(even) {
      grid-column: 2;
    }
    
    @supports(grid-gap: 1vh) { /* still using standard code! */
      .card-list {
        grid-gap: 1vh;
      }
      .card {
        margin-right: 0;
        margin-bottom: 0;
      }
    }
    

Not the answer you're looking for? Browse other questions tagged or ask your own question.