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;
}
}
@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
}
}
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
Fixed https://github.com/postcss/autoprefixer/pull/1018
Released in 8.3.
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;
}
}
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.
Most helpful comment
Released in 7.2.3. @evgeny-petukhov was really quick in solving this issue.