Autoprefixer: CSS-Grid wrong ms prop values w/ media queries

Created on 13 Dec 2017  路  18Comments  路  Source: postcss/autoprefixer

Description
When a container with display: grid; changes the grid-template-areas property in a media query, children with a grid-area property will end up with values for -ms-grid-row, -ms-grid-column and -ms-grid-column-span that correspond to whichever grid-template-areas comes first, any other instances are ignored resulting in wrong placement.

Expected or desired result
Depending on whether you consider this a bug, an oversight or a feature request ;)

Children with a grid-area property should be rendered once inside a new media query for each time its parent's grid changes with MS values corresponding to these new grid values.

Example
I don't know how to add the grid: true config option to CodePen's Autoprefixer so unfortunately, you're going to have to try this example locally. Here's a link to the pen anyway, in case anyone knows.

If you let Autoprefixer transpile the following code you'll notice that the third box will have only received -ms- property values for the 768px media query and that it will still span two columns and be on a second row which no long exists above 1200px.

<div class="container">
  <div class="box boxFirst">First box</div>
  <div class="box boxSecond">Second box</div>
  <div class="box boxThird">Third box</div>
</div>
@media screen and (min-width: 768px) {
  .container {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto;
    grid-template-areas:
      "boxFirst boxSecond"
      "boxThird boxThird";
  }
}

@media screen and (min-width: 1200px) {
  .container {
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: auto;
    grid-template-areas:
      "boxFirst boxSecond boxThird";
  }
}

.box { padding: 16px; text-align: center; color: white; font-family: sans-serif; }

.boxFirst { grid-area: boxFirst; background-color: #90afc5;  }
.boxSecond { grid-area: boxSecond; background-color: #2a3132; }
.boxThird { grid-area: boxThird; background-color: #763626; }

After transpilation:

.boxThird {
  background-color: background-color: #763626;
  -ms-grid-row: 2;
  -ms-grid-column: 1;
  -ms-grid-column-span: 2;
  grid-area: boxThird;
}

Expected after transpilation:

@media screen and (min-width: 768px) {
  .boxThird {
    background-color: background-color: #763626;
    -ms-grid-row: 2;
    -ms-grid-column: 1;
    -ms-grid-column-span: 2;
    grid-area: boxThird;
  }
}

@media screen and (min-width: 1200px) {
  .boxThird {
    background-color: background-color: #763626;
    -ms-grid-row: 1;
    -ms-grid-column: 3;
    -ms-grid-column-span: 1;
    grid-area: boxThird;
  }
}
enhancement support

Most helpful comment

Released in 7.2.3. @evgeny-petukhov was really quick in solving this issue.

All 18 comments

@evgeny-petukhov seems like we need to insert rules to first parent.type === "atrule || parent.type === "root". Do you want to fix it?

Yes, I'll fix it. @ai How do you think what tests can cover this situation?
I want to fully support media query, and insert different positions for different media (like the example in issue), but it's not a hotfix, it needs more time.

You don't need to create another media, just find first at-rule parent and insert new rules there instead of inserting to root

I will release a fix few hours later, when I will be at home

Released in 7.2.3. @evgeny-petukhov was really quick in solving this issue.

Thanks for the quick work!

Might be worth mentioning somewhere that this solution requires the elements that you want to position within the grid and their parent, to be located under the same media query and that the grid-area property has to be declared again for every child each time you change the grid in the parent.

My test website broke (layout was messed up and autoprefixer warning that grid areas couldn't be found) so I had to figure it out by looking at the changes in the commit.

Here's the code that didn't work, I'm using Stylus with the Rupture plugin for media queries:

.parent
  display grid
  +above(768px)
    grid-template-columns 1fr 1fr
    grid-template-rows auto auto
    grid-template-areas \
      'boxFirst boxSecond' \
      'boxThird boxThird'
  +above(1200px)
    grid-template-columns 1fr 1fr 1fr
    grid-template-rows auto
    grid-template-areas \
      'boxFirst boxSecond boxThird'

.boxFirst
  grid-area boxFirst

.boxSecond
  grid-area boxSecond

.boxThird
  grid-area boxThird

@pcjmfranken can you show me CSS, which was passed to Autoprefixer and CSS from Autoprefixer?

For example, just add console.log to PostCSS.

I'm sorry, I don't quite understand where to add the console.log to get the CSS that was passed to Autoprefixer (using Webpack).

What I do have for you is the input Styl and the output CSS:

Input Styl

.parent
  display grid
  color white
  text-align center
  +above(768px)
    grid-template-columns 1fr 1fr
    grid-template-rows auto auto
    grid-template-areas \
      'boxFirst boxSecond' \
      'boxThird boxThird'
  +above(1200px)
    grid-template-columns 1fr 1fr 1fr
    grid-template-rows auto
    grid-template-areas \
      'boxFirst boxSecond boxThird'

.boxFirst
  background-color #90afc5
  grid-area boxFirst

.boxSecond
  background-color #2a3132
  grid-area boxSecond

.boxThird
  background-color #763626
  grid-area boxThird

Output CSS

.parent
  display grid
  color white
  text-align center
  +above(768px)
    grid-template-columns 1fr 1fr
    grid-template-rows auto auto
    grid-template-areas \
      'boxFirst boxSecond' \
      'boxThird boxThird'
  +above(1200px)
    grid-template-columns 1fr 1fr 1fr
    grid-template-rows auto
    grid-template-areas \
      'boxFirst boxSecond boxThird'

.boxFirst
  background-color #90afc5
  grid-area boxFirst

.boxSecond
  background-color #2a3132
  grid-area boxSecond

.boxThird
  background-color #763626
  grid-area boxThird

Warning

warning  in ./src/test/test.styl

autoprefixer: .\src\test\test.styl:14:4: Can not find grid areas: boxFirst, boxSecond, boxThird

Temporary solution: dublicate grid-area inside media-query.

@evgeny-petukhov you will not like this 馃槄 seems like in case when we didn't find area in media we need do to root, find selector, then create new rule in media query.

@ai I wanted to implement this solution but it's not so quick. I am working on it.

Of course 馃憤 it doesn't look as quick fix for me too 馃槄

Sorry for being your CSS Grid party pooper this week 馃挬

Your temporary solution doesn't work, at least not in the following way:

Input Styl
Added grid-area for each media query.

.parent
  display grid
  color white
  text-align center
  +above(768px)
    grid-template-columns 1fr 1fr
    grid-template-rows auto auto
    grid-template-areas \
      'boxFirst boxSecond' \
      'boxThird boxThird'
  +above(1200px)
    grid-template-columns 1fr 1fr 1fr
    grid-template-rows auto
    grid-template-areas \
      'boxFirst boxSecond boxThird'

.boxFirst
  background-color #90afc5
  +above(768px)
    grid-area boxFirst
  +above(1200px)
    grid-area boxFirst

.boxSecond
  background-color #2a3132
  +above(768px)
    grid-area boxSecond
  +above(1200px)
    grid-area boxSecond

.boxThird
  background-color #763626
  +above(768px)
    grid-area boxThird
  +above(1200px)
    grid-area boxThird

Output CSS
It just repeat-outputs the children without actually transpiling their grid-area prop into -ms- props.

.parent {
  display: -ms-grid;
  display: grid;
  color: #fff;
  text-align: center
}

@media only screen and (min-width: 768px) {
  .parent {
    -ms-grid-columns:1fr 1fr;
    grid-template-columns: 1fr 1fr;
    -ms-grid-rows: auto auto;
    grid-template-rows: auto auto;
    grid-template-areas: "boxFirst boxSecond" "boxThird boxThird"
  }
}

@media only screen and (min-width: 1200px) {
  .parent {
    -ms-grid-columns:1fr 1fr 1fr;
    grid-template-columns: 1fr 1fr 1fr;
    -ms-grid-rows: auto;
    grid-template-rows: auto;
    grid-template-areas: "boxFirst boxSecond boxThird"
  }
}

.boxFirst {
  background-color: #90afc5
}

@media only screen and (min-width: 768px) {
  .boxFirst {
    grid-area:boxFirst
  }
}

@media only screen and (min-width: 1200px) {
  .boxFirst {
    grid-area:boxFirst
  }
}

.boxSecond {
  background-color: #2a3132
}

@media only screen and (min-width: 768px) {
  .boxSecond {
    grid-area:boxSecond
  }
}

@media only screen and (min-width: 1200px) {
  .boxSecond {
    grid-area:boxSecond
  }
}

.boxThird {
  background-color: #763626
}

@media only screen and (min-width: 768px) {
  .boxThird {
    grid-area:boxThird
  }
}

@media only screen and (min-width: 1200px) {
  .boxThird {
    grid-area:boxThird
  }
}

Working temporary solution

A cleaner temporary solution can be found in this comment.

Repeated parent grid-template-areas prop and children's grid-area prop for each media query where grid-template-areas prop changes.

Input Styl

.parent
  display grid
  color white
  text-align center

.boxFirst
  background-color #90afc5

.boxSecond
  background-color #2a3132

.boxThird
  background-color #763626

+above(768px)
  .parent
    grid-template-columns 1fr 1fr
    grid-template-rows auto auto
    grid-template-areas \
      'boxFirst boxSecond' \
      'boxThird boxThird'

  .boxFirst
    grid-area boxFirst

  .boxSecond
    grid-area boxSecond

  .boxThird
    grid-area boxThird

+above(1200px)
  .parent
    grid-template-columns 1fr 1fr 1fr
    grid-template-rows auto
    grid-template-areas \
      'boxFirst boxSecond boxThird'

  .boxFirst
    grid-area boxFirst

  .boxSecond
    grid-area boxSecond

  .boxThird
    grid-area boxThird

Output CSS

.parent {
  display: -ms-grid;
  display: grid;
  color: #fff;
  text-align: center
}

.boxFirst {
  background-color: #90afc5
}

.boxSecond {
  background-color: #2a3132
}

.boxThird {
  background-color: #763626
}

@media only screen and (min-width: 768px) {
  .parent {
    -ms-grid-columns:1fr 1fr;
    grid-template-columns: 1fr 1fr;
    -ms-grid-rows: auto auto;
    grid-template-rows: auto auto;
    grid-template-areas: "boxFirst boxSecond" "boxThird boxThird"
  }

  .boxFirst {
    -ms-grid-row: 1;
    -ms-grid-column: 1;
    grid-area: boxFirst
  }

  .boxSecond {
    -ms-grid-row: 1;
    -ms-grid-column: 2;
    grid-area: boxSecond
  }

  .boxThird {
    -ms-grid-row: 2;
    -ms-grid-column: 1;
    -ms-grid-column-span: 2;
    grid-area: boxThird
  }
}

@media only screen and (min-width: 1200px) {
  .parent {
    -ms-grid-columns:1fr 1fr 1fr;
    grid-template-columns: 1fr 1fr 1fr;
    -ms-grid-rows: auto;
    grid-template-rows: auto;
    grid-template-areas: "boxFirst boxSecond boxThird"
  }

  .boxFirst {
    -ms-grid-row: 1;
    -ms-grid-column: 1;
    grid-area: boxFirst
  }

  .boxSecond {
    -ms-grid-row: 1;
    -ms-grid-column: 2;
    grid-area: boxSecond
  }

  .boxThird {
    -ms-grid-row: 1;
    -ms-grid-column: 3;
    grid-area: boxThird
  }
}

Hopefully this information helps you reach a solution. May the force be with you.

For temporary solution you need to put them in that same media query

Yes of course you're right. Oversight on my end.

The following code works (stylus can get a bit messy if you're not used to it):

.parent
  display grid
  color white
  text-align center

  +above(768px)
    grid-template-columns 1fr 1fr
    grid-template-rows auto auto
    grid-template-areas \
      'boxFirst boxSecond' \
      'boxThird boxThird'
    .boxFirst
      grid-area boxFirst
    .boxSecond
      grid-area boxSecond
    .boxThird
      grid-area boxThird

  +above(1200px)
    grid-template-columns 1fr 1fr 1fr
    grid-template-rows auto
    grid-template-areas \
      'boxFirst boxSecond boxThird'  
    .boxFirst
      grid-area boxFirst
    .boxSecond
      grid-area boxSecond
    .boxThird
      grid-area boxThird

updated with expected CSS
I'm having a little trouble with this

I created a codepen https://s.codepen.io/Seanom/debug/ZqpxzL/xJAjOqyDXvjk (codepen appears to be using Autoprefixer version 8.6.0)
If I'm applying the above comments correctly the the following should work, but the grid columns only work for the initial grid deceleration outside of the media query

I had used the same area names but decided to change them to see if that made a difference
This is the input CSS

.c-contact-panel {
  display: grid;
  grid-gap: 32px;
  grid-template:
    "mob-a" 1fr 
    "mob-b" 1fr
    "mob-c" 1fr / 
    1fr
    ;
  border: 2px solid black;
  padding: 32px;
}

.c-contact-panel__local {
  grid-area: mob-a;
}

.c-contact-panel__international {
  grid-area: mob-b;
}

.c-contact-panel__address {
  grid-area: mob-c;
}

@media (min-width: 960px) {
  .c-contact-panel {
    grid-template:
      "tab-a tab-c" 1fr
      "tab-b tab-c" 1fr /
       1fr    1fr;
  }

  .c-contact-panel__local {
    grid-area: tab-a;
  }

  .c-contact-panel__international {
    grid-area: tab-b;
  }

  .c-contact-panel__address {
    grid-area: tab-c;
  }
}

This is the compiled CSS

.c-contact-panel {
  display: -ms-grid;
  display: grid;
  grid-gap: 32px;
  -ms-grid-rows: 1fr 32px 1fr 32px 1fr;
  -ms-grid-columns: 1fr;
      grid-template:
    "mob-a" 1fr 
    "mob-b" 1fr
    "mob-c" 1fr / 
    1fr
    ;
}
.c-contact-panel__local {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
  grid-area: mob-a;
}

.c-contact-panel__international {
  -ms-grid-row: 3;
  -ms-grid-column: 1;
  grid-area: mob-b;
}

.c-contact-panel__address {
  -ms-grid-row: 5;
  -ms-grid-column: 1;
  grid-area: mob-c;
}

@media (min-width: 960px) {
  .c-contact-panel {
    -ms-grid-rows: 1fr 1fr;
    -ms-grid-columns: 1fr 1fr;
        grid-template:
      "tab-a tab-c" 1fr
      "tab-b tab-c" 1fr /
       1fr    1fr;
  }

  .c-contact-panel__local {
    grid-area: tab-a;
  }

  .c-contact-panel__international {
    grid-area: tab-b;
  }

  .c-contact-panel__address {
    grid-area: tab-c;
  }
}

This is the expected CSS

.c-contact-panel {
  display: -ms-grid;
  display: grid;
  grid-gap: 32px;
  -ms-grid-rows: 1fr 32px 1fr 32px 1fr;
  -ms-grid-columns: 1fr;
      grid-template:
    "mob-a" 1fr 
    "mob-b" 1fr
    "mob-c" 1fr / 
    1fr
    ;
  border: 2px solid black;
  padding: 32px;
}

.c-contact-panel__local {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
  grid-area: mob-a;
}

.c-contact-panel__international {
  -ms-grid-row: 3;
  -ms-grid-column: 1;
  grid-area: mob-b;
}

.c-contact-panel__address {
  -ms-grid-row: 5;
  -ms-grid-column: 1;
  grid-area: mob-c;
}

@media (min-width: 960px) {
  .c-contact-panel {
    -ms-grid-rows: 1fr 1fr;
    -ms-grid-columns: 1fr 1fr;
        grid-template:
      "tab-a tab-c" 1fr
      "tab-b tab-c" 1fr /
       1fr    1fr;
  }

  .c-contact-panel__local {
    grid-area: tab-a;
   -ms-grid-row: 1;
    -ms-grid-column: 1;
  }

  .c-contact-panel__international {
    grid-area: tab-b;
    -ms-grid-row: 3;
    -ms-grid-column: 1;
  }

  .c-contact-panel__address {
    grid-area: tab-c;
    -ms-grid-row: 1;
    -ms-grid-row-span: 3;
    -ms-grid-column: 3;
  }
}

Update, testing in http://autoprefixer.github.io/ with

Postcss: v7.0.2, autoprefixer: v9.1.5 appears to work

@Seanom wait next minor update. We will release big Grid update which could fix it

When logging Autoprefixer issues, always provide input CSS, current output CSS and expected output CSS. It's difficult to understand what the issue is otherwise.

It looks like you are trying to use grid gap inheritance through media queries. That feature is broken in the current release as noted in issue https://github.com/postcss/autoprefixer/issues/1133. That will be fixed in the next release.

Also, try using http://autoprefixer.github.io/ as a playground to test in. It is using the most up to date version of Autoprefixer.

Was this page helpful?
0 / 5 - 0 ratings