Repository: postcss/autoprefixer
Pull request #1151 (2018-10-24 14:26:52)

[css-grid] Implement autoplacement (#1148)
This PR implements #1148

It can already be tested, but the following things need to be done/considered:

- [x]  Add warning for `grid-auto-flow: dense`
- [x]  We have a warning that's showed when grid-auto-flow is used. Do we remove it? Do we show it only when `grid-template(-areas)` is present?
- [x]  Refactoring
- [x]  General checks: compiler must not break, all values should be correct

/cc @Dan503 

ai: Note, that I will have vacation in November, so I will not be able to release it quick (but I think it is not the problem, it is better to think about it longer)
Dan503: >  We have a warning that's showed when `grid-auto-flow` is used. Do we remove it? Do we show it only when grid-template(-areas) is present?

I think showing it when `grid-template(-areas)` is present is the correct answer to that question.

We don't support auto-flow if the `grid-template-areas` algorithm is being used.
bogdan0083: @evandiamond Autoplacement feature is ready for testing! 🤠

I would be happy if you could test the feature in your spare time. Here are the things you need to do:

1. Clone my branch: `git clone -b feature/grid-autoplacement https://github.com/bogdan0083/autoprefixer`
2. run `yarn` inside cloned repository
3. run `npx gulp play`, add the code to `./playground/input.css` and save the file
4. the output fill be in `./playground/output.css`
evandiamond: @bogdan0083 Thank you so much! Going to do some testing later today and I'll report back with feedback. Cheers!
Dan503: @evandiamond I should have probably mentioned this while we were discussing the issue.

Like with everything else in Autoprefixer's grid translations, Autoprefixer has many limitations in what it is able to achieve. People need to work within those limitations. Autoprefixer can't magically fix _everything_ (just most things 😉).

Autoprefixer can do only the most bare basic of autoplacement functionality. If you try to manually place grid cells in the grid, Autoprefixer will make the grid cells overlap in IE rather than push the other content out of the way.

You can either let content place itself automatically inside the grid **OR** you can manually place grid cells inside the grid using `grid-template-areas`. 

**You cannot manually place grid cells inside the explicit grid of an auto-placement grid.**

For example think about this:

```css
.grid-one {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(3, 1fr);
    grid-gap: 20px;
}

.grid-two {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: repeat(4, 1fr);
    grid-gap: 30px;
}

/* Is grid-cell placed in grid-one or grid-two? */
.grid-cell {
  grid-column: 2;
  grid-row: 2;
}
```

In the example above, we have absolutely no way of knowing what grid the user intends for `.grid-cell` to go in so we are not going to factor it into the equation while building the output code.

However Autoprefixers auto-placement algorithm only works within the _explicit_ grid. Placing things in the _implicit_ grid will work just fine. 😊

```css
.grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(3, 1fr);
    grid-gap: 20px;
}

.grid-cell {
  grid-column: 1 / span 2;
  grid-row: 4; /* <-- This places the grid cell in the implicit grid */
}
```

@bogdan0083 I'm going to do some testing on this over the weekend. I don't expect I'll find any issues though since the grid doesn't need to take grid cells into consideration like grid-areas do.
Dan503: You also can't make any grid cells span multiple columns/rows if they are placed inside the explicit grid for the same reason.

Autoprefixers auto-placement is only to be used in that one use case where every grid-cell only takes up one grid-cell worth of space and they are all placed automatically in the grid. No manual grid-cell placement or spanning grid-cells over multiple columns/rows.

Thanks for getting this implemented @bogdan0083, this feature is awesome! 😁
Dan503: @bogdan0083 I've found a bug.

In the [MDN docs for `grid-auto-flow`](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow), it says that you can provide the `dense` keyword alongside `row` or `column`.

```css
grid-auto-flow: row dense;
grid-auto-flow: column dense;
```

This CSS **does** output a warning:

```css
.grid {
  display: grid;
  grid-auto-flow: dense;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(2, 1fr);
  grid-gap: 20px;
  grid-row-gap: 0;
}
```

This CSS does **not** output a warning:

```css
.grid {
  display: grid;
  grid-auto-flow: column dense; /* <-- no warning */
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(2, 1fr);
  grid-gap: 20px;
  grid-row-gap: 0;
}
```

Also, if the user does this, it should output a warning saying that `grid-auto-flow` needs to be used in the same rule as `grid-template-columns` and `grid-template-rows`:

```css
.grid {
  grid-auto-flow: column;
}
```
evandiamond: > You also can't make any grid cells span multiple columns/rows if they are placed inside the explicit grid for the same reason.
> 
> Autoprefixers auto-placement is only to be used in that one use case where every grid-cell only takes up one grid-cell worth of space and they are all placed automatically in the grid. No manual grid-cell placement or spanning grid-cells over multiple columns/rows.

@Dan503 Sure, but in the **Intermediate Example** with the `.button-container` being a nested child of `.Form`, if I am mention in the code `grid-column: 1/4;` I feel like Autoprefixer should know how many columns there are to give me the correct output of:

```
-ms-grid-column: 1;
    -ms-grid-column-span: 3;
    /*-ms-grid-column-span: 6; <---- correct
```

Right? Since IE is counting the columns, and we know how many columns from the parent, it should output the correct span if we are manually putting this in the CSS. So, that's possibly a bug.
Dan503: Ahh I see what you're saying.

Yeah that makes sense. We state the parent grid as part of the selector.

...that makes this way more complicated though :/

I think that is out of scope for this initial feature release. It adds loads of complications into the mix.

I think we can do a release with the basic autoplacement functionality first and then create a new issue for tackling grid cells that are placed inside the implicit grid.
bogdan0083: @evandiamond Thank you for testing and suggestions! 😀 Your ideas are good and I'll try to improve grid autoplacement to handle complex cases in the next release 🤔
Dan503: I've got some kind of bad news. If we release this, it will need to be released as a **new major version** 
because it introduces a breaking change.

If this was your html:

```html
<div class="grid">
  <div class="grid-cell"></div>
</div>
```

If you wrote this CSS before:

```css
.grid-cell {
  grid-column: 2;
  grid-row: 2;
}

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}
```

It used to compile into this:

```css
/* grid-cell placed in 2nd column & 2nd row */
.grid-cell {
  -ms-grid-column: 2;
  grid-column: 2;
  -ms-grid-row: 2;
  grid-row: 2;
}

.grid {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: (1fr)[3];
  grid-template-columns: repeat(3, 1fr);
  -ms-grid-rows: (1fr)[3];
  grid-template-rows: repeat(3, 1fr);
}
```

But now it compiles into this:

```css
/* user intended 2nd column & 2nd row */
.grid-cell {
  -ms-grid-column: 2;
  grid-column: 2;
  -ms-grid-row: 2;
  grid-row: 2;
}

.grid {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: (1fr)[3];
  grid-template-columns: repeat(3, 1fr);
  -ms-grid-rows: (1fr)[3];
  grid-template-rows: repeat(3, 1fr);
}

/* This rule overrides the users intended grid-cell rule */
/* Grid cell is placed in the 1st column & 1st row */
.grid > *:nth-child(1) {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
}

.grid > *:nth-child(2) {
  -ms-grid-row: 1;
  -ms-grid-column: 2;
}

.grid > *:nth-child(3) {
  -ms-grid-row: 1;
  -ms-grid-column: 3;
}

.grid > *:nth-child(4) {
  -ms-grid-row: 2;
  -ms-grid-column: 1;
}

.grid > *:nth-child(5) {
  -ms-grid-row: 2;
  -ms-grid-column: 2;
}

.grid > *:nth-child(6) {
  -ms-grid-row: 2;
  -ms-grid-column: 3;
}

.grid > *:nth-child(7) {
  -ms-grid-row: 3;
  -ms-grid-column: 1;
}

.grid > *:nth-child(8) {
  -ms-grid-row: 3;
  -ms-grid-column: 2;
}

.grid > *:nth-child(9) {
  -ms-grid-row: 3;
  -ms-grid-column: 3;
}
```

We should definitely still go ahead with this feature but it will need to be released as a new breaking change.
Dan503: I don't feel like `grid: 'auto'` describes the intent of enabling auto-placement well enough. 😕

We want to enable auto-placement by default. It's a feature that people really want and the more hoops that we make people jump through the harder it is for them to use the new feature. People already find it hard enough just setting the `grid` setting to `true`.

I think it might be better to add a new `gridAutoplacement` config setting that is separate from the `grid` setting.

By default, `gridAutoplacement` should be set to `true`.

If the user is migrating a project from 9.x to 10.x they should set `gridAutoplacement` to `false` so they don't get any regressions.

```js
autoprefixer({ grid: true, gridAutoplacement: false });
```

If the user is migrating to 10.x though then they probably want to be able to use the auto-placement feature in their project. In order to allow for this I think we need a new control comment. Something like this:

```
/* autoprefixer grid autoplacement: on */
```

It would be a block level control comment. I can see this also being useful for people who want to place grid cells manually using column and row numbers rather than grid areas. Eg. maybe they have some sort of Sass mixin that places grid cells in the grid for them based on column and row numbers.

Those people won't want Autoprefixer to output all the nth-child selectors if they intend to place the cells manually, especially if it's a large grid (a 3 column grid with 10 rows is 30nth child selectors!).

People who are migrating from 9.x to 10.x who want to use auto-placement will do this:

```js
autoprefixer({ grid: true, gridAutoplacement: false });
```

```css
.grid {
  /* autoprefixer grid autoplacement: on */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, auto);
}
```

People who are migrating from 9.x to 10.x, want to use auto-placement, but don't know how (or can't) configure Autoprefixer will do this:

```css
/* autoprefixer grid: on */
/* autoprefixer grid autoplacement: off */

.grid {
  /* autoprefixer grid autoplacement: on */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, auto);
}
```

People on a new project who occasionally want to place things manually for whatever reason will do this:

```js
autoprefixer({ grid: true });
```

```css
.grid {
  /* autoprefixer grid autoplacement: off */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  grid-template-rows: 1fr auto 1fr;
  height: 200px;
  width: 200px;
}
.grid-cell {
  grid-column: 2;
  grid-row: 2;
}
```

People who are on a new project running 10.x and using Autoprefixer in the typical intended way will do auto-placement like this:

```js
autoprefixer({ grid: true });
```

```css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, auto);
}
```

Yeah it's a bit more work for people that are migrating but it's easy for anyone starting new projects which is the most important thing going into the future. We want to make sure that new projects are easy to set up.
Dan503: If people are pretty confident that they don't have the breaking change in their css, then they can upgrade to 10.x without having to change anything. If we use something like a `grid: 'auto'` setting then people will be forced to change their config settings if they want to start using auto-placement in their project.

It's a very specific use case that cases the breaking change.

---

This CSS will cause a breaking change

```css
.grid-cell {
  grid-column: 2;
  grid-row: 2;
}

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}
```

---

However this css will **not** result in a breaking change.

```css
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}
.grid-cell {
  grid-column: 2;
  grid-row: 2;
}
```

---

If they have used grid-areas to place their grid cells then it isn't a breaking change for them either.
Dan503: Oh by the way, remember how I said that we might need to alter the auto-placement algorithm for `writing-mode` and `direction`?

Well apparently IE already has that covered for us.

I pasted the Autoprefixer auto-placement output into a Code Pen that has both direction and writing modes set on it and it works perfectly in IE11! 😁

https://codepen.io/daniel-tonon/pen/rqPbmZ
Dan503: Oh actually not perfectly :/

IE supports `writing-mode: vertical-rl;` and `direction: rtl;` individually but not both at the same time 🙁

Working around that limitation is probably out of scope. Maybe a fix for a future release.
Dan503: Ok then, we can have `gridAutoplacement` set to `false` by default then. That will ensure backwards compatibility at the cost of extra configuration for most users.

So in order to use autoplacement, most users will need to apply these settings:

```js
autoprefixer({ grid: true, gridAutoplacement: true });
```

When we do eventually switch to 10 we can make `gridAutoplacement` default to `true`.

We should still add a control comment for turning auto-placement on and off in the CSS.

Maybe it is better this way since we don't support full auto-placement.
Dan503: What if we shorten `gridAutoplacement` to `autoplacement`? I'm a little worried it could be problematic in future if we want to do some other sort of auto-placement setting at some point.

I guess I can live with `grid: 'auto'`, I don't feel like it describes the intent well enough though.

We should add the new control comment no matter what we go with. People will want to be able to control this and we need it for the exact same reasons why we added the `/* autoprefixer grid: on */` control comment, especially if we are not enabling auto-placement by default.

How do people on Code Pen, Angular and Create React App use auto-placement if it is disabled by default and they are locked out of the Autoprefixer settings?

There is also the weight of all the extra nth-child selectors being a performance hit. People will want a way to prevent them from being output if they are placing grid cells manually without the use of grid-areas.
Dan503: What about `grid: 'autoplace'`?
ai: > What about grid: 'autoplace'?

Yeap, much better :+1: 
Dan503: @ai we need to have a control comment. What syntax do you think is best?

---

`/* autoprefixer grid autoplacement: on|off */`
- (+) Good English 
- (-) A bit long
- (-) Doesn't match `grid` setting

---

`/* autoprefixer grid autoplace: on|off */`
- (+) Matches the wording used in the `grid` setting
- (+) A little bit shorter
- (-) Not _as_ good English

---

`/* autoprefixer grid auto: on|off */`
- (+) Good English 
- (+) Short
- (-) doesn't match `grid` setting
- (-) Doesn't specifically refer to auto-placement

---

Or maybe you can think of a better control comment?
Dan503: On the one hand, I like the succinctness of `/* autoprefixer grid: autoplace|on|off */` and I like how it mirrors how the `grid` setting is used.

On the other hand, it's a bit awkward to use it as a means of turning auto-placement on and off.

---

Turning auto-placement on and off using `/* autoprefixer grid: autoplace|on|off */`

```css
/* autoprefixer grid: autoplace */

.grid {
  /* autoprefixer grid: on */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}
```

---

Turning auto-placement on and off using `/* autoprefixer grid autoplace: on|off */`

```css
/* autoprefixer grid: on */
/* autoprefixer grid autoplace: on */

.grid {
  /* autoprefixer grid autoplace: off */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}
```

@bogdan0083, @evandiamond what sort of control comment syntax do you think is better?
ai: Two different option allows user to do strange thing like:

```css
/* autoprefixer grid: off */
/* autoprefixer grid autoplace: on */
```
Dan503: If grid is turned off then `/* autoprefixer grid autoplace: on */` has no effect.
Dan503: or maybe `/* autoprefixer grid autoplace: on */` can be considered a shortcut to also turning grid on if it isn't on already.

```css
/* autoprefixer grid autoplace: on */
/* (grid is implicitly enabled) */

.grid {
  /* autoprefixer grid autoplace: off */
  /* (grid is still enabled but auto-placement has been turned off) */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}
```
ai: `/* autoprefixer grid: autoplace */` will be shorter and has no this tricky case
Dan503: I just feel like making people do this as the method used for turning auto-placement on and off is super confusing.

```css
/* autoprefixer grid: autoplace */

.grid {
  /* autoprefixer grid: on */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}
```

`/* autoprefixer grid: on */` makes it seem like the intent of the code is to just enable IE grid translations. The **real** intent of the code however is to disable auto-placement.

Nothing about `/* autoprefixer grid: on */` makes it clear to the reader of the code that the intent is to disable auto-placement. It's going to confuse the hell out of people.
Dan503: My preference is to go with 

```
/* autoprefixer grid: on */
/* autoprefixer grid autoplace: on */
```

If the user does this (as in grid turned off but auto-placement turned on)...

```
/* autoprefixer grid: off */
/* autoprefixer grid autoplace: on */
```

Then I prefer `/* autoprefixer grid autoplace: on */` to simply be ignored.

Having `/* autoprefixer grid autoplace: on */` implicitly also enable grid translations is probably going to confuse people.
ai: What is a reason behind having 2 separated control comments?
Dan503: It prevents the confusion I explained in this comment: https://github.com/postcss/autoprefixer/pull/1151#issuecomment-433587881
bogdan0083: Personally I would prefer `grid autoplace: on|off`. With `grid on|off|autoplace` it's not very clear how to turn off the autoplacement feature.
Dan503: @bogdan0083 while we wait for the twitter poll results to come in, you can probably start figuring out how to implement the `grid: "autoplace"` setting.

Everything you have done for this pull request so far can only take effect if the `grid` setting is set to `"autoplace"`. It basically needs to function the same way it does on master branch if the `grid` setting is set to `true`.
bogdan0083: > @bogdan0083 while we wait for the twitter poll results to come in, you can probably start figuring out how to implement the grid: "autoplace" setting

Yep, I'm working on it :) 
Dan503: > IE supports writing-mode: vertical-rl; and direction: rtl; individually but not both at the same time 🙁

Separate issue created here: https://github.com/postcss/autoprefixer/issues/1152
bogdan0083: Alright, I added support for `grid: 'autoplace'` and also added support for conditional comment `autoprefixer grid autoplace: on|off` (at least for now. It's not hard to change conditional comment if we decide to use another one)

I also added the test cases, check it out. Do I need to add more test cases for this conditional comment?
Dan503: Have we got a "Second Autoprefixer grid autoplace control comment was ignored." warning?

I'm not sure why someone would use a second one but I'm sure someone will.
bogdan0083: Yep, we have that one.
Dan503: Can we change the wording in the warning to

> Second Autoprefixer grid **autoplace** control comment was ignored. Autoprefixer applies control comments to the whole block, not to the next rules.

Just to make it clearer that it was due to the inclusion of an auto-placement control comment. (FYI, if we switch to the the `grid: autoplace|on|off` style it won't make sense).

I also made some grammar tweaks in the warning message. This is the original warning for comparison:

> Second Autoprefixer grid control comment was ignored. Autoprefixer applies control comment to whole block, not to next rules.
Dan503: @bogdan0083 If you wan't to enable autoplacement in the playground by default, find the following snippet in `gulpfile.js`:

```js
gulp.task('compile-playground', () => {
  let autoprefixer = require('./build')
  return gulp.src('./playground/input.css')
    .pipe(rename('output.css'))
    .pipe(postcss([autoprefixer({ grid: true })]))
    .pipe(gulp.dest('./playground'))
})
```

Change `grid: true` to `grid: 'autoplace'`

```js
gulp.task('compile-playground', () => {
  let autoprefixer = require('./build')
  return gulp.src('./playground/input.css')
    .pipe(rename('output.css'))
    .pipe(postcss([autoprefixer({ grid: 'autoplace' })]))
    .pipe(gulp.dest('./playground'))
})
```

Dan503: By the way, thanks for implementing the changes so quickly! You're awesome @bogdan0083 😁
bogdan0083: We shoudn't show a warning if we have `grid: on` and then `grid autoplace: on`, right? We should then just turn on the autoplacement. Am I right?
Dan503: yeah `grid: on` and `grid autoplace: on` are two completly differnt commands.

`grid: on` + `autoplace: on` = grid translations + auto-placement

`grid: off` + `autoplace: on` = no grid translations + warn user that grid is turned off

`grid: on` + `autoplace: off` = grid translations + no auto-placement

`grid: off` + `autoplace: off` = no grid translations
bogdan0083: I kinda agree with Andrey. As I started adding test cases with two conditional comments it became way more confusing for me (as it turned out). We also need to add a slight overhead with all those different warnings and different conditions. 
Dan503: What is so confusing?

`/* autoprefixer grid: off */` = turn off all CSS grid translations.

`/* autoprefixer grid autoplace: off */` = only turn off auto placement, allow all other grid translations to continue as normal.

Remember, the alternative means that you have to enable and disable auto-placement like this which is super confusing for users:

```css
/* autoprefixer grid: autoplace */

.grid {
  /* autoprefixer grid: on */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}
```

`/* autoprefixer grid: on */` does not adequately say to the reader of the code that the authors intention is to turn off auto-placement.
bogdan0083: > /* autoprefixer grid: on */ does not adequately say to the reader of the code that the authors intention is to turn off auto-placement.

I agree. This is what I meant when I was saying this:
> But I also agree that disabling autoplacement with `autoprefixer grid: on` is quite confusing.

ai: > Remember, the alternative means that you have to enable and disable auto-placement like this which is super confusing for users

I do not think it will be a popular case. Most users should use `/* autoprefixer grid: autoplace */`.

But can have `/* autoprefixer grid: autoplace|no-autoplace|on|off */`, where `no-autoplace` will be the alias for `on`, just to make code readable in this rare cases.
Dan503: ```
/* autoprefixer grid: autoplace|no-autoplace|on|off */, 
```
That's a great idea! It's the best of both worlds. 😊
bogdan0083: I changed conditional comment, now it supports `grid: (on|off|autoplace|no-autoplace)`. I also changed the test cases to match these new comments 🙂
Dan503: That means that there is only some testing left to do and then it should be able to be released! 🎉

By the way, the Twitter poll results came in. It was pretty much a 50/50 split with `grid autoplace: on|off` being slightly ahead at 53% (15 votes).

I think the community will be happy with the `grid: (on|off|autoplace|no-autoplace)` option @ai came up with. The main issue with it was just disabling autoplacement which was fixed by adding the `no-autoplace` option.
ai: @bogdan0083 do not forget to update `README.md`
Dan503: I'll check it out and make a pull request against your branch if I need to make changes.
bogdan0083: That would be awesome, thanks! 😃
Dan503: I just realized something. What if there is a `::before`/`::after` element on the grid container?

```css
.autoplacement-example {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto;
  grid-gap: 20px;
}
.autoplacement-example::before {
  content: '';
}
```

In a modern browser, `::before` would be placed in the `:nth-child(1)` spot and `:nth-child(1)` would be placed in the `:nth-child(2)` spot.

Do you think that is something we can add support for in this release? or would it be better to tie it into the next release when we do more of the parent/child relationship stuff?

Yeah, it's probably out of scope for this initial release.
bogdan0083: > In a modern browser, ::before would be placed in the :nth-child(1) spot and :nth-child(1) would be placed in the :nth-child(2) spot.

Hmm, I'm sorry, I haven't been working on projects with css for about a year, can you elaborate a little on what the problem is with `::before/::after`? Do modern browsers change the order for selectors with pseudo elements? It's not quite clear for me right now.

Dan503: I'll make a demo to show what I mean and finish the edits to the Readme tomorrow night.
bogdan0083: Alright, done! 😀

I'll double-check the README tomorrow to make sure I did everything right (I'm falling asleep right now)
Dan503: I made a bunch of edits to the Readme last night. I'm going to have to resolve conflicts now :(
Dan503: Should we add a deprecation warning to `/* autoprefixer grid: on */`?

Something like:

> /* autoprefixer grid: on \*/ control comment has been deprecated in favour of /* autoprefixer grid: no-autoplace */
ai: > Should we add a deprecation warning to /* autoprefixer grid: on */?

I don’t think we need it
Dan503: @bogdan0083 I've finished editing the Readme. I'm having difficulty creating a pull request against your branch though. You name isn't showing up in the list of forks I can merge into.

Can you add my repo as a remote and then merge my feature branch into yours?

https://github.com/Dan503/autoprefixer/tree/feature/grid-autoplacement

I don't want to loose the Git History.
Dan503: > I'll make a demo to show what I mean and finish the edits to the Readme tomorrow night.

@bogdan0083 Here is the demo I promised:
https://codepen.io/daniel-tonon/pen/gBymVw

It doesn't have any IE translations, it does demonstrate what the `::before`/`::after` issue is though.
bogdan0083: Alright, now it fixed. Sorry about that. I didn't see that Andrey added `gridStatus` check only for `true` value, now it should work fine. I also turned on `grid: 'autoplace'` for every test case (it was on only for `grid-autopalcement.css`(.
evandiamond: Wow. Been following along most of the weekend. You guys are absolutely crushing it. Is there an ETA for when this will be ready for production?
bogdan0083: > @bogdan0083 Here is the demo I promised:
https://codepen.io/daniel-tonon/pen/gBymVw

@Dan503 Alright, now I think I got it: if we use `::before/::after`, modern browsers consider it as additional grid cells. To make the same effect in IE we need to preserve the first cell for `:before` pseudo element. Am I right?

I think I need to install Parallels to understand how to emulate the same behaviour in IE. This certainly should be fixed in the next release.

@evandiamond As Andrey said:
> Note, that I will have vacation in November, so I will not be able to release it quick (but I think it is not the problem, it is better to think about it longer)

Dan503: > To make the same effect in IE we need to preserve the first cell for :before pseudo element (and add -ms-grid-row/column). Am I right?

Yeah basically but **only if ::before exists**. If it doesn't exist then `:nth-child(1)` retains it's usual spot.

`::after` just needs to be tacked on at the end as if it were an extra grid cell but I don't want to output an `::after` at the end of every grid autoplacement on the off chance it happens to be used. It's also a bit crap supporting `::after` but not `::before`.

This all depends on parent child relationships which is out of scope for this release. We'll explore it more in the next one.
Dan503: > Alright, now it fixed. Sorry about that. I didn't see that Andrey added gridStatus check only for true value, now it should work fine. I also turned on grid: 'autoplace' for every test case (it was on only for grid-autopalcement.css).

Thanks for fixing the bug but now I'm terrified that there might be some other awful bug lurking in the code somewhere.

The pull request status said that it was passing but then I stumbled onto that catastrophic bug in the areas algorithm. If we released with that it would have been a disaster.

Any idea why the tests were passing? How can we trust the tests now? 😟
Dan503: With the `grid` setting, I feel like we should align it with the control comment.

So instead of `true`,`false`, and `"autoplace"` we have `"autoplace"`,`"no-autoplace"`, `false` and deprecate the `true` value.

I think that will be less confusing for people.
bogdan0083: >Thanks for fixing the bug but now I'm terrified that there might be some other awful bug lurking in the code somewhere.
The pull request status said that it was passing but then I stumbled onto that catastrophic bug in the areas algorithm. If we released with that it would have been a disaster.
Any idea why the tests were passing? How can we trust the tests now? 😟

As we have `grid: 'autoplace'` as a default value the bug is fixed now, that's for sure.

That was my fuck up. All the hacks and prefixes were working, but I forgot that areas algorithm is called from the special place and didn't check the condition.

Anyways, like Andrey said I'm gonna add an additional test to cover the cases for different options (`grid: 'autoplace', grid: true/'no-autoplace, grid: false`). That test will eliminate the bugs like that and the output with different options will be predictable
bogdan0083: @Dan503 @ai I added the test case that process the same file `grid-options.css` with different options and different outputs. Can you check it out? 
Dan503: I've updated the readme with the new `"no-autoplace"` `grid` setting and I also added a section to the auto-placement restrictions telling people not to use `::before` and `::after` elements.

@bogdan0083 can you do another merge of my branch?

https://github.com/Dan503/autoprefixer/tree/feature/grid-autoplacement

I think this might be ready for release now! 😁
Dan503: Sorry @bogdan0083 one more minor fix to the readme. Can you merge again?
bogdan0083: > Sorry @bogdan0083 one more minor fix to the readme. Can you merge again?
Done! :)

> I think this might be ready for release now! 😁
Did you test the branch on the real projects? does it function alright?
Dan503: > Did you test the branch on the real projects? does it function alright?

... not yet.

I'll need to do that tomorrow night after work ☹
Dan503: I don't really have much in the way of projects that I can actually test in unfortunately.

I have one that is pretty good for testing the duplicate areas stuff but Grid is only used for that one thing.  It isn't used anywhere else in the site.

The other one I test in is a site that used to to have loads of CSS Grid in it but then most of the CSS Grid was removed after this happened:

> I used CSS Grid in a project (IE friendly version). Everything was going great. At end of project, client  had a press conference showing off the new site... but used a 5 year old version of Firefox 😖
>
> The site blew up and now my company is terrified of implementing grid 😢
> https://twitter.com/Daniel_Tonon/status/1056294555966787584

I can test if the code compiles but I can't test if the site looks how it's supposed to.

And now after that problem happening I'm not getting any new chances to experiment with CSS Grid in real projects any more. ☹
bogdan0083: >I used CSS Grid in a project (IE friendly version). Everything was going great. At end of project, client had a press conference showing off the new site... but used a 5 year old version of Firefox 😖
The site blew up and now my company is terrified of implementing grid 😢
https://twitter.com/Daniel_Tonon/status/1056294555966787584

As I was reading this I literally had goosebumps all over my body 😧, oh god.. How did it turn out for you?
Dan503: > How did it turn out for you?

Fortunately I'm a bit too good at what I do for them to just fire me. Plus I had permission at the start of the project to use Grid so the heat wasn't entirely on me... just mostly on me since I was the one pushing the team to let me use it in the first place.

The Client was pretty pissed though so we had to go into damage control mode and try and implement flexbox workarounds for all the grid stuff we put in there.

----

@evandiamond do you have any real world production sites that have heavy use of CSS grid in them?

If you do can we get you to do some production site testing for us?

1. Fork or check out a copy of Bogdans feature branch
2. Run `gulp` (assuming you have Gulp installed. run `npm i -g gulp-cli` if not)
3. Enter the "build" folder
4. Go to your production site and find the "autoprefixer" folder in your "node_modules" folder
5. Save a backup of the "autoprefixer" folder so you can restore it after the testing.
6. Copy all the files from the "build" folder into the "autoprefixer" folder in "node_modules"
7. Compile the site and check everything looks how it's supposed to in IE.
Dan503: Otherwise maybe @ai can do a callout on Twitter asking for volunteers to help test before release?
evandiamond: @Dan503 I do have a couple sites I can test with, however, I will need to strip out client names/logos etc. Hopefully I can throw together a few samples this week, but I would think the more the merrier in terms of testing :)
Dan503: You don't actually need to show us the results. You just need to run the test locally and report back if you notice anything odd happen or if everything went perfectly.

Also do a test with grid set to autoplace just to make sure Autoprefixer doesn't blow up on a large scale project with autoplacement enabled. There is potential for some things to possibly look different with autoplacement enabled but for the most part it is backwards compatible so theoretically should still display the site the same.
Dan503: I did some tests on the one project I can still use as a good test case and I didn't run into any issues 😊
Dan503: @bogdan0083 I've made some more minor readme fixes. I noticed some oddities in the text. They've been fixed now.

https://github.com/Dan503/autoprefixer/tree/feature/grid-autoplacement
ai: We need to fix small thing. Now Autoprefixer show warnings on `auto` values and disable Grid prefixes in `@supports` with `auto` values.

We need to disable it on `grid: 'autoplace'`.
Dan503: > We need to fix small thing. Now Autoprefixer show warnings on auto values and disable Grid prefixes in @supports with auto values.

That's not a good idea. We still don't support properties like `grid-auto-rows` and `grid-auto-columns`.

We only support auto-placement inside the explicit grid. Those auto properties affect the implicit grid. We don't support that. Leave it the way it is.
ai: Sure, let’s remove at least warning which we can support. Because Autoprefixer will show a warning for this new feature.
Dan503: No don't even remove the warning because then people might get the idea that they can place things in the implicit grid.

It is perfect the way it is. Don't mess with it.

We will never be able to support auto-placement in the implicit grid, only the explicit grid.
ai: > only the explicit grid.

I am talking that Autoprefixer will warn user on `auto` in the explicit grid too.

Any CSS with `grid` and `auto` cause a warning right now. So even the things that we support cause the warning.
Dan503: Ok if that is the case then we should fix that. Be careful not to break anything to do with `grid-auto-*` though. They still need to produce warnings and turn off grid in @supports statements.
Dan503: @ai can you provide and example code snippet of what you mean?
ai: Maybe I missed something in diff, but

```css
grid-template-rows: 100px repeat(2, auto);
```

should print a warning right now
Dan503: No it shouldn't. In most cases auto on rows in IE acts very similarly to auto in modern browsers because the height of the grid is usually the same height as the content.

We don't want to warn users for rows.

If there is at least one `fr` unit used in a columns template then we don't want to warn users of auto in that case either.
Dan503: @evandiamond will you be able to do your testing this weekend?

That's pretty much all we are waiting on now before releasing to the public.
evandiamond: I will try to get some testing in this weekend!

On Fri, Nov 2, 2018 at 3:20 AM Daniel Tonon <notifications@github.com>
wrote:

> @evandiamond <https://github.com/evandiamond> will you be able to do your
> testing this weekend?
>
> That's pretty much all we are waiting on now before releasing to the
> public.
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/postcss/autoprefixer/pull/1151#issuecomment-435292554>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AM7eGmXxL332oRkHIyJ62qDmWSfKa6kDks5uq_IigaJpZM4X4Dau>
> .
>
-- 


*Evan*

evandiamond: @Dan503 I think I'm having some issues here, not sure if it's something in my Webpack setup, but after replacing the Autoprefixer package as you mentioned above, I get this error when running everything:

```
ERROR in ./node_modules/postcss-loader/src!./app/index.scss
Module build failed: Error: Loading PostCSS Plugin failed: Unexpected token =
```

I've tried a dozen things, but for some reason I can't get it working.

```
{
        test: /\.scss$/,
        use: [
          "style-loader", "css-loader", 'postcss-loader', 'sass-loader'
        ]
      }
```

```
module.exports = () => ({
  plugins: {
    'autoprefixer': {grid: "autoplace"}
  }
})
```

Stumped :(
Dan503: Is your version of Post CSS up to date? Running an out of date version of Post CSS has bitten me in the ass multiple times while testing new Autoprefixer builds.

Make sure that anything to do with Post CSS is running the latest version.
bogdan0083: If the above Dan's advice doesn't help, you can disable autoprefixer in webpack, build the project, take the project css output without autoprefixer and process it in fork using `gulp play`(I described the steps somewhere in the beginning of this PR). Then simply replace the build css with the output from playground. 🤠
evandiamond: @Dan503 I thought I was using the most up-to-date.

```
"postcss": "^7.0.5",
"autoprefixer": "^9.3.1",
```

I'll try @bogdan0083's method later.
Dan503: Also check that `postcss-loader` is up to date.

If postcss-loader depends on an out of date version then npm will resolve the dependency conflict by downloading the out of date version of Post CSS.

You can tell what the actual version of Post CSS that you are using is by searching for `"postcss"` in your package-lock.json file (include the quote marks to filter out Post CSS plugins).

Make sure that every single instance of  `"postcss"` in package-lock.json states the latest version.

I had an issue where I was using an out of date version of `gulp-postcss`. It was preventing Post CSS from using the latest version even though I stated the latest version in my package-lock.json file.
Dan503: npm will use whatever the _oldest_ version of Post CSS is that is stated in your package-lock.json file. 
evandiamond: I ran the Autoprefixer playground branch against a landing page built primarily using grid. I used the “autoplace” function. I kept my manual GridCSS properties in place and commented them out to see exactly how things matched up. I’ll paste snippets below. The manual items I have commented out (/* -ms */) to show exactly what I was testing against. The properties uncommented are from the Autoprefixer.

```
header {
    max-width: 1140px;
    margin: 40px auto 0;
    padding-bottom: 52px;
    display: -ms-grid;
    display: grid;
    /*-ms-grid-columns: 33% 15px 66%;*/
    -ms-grid-columns: 33% 15px 66%;
    grid-template-columns: 33% 66%;
    grid-gap: 0 15px;
}

header figure {
    /*-ms-grid-column: 1;*/
    -ms-grid-column: 1;
    grid-column: 1;
}


header ul {
    /*-ms-grid-column: 3;*/
    -ms-grid-column: 2;
    grid-column: 2;
    text-align: right;
}
```

```
.wrapper article {
    max-width: 1140px;
    margin: 0 auto;
    /*-ms-grid-row: 1;*/
    /*-ms-grid-column: 12;*/
    -ms-grid-column-span: 12;
    grid-column: span 12;
    -ms-grid-column: 1;
        grid-column-start: 1;
    /*-ms-grid-rows: 1fr;*/
    -ms-grid-rows: 1fr;
    grid-template-rows: 1fr;
}

article.fullwidth {
    /*display: -ms-grid;*/
    display: -ms-grid;
    display: grid;
    grid-gap: 0;
    -ms-grid-column: 1;
    grid-column-start: 1;
    /*grid-column: span 1;*/
    /*-ms-grid-row: 1;*/
    /*-ms-grid-column: 1;*/
    -ms-grid-column-span: 0;
    grid-column-end: 1;
    -ms-grid-rows: 1fr;
    grid-template-rows: 1fr;
    -ms-grid-columns: 1fr;
    grid-template-columns: 1fr;
}

```

The above example I chose was from one of the first GridCSS tests. A lot of the code was using older properties and not enough shorthand to give a proper test. I might need to code up a simple site this week to really test the Autoprefixing functionality that was added. Most things worked well, but I see some issues in the actual GridCSS code I used, which is causing problems. :(

I'm unsure why the `header ul` column is incorrect. I believe it should be 3 to match the proper IE grid-gaps.
Dan503: > I'm unsure why the header ul column is incorrect. I believe it should be 3 to match the proper IE grid-gaps.

It isn't using `grid-template-areas` and it isn't using autoplacement so we don't support grid-gaps in that use case.
Dan503: Actually we should probably add a warning. If we detect `grid-gap` and neither the autoplacement or areas algorithms have activated then we should warn the user not to use `grid-gap` unless `grid-template-areas` or basic autoplacement is being used.
Dan503: ```
    -ms-grid-column: 1;
    grid-column-start: 1;
    /*grid-column: span 1;*/
    /*-ms-grid-row: 1;*/
    /*-ms-grid-column: 1;*/
    -ms-grid-column-span: 0; /* <- bug */
    grid-column-end: 1;
```
That looks like a bug to me. It should be saying `-ms-grid-column-span: 1;` I think.

That is not related to autoplacement though so maybe file a new bug for that one.
Dan503: Actually no it's not. That is correct. A grid column that ends at line 1 will span 0 lines.

I'll need to do a bit of testing to see if it results in a consistent grid with modern browsers. I think modern browsers won't let a grid cell span less than 1 track.
Dan503: > I'll need to do a bit of testing to see if it results in a consistent grid with modern browsers.

I put together a little test.

https://codepen.io/daniel-tonon/pen/aQOPoa

It appears consistently in IE as it does in modern browsers. `-ms-grid-column-span: 0;` is not a bug.
bogdan0083: @ai Happy vacation, Andrey! 

I will try to write it tomorrow, but I hope Dan will help me with that 😄
Dan503: Yeah I'll help write the release notes.

If you could write up the initial release notes Bogdan I'll review and make edits.
Dan503: If we write up the release notes for you, will we be able to release this while you are on vacation @ai?

The end of November is pretty far away. ☹
Dan503: @bogdan0083 what happens if the user does this:

```css
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto;
  grid-gap: 50px;
}

@media (max-width: 600px) {
  .grid {
    grid-gap: 20px;
  }
}
```

Does it pay any attention to the media query? I'm guessing not.

This is probably out of scope for this release.
bogdan0083: > Does it pay any attention to the media query? I'm guessing not.

Yeah, this is the thing that should be fixed in the next release. We also need to change grid cells position if grid-gap value is changed from `grid-gap: 30px` to `grid-gap: 0` for example.
ai: > will we be able to release this while you are on vacation

Maybe

> Does it pay any attention to the media query?

Let’s focus only on important parts
Dan503: > Maybe

I'm trying to figure out what to do with that unpublished grid areas article.

It turns out Chris (CSS Tricks) was just super busy at the time and was taking a while to get back to me. I told him that we will probably be releasing the next version of Autoprefixer this week and it would be best for him to wait for that before upgrading CodePen.

If it isn't going to be released until the end of November though then I'll tell Chris to go ahead and upgrade to the current version of Autoprefixer and proceed with publishing the grid areas article.
bogdan0083: Here's the possible release message:
<details>
<summary>Message</summary>

Autoprefixer 9.4 brings limited **autoplacement** support in IE for Grid Layout

## Grid Autoplacement

<img src="https://user-images.githubusercontent.com/19343/47355871-8df3cd00-d690-11e8-8ca3-5574d0104ff3.png" alt="Coat of Arms of Oklahoma" width="200" height="202" align="right" style="max-width:100%;">

If the grid option is set to `"autoplace"`, limited autoplacement support is added to Autoprefixers grid translations. You can also use the `/* autoprefixer grid: autoplace */` control comment to enable autoplacement


```css
/* Input CSS */

/* autoprefixer grid: autoplace */

.autoplacement-example {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto;
    grid-gap: 20px;
}
```

```css
/* Output CSS */

/* autoprefixer grid: autoplace */

.autoplacement-example {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 1fr 20px 1fr;
  grid-template-columns: 1fr 1fr;
  -ms-grid-rows: auto 20px auto;
  grid-template-rows: auto auto;
  grid-gap: 20px;
}

.autoplacement-example > *:nth-child(1) {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
}

.autoplacement-example > *:nth-child(2) {
  -ms-grid-row: 1;
  -ms-grid-column: 3;
}

.autoplacement-example > *:nth-child(3) {
  -ms-grid-row: 3;
  -ms-grid-column: 1;
}

.autoplacement-example > *:nth-child(4) {
  -ms-grid-row: 3;
  -ms-grid-column: 3;
}
```

Check out [Grid Autoplacement support in IE ](https://github.com/postcss/autoprefixer#grid-autoplacement-support-in-ie) section for more details.
</details>
<details>
<summary>Markdown code</summary>

<pre>
Autoprefixer 9.4 brings limited **autoplacement** support in IE for Grid Layout

## Grid Autoplacement

If the grid option is set to `"autoplace"`, limited autoplacement support is added to Autoprefixers grid translations. You can also use the `/* autoprefixer grid: autoplace */` control comment to enable autoplacement


```css
/* Input CSS */

/* autoprefixer grid: autoplace */

.autoplacement-example {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto;
    grid-gap: 20px;
}
```

```css
/* Output CSS */

/* autoprefixer grid: autoplace */

.autoplacement-example {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 1fr 20px 1fr;
  grid-template-columns: 1fr 1fr;
  -ms-grid-rows: auto 20px auto;
  grid-template-rows: auto auto;
  grid-gap: 20px;
}

.autoplacement-example > *:nth-child(1) {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
}

.autoplacement-example > *:nth-child(2) {
  -ms-grid-row: 1;
  -ms-grid-column: 3;
}

.autoplacement-example > *:nth-child(3) {
  -ms-grid-row: 3;
  -ms-grid-column: 1;
}

.autoplacement-example > *:nth-child(4) {
  -ms-grid-row: 3;
  -ms-grid-column: 3;
}
```

Check out [Grid Autoplacement support in IE ](https://github.com/postcss/autoprefixer#grid-autoplacement-support-in-ie) section for more details.
</pre>
</details>

@Dan503 
ai: Good. I especially like that you investigated and copied origin style. Let’s just add your and main testers name to the release notes. “Homeland must know hero names” ☭
Dan503: I've finished reviewing the release notes message. This is what I came up with:

<details>
<summary>Message</summary>

<a target="_blank" rel="noopener noreferrer" href="https://user-images.githubusercontent.com/19343/47355871-8df3cd00-d690-11e8-8ca3-5574d0104ff3.png"><img src="https://user-images.githubusercontent.com/19343/47355871-8df3cd00-d690-11e8-8ca3-5574d0104ff3.png" alt="Coat of Arms of Oklahoma" width="200" height="202" align="right" style="max-width:100%;"></a>

Autoprefixer 9.4.0 brings limited **autoplacement** support to IE CSS Grid translations.

## Grid Autoplacement

@bogdan0083, @Dan503, and @evandiamond implemented the new CSS Grid Autoplacement feature.

If the `grid` option is set to `"autoplace"`, limited autoplacement support is now added to the Autoprefixer CSS Grid translations. You can also use the `/* autoprefixer grid: autoplace */` control comment to enable autoplacement directly from your CSS.

In order to use the new autoplacement feature, you **must define both rows and columns** when declaring the grid template.

```css
/* Input CSS */

/* autoprefixer grid: autoplace */

.autoplacement-example {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto;
    grid-gap: 20px;
}
```

```css
/* Output CSS */

/* autoprefixer grid: autoplace */

.autoplacement-example {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 1fr 20px 1fr;
  grid-template-columns: 1fr 1fr;
  -ms-grid-rows: auto 20px auto;
  grid-template-rows: auto auto;
  grid-gap: 20px;
}

.autoplacement-example > *:nth-child(1) {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
}

.autoplacement-example > *:nth-child(2) {
  -ms-grid-row: 1;
  -ms-grid-column: 3;
}

.autoplacement-example > *:nth-child(3) {
  -ms-grid-row: 3;
  -ms-grid-column: 1;
}

.autoplacement-example > *:nth-child(4) {
  -ms-grid-row: 3;
  -ms-grid-column: 3;
}
```

Autoplacement support in Autoprefixer is currently very limited in what it can do. Please read the  [Grid Autoplacement support in IE ](https://github.com/postcss/autoprefixer#grid-autoplacement-support-in-ie) section before using this new feature.

</details>


<details>
<summary>Markdown</summary>

``````

<a target="_blank" rel="noopener noreferrer" href="https://user-images.githubusercontent.com/19343/47355871-8df3cd00-d690-11e8-8ca3-5574d0104ff3.png"><img src="https://user-images.githubusercontent.com/19343/47355871-8df3cd00-d690-11e8-8ca3-5574d0104ff3.png" alt="Coat of Arms of Oklahoma" width="200" height="202" align="right" style="max-width:100%;"></a>

Autoprefixer 9.4.0 brings limited **autoplacement** support to IE CSS Grid translations.

## Grid Autoplacement

@bogdan0083, @Dan503, and @evandiamond implemented the new CSS Grid Autoplacement feature.

If the `grid` option is set to `"autoplace"`, limited autoplacement support is now added to the Autoprefixer CSS Grid translations. You can also use the `/* autoprefixer grid: autoplace */` control comment to enable autoplacement directly from your CSS.

In order to use the new autoplacement feature, you **must define both rows and columns** when declaring the grid template.

```css
/* Input CSS */

/* autoprefixer grid: autoplace */

.autoplacement-example {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto;
    grid-gap: 20px;
}
```

```css
/* Output CSS */

/* autoprefixer grid: autoplace */

.autoplacement-example {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 1fr 20px 1fr;
  grid-template-columns: 1fr 1fr;
  -ms-grid-rows: auto 20px auto;
  grid-template-rows: auto auto;
  grid-gap: 20px;
}

.autoplacement-example > *:nth-child(1) {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
}

.autoplacement-example > *:nth-child(2) {
  -ms-grid-row: 1;
  -ms-grid-column: 3;
}

.autoplacement-example > *:nth-child(3) {
  -ms-grid-row: 3;
  -ms-grid-column: 1;
}

.autoplacement-example > *:nth-child(4) {
  -ms-grid-row: 3;
  -ms-grid-column: 3;
}
```

Autoplacement support in Autoprefixer is currently very limited in what it can do. Please read the  [Grid Autoplacement support in IE ](https://github.com/postcss/autoprefixer#grid-autoplacement-support-in-ie) section before using this new feature.

``````

</details>

I placed people in order of their contribution. @bogdan0083 first for building the thing. @Dan503 next for convincing Bogdan to build it and I also wrote the Autoplacment guide in the readme. @evandiamond third for coming up with the initial idea and helping us with some testing.

By the way @bogdan0083 I added an extra section to the autoplacement guide about re-declaring columns and rows if editing the size of a `grid-gap`. Can you merge with my branch again?
evandiamond: This is great! I appreciate the mention :)

In the next week or so when I have some more time, I'm going to create a layout that we can use to test a bunch of different things down the line. You guys are awesome for putting so much attention and detail into this feature. I really can't thank you enough!
Dan503: I've edited my release entry. previously it said:

> @bogdan0083, @Dan503, and @evandiamond implemented the new CSS Grid Autoplacement feature.

Now it says this to make it clearer what each person did:

> Thanks to @bogdan0083 for implementing the new feature, @Dan503 for documenting it, and @evandiamond for coming up with the initial idea.

Also @bogdan0083 don't forget to merge with my branch again. It doesn't look like you've done it yet.
Dan503: @ai this is all set and ready to go. The release notes have been written and the testing is all looking good.

Can we release this thing now?
Dan503: I talked with @ai.

We decided it would be best that we release the grid areas article while 9.3.1 was still the latest version. It didn't make sense releasing the grid areas article when the exciting new feature was autoplacement.

Andre gets to enjoy a stress free vacation that way as well. He will release 9.4.0 when he gets back at the end of November.
Dan503: @bogdan0083 I started writing the auto-placement article and I've found a bug.

**Input CSS**

```css
.autoplacement-disabled {
  /* autoprefixer grid: no-autoplace */
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto;
  grid-gap: 20px;
}
```

**Current Output**

(It warns the user not to use `grid-gap`)
```css
.autoplacement-disabled {
  /* autoprefixer grid: no-autoplace */
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 1fr 20px 1fr;
  grid-template-columns: 1fr 1fr;
  -ms-grid-rows: auto 20px auto;
  grid-template-rows: auto auto;
  grid-gap: 20px;
}
```

**Expected output**
(It should still warn the user not to use `grid-gap`)
```css
.autoplacement-disabled {
  /* autoprefixer grid: no-autoplace */
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 1fr 1fr;
  grid-template-columns: 1fr 1fr;
  -ms-grid-rows: auto auto;
  grid-template-rows: auto auto;
  grid-gap: 20px;
}
```

Though it's kind of cool applying the grid gap, this would be an accidental breaking change if it got into the final release.
Dan503: Also, I've added another bit to the auto-placement guide in my repo. It points out that `auto-fit` and `auto-fill` are still not supported. I think users need to be told that explicitly to prevent them getting too excited.

When the auto-placement article I'm writing is published, we will probably scrap the guide in the readme in favour of a link to the article.
Dan503: Found another bug @bogdan0083. This is just a tiny one.

This will produce the warning: 

> Autoplacement does not work without grid-template-rows property

```css
.autoplacement-enabled {
  display: grid;
  grid-template-columns: 1fr 1fr;
  /* grid-template-rows: auto auto; */
}
```

However if I do this:
```css
.autoplacement-enabled {
  display: grid;
  /* grid-template-columns: 1fr 1fr; */
  grid-template-rows: auto auto;
}
```

There is now warning to say that columns need to be defined.
bogdan0083: Seems like it's fixed now. Can you check it out?
bogdan0083: @Dan503 I'm sorry, I've been busy these days. I've sent you an invite to join my fork as collaborator.

Patch:
diff --git a/README.md b/README.md
index 98d24d8..a6619e8 100644
--- a/README.md
+++ b/README.md
@@ -50,6 +50,52 @@ Twitter account for news and releases: [@autoprefixer].
 [cult]:             http://cultofmartians.com/tasks/autoprefixer-grid.html
 
 
+
+## Contents  <!-- omit in toc -->
+
+<details>
+  <summary>View table of contents</summary>
+
+- [Browsers](#browsers)
+- [FAQ](#faq)
+    - [Does Autoprefixer polyfill Grid Layout for IE?](#does-autoprefixer-polyfill-grid-layout-for-ie)
+    - [No prefixes in production](#no-prefixes-in-production)
+    - [What is the unprefixed version of `-webkit-min-device-pixel-ratio`?](#what-is-the-unprefixed-version-of--webkit-min-device-pixel-ratio)
+    - [Does it add polyfills?](#does-it-add-polyfills)
+    - [Why doesn’t Autoprefixer add prefixes to `border-radius`?](#why-doesnt-autoprefixer-add-prefixes-to-border-radius)
+    - [Why does Autoprefixer use unprefixed properties in `@-webkit-keyframes`?](#why-does-autoprefixer-use-unprefixed-properties-in--webkit-keyframes)
+    - [How to work with legacy `-webkit-` only code?](#how-to-work-with-legacy--webkit--only-code)
+    - [Does Autoprefixer add `-epub-` prefix?](#does-autoprefixer-add--epub--prefix)
+    - [Why doesn’t Autoprefixer transform generic font-family `system-ui`?](#why-doesnt-autoprefixer-transform-generic-font-family-system-ui)
+- [Usage](#usage)
+    - [Gulp](#gulp)
+    - [Webpack](#webpack)
+    - [Grunt](#grunt)
+    - [Other Build Tools:](#other-build-tools)
+    - [Preprocessors](#preprocessors)
+    - [CSS-in-JS](#css-in-js)
+    - [GUI Tools](#gui-tools)
+    - [CLI](#cli)
+    - [JavaScript](#javascript)
+    - [Text Editors and IDE](#text-editors-and-ide)
+- [Warnings](#warnings)
+- [Disabling](#disabling)
+    - [Prefixes](#prefixes)
+    - [Features](#features)
+    - [Control Comments](#control-comments)
+- [Options](#options)
+- [Grid Autoplacement support in IE](#grid-autoplacement-support-in-ie)
+    - [Beware of enabling autoplacment in already existing projects](#beware-of-enabling-autoplacment-in-already-existing-projects)
+    - [Autoplacement limitations](#autoplacement-limitations)
+        - [Both columns and rows must be defined](#both-columns-and-rows-must-be-defined)
+        - [Repeat auto-fit and auto-fill are not supported](#repeat-auto-fit-and-auto-fill-are-not-supported)
+        - [No manual cell placement or column/row spans allowed inside an autoplacement grid](#no-manual-cell-placement-or-columnrow-spans-allowed-inside-an-autoplacement-grid)
+        - [Do not create `::before` and `::after` pseudo elements](#do-not-create-before-and-after-pseudo-elements)
+        - [When changing the `grid gap` value, columns and rows must be re-declared](#when-changing-the-grid-gap-value-columns-and-rows-must-be-re-declared)
+- [Debug](#debug)
+
+</details>
+
 ## Browsers
 
 Autoprefixer uses [Browserslist], so you can specify the browsers
@@ -74,20 +120,20 @@ See [Browserslist docs] for queries, browser names, config format, and defaults.
 
 ## FAQ
 
-#### Does Autoprefixer polyfill Grid Layout for IE?
+### Does Autoprefixer polyfill Grid Layout for IE?
 
-Autoprefixer can be used to use Grid Layout for IE 10 and IE 11, but this
-polyfill will not work in 100% of cases. This is why it is disabled by default.
+Autoprefixer can be used to translate modern CSS Grid syntax into IE 10 and IE 11 syntax,
+but this polyfill will not work in 100% of cases. This is why it is disabled by default.
 
-First, you need to enable Grid prefixes by `grid: true` option or `/* autoprefixer grid: on */` comment.
+First, you need to enable Grid prefixes by using either the `grid: "autoplace"` option or the `/* autoprefixer grid: autoplace */` control comment.
 
 Second, you need to test every fix with Grid in IE. It is not an enable and
 forget feature, but it is still very useful.
 Financial Times and Yandex use it in production.
 
-Third, there is no auto placement, so all grid cell positions must be set
-explicitly. Autoprefixer _can_ covert `grid-template` and `grid-gap`, but only
-when both are used together.
+Third, there is only very limited auto placement support. Read the [Grid Autoplacement support in IE](#grid-autoplacement-support-in-ie) section for more details.
+
+Fourth, if you are not using the autoplacment feature, the best way to use Autoprefixer is by using  `grid-template` or `grid-template-areas`.
 
 ```css
 .page {
@@ -119,13 +165,13 @@ See also:
 * [`postcss-gap-properties`] to use new `gap` property
   instead of old `grid-gap`.
 * [`postcss-grid-kiss`] has alternate “everything in one property” syntax,
-  which make using Autoprefixer’s Grid safer.
+  which makes using Autoprefixer’s Grid translations safer.
 
 [The guide about Grids in IE and Autoprefixer]: https://css-tricks.com/css-grid-in-ie-css-grid-and-the-new-autoprefixer/
 [`postcss-gap-properties`]:                     https://github.com/jonathantneal/postcss-gap-properties
 [`postcss-grid-kiss`]:                          https://github.com/sylvainpolletvillard/postcss-grid-kiss
 
-#### No prefixes in production
+### No prefixes in production
 
 Many other tools contain Autoprefixer. For example, webpack uses Autoprefixer
 to minify CSS by cleaning unnecessary prefixes.
@@ -141,7 +187,7 @@ cssnano, doiuse, cssnext, etc) use the same browsers list.
 [browserslist config file]: https://github.com/ai/browserslist#config-file
 
 
-#### What is the unprefixed version of `-webkit-min-device-pixel-ratio`?
+### What is the unprefixed version of `-webkit-min-device-pixel-ratio`?
 
 ```css
 @media (min-resolution: 2dppx) {
@@ -164,7 +210,7 @@ Will be compiled to:
 ```
 
 
-#### Does it add polyfills?
+### Does it add polyfills?
 
 No. Autoprefixer only adds prefixes.
 
@@ -185,7 +231,7 @@ you might take a look at:
 [Oldie]:                  https://github.com/jonathantneal/oldie
 
 
-#### Why doesn’t Autoprefixer add prefixes to `border-radius`?
+### Why doesn’t Autoprefixer add prefixes to `border-radius`?
 
 Developers are often surprised by how few prefixes are required today.
 If Autoprefixer doesn’t add prefixes to your CSS, check if they’re still
@@ -194,13 +240,13 @@ required on [Can I Use].
 [Can I Use]: http://caniuse.com/
 
 
-#### Why does Autoprefixer use unprefixed properties in `@-webkit-keyframes`?
+### Why does Autoprefixer use unprefixed properties in `@-webkit-keyframes`?
 
 Browser teams can remove some prefixes before others, so we try to use all
 combinations of prefixed/unprefixed values.
 
 
-#### How to work with legacy `-webkit-` only code?
+### How to work with legacy `-webkit-` only code?
 
 Autoprefixer needs unprefixed property to add prefixes. So if you only
 wrote `-webkit-gradient` without W3C’s `gradient`,
@@ -212,7 +258,7 @@ Use [postcss-unprefix] before Autoprefixer.
 [postcss-unprefix]: https://github.com/gucong3000/postcss-unprefix
 
 
-#### Does Autoprefixer add `-epub-` prefix?
+### Does Autoprefixer add `-epub-` prefix?
 
 No, Autoprefixer works only with browsers prefixes from Can I Use.
 But you can use [postcss-epub]
@@ -221,7 +267,7 @@ for prefixing ePub3 properties.
 [postcss-epub]: https://github.com/Rycochet/postcss-epub
 
 
-#### Why doesn’t Autoprefixer transform generic font-family `system-ui`?
+### Why doesn’t Autoprefixer transform generic font-family `system-ui`?
 
 `system-ui` is technically not a prefix and the transformation is not
 future-proof. You can use [postcss-font-family-system-ui] to transform
@@ -478,19 +524,20 @@ If some prefixes were generated incorrectly, please create an [issue on GitHub].
 
 ### Features
 
-You can use these plugin options to disable some of Autoprefixer’s features.
+You can use these plugin options to control some of Autoprefixer’s features.
 
-* `grid: true` will enable `-ms-` prefixes for Grid Layout.
+* `grid: "autoplace"` will enable `-ms-` prefixes for Grid Layout including some
+  [limited autoplacement support](#grid-autoplacement-support-in-ie).
 * `supports: false` will disable `@supports` parameters prefixing.
 * `flexbox: false` will disable flexbox properties prefixing.
   Or `flexbox: "no-2009"` will add prefixes only for final and IE
   versions of specification.
 * `remove: false` will disable cleaning outdated prefixes.
 
-You should set them to the plugin:
+You should set them inside the plugin like so:
 
 ```js
-autoprefixer({ grid: true });
+autoprefixer({ grid: "autoplace" });
 ```
 
 
@@ -518,10 +565,16 @@ you can use control comments to disable Autoprefixer.
 
 There are three types of control comments:
 
-* `/* autoprefixer: off */` disable the whole block *before* and after comment.
-* `/* autoprefixer: ignore next */` disable only next property
+* `/* autoprefixer: (on|off) */`: enable/disable all Autoprefixer translations for the
+  whole block both *before* and *after* the comment.
+* `/* autoprefixer: ignore next */`: disable Autoprefixer only for the next property
   or next rule selector or at-rule parameters (but not rule/at‑rule body).
-* `/* autoprefixer grid: on */` enable grid option. Use `off` to disable this option.
+* `/* autoprefixer grid: (autoplace|no-autoplace|off) */`: control how Autoprefixer handles
+  grid translations for the whole block:
+    * `autoplace`: enable grid translations with autoplacement support.
+    * `no-autoplace`: enable grid translations with autoplacement support *disabled*.
+      (alias for deprecated value `on`)
+    * `off`: disable all grid translations.
 
 You can also use comments recursively:
 
@@ -535,6 +588,20 @@ You can also use comments recursively:
 }
 ```
 
+Note that comments that disable the whole block should not be featured in the same
+block twice:
+
+```css
+/* How not to use block level control comments */
+
+.do-not-do-this {
+    /* autoprefixer: off */
+    transition: 1s;
+    /* autoprefixer: on */
+    transform: rotate(20deg);
+}
+```
+
 
 ## Options
 
@@ -558,9 +625,14 @@ Available options are:
 * `flexbox` (boolean|string): should Autoprefixer add prefixes for flexbox
   properties. With `"no-2009"` value Autoprefixer will add prefixes only
   for final and IE versions of specification. Default is `true`.
-* `grid` (boolean): should Autoprefixer add IE prefixes for Grid Layout
-  properties. Default is `false`. You can also use `/* autoprefixer grid: on */`
-  comment in CSS.
+* `grid` (false|"autoplace"|"no-autoplace"): should Autoprefixer add IE prefixes for Grid Layout
+  properties?
+    * `false` (default): prevent Autoprefixer from outputting CSS Grid translations.
+    * `"autoplace"`: enable Autoprefixer grid translations and *include* autoplacement
+      support. You can also use `/* autoprefixer grid: autoplace */` in your CSS.
+    * `"no-autoplace"`: enable Autoprefixer grid translations but *exclude* autoplacement
+      support. You can also use `/* autoprefixer grid: no-autoplace */` in your CSS.
+      (alias for the deprecated `true` value)
 * `stats` (object): custom [usage statistics] for `> 10% in my stats`
   browsers query.
 * `browsers` (array): list of queries for target browsers. Try to not use it.
@@ -579,6 +651,321 @@ to increase performance.
 [usage statistics]: https://github.com/ai/browserslist#custom-usage-data
 [PostCSS API]:      http://api.postcss.org
 
+## Grid Autoplacement support in IE
+
+If the `grid` option is set to `"autoplace"`, limited autoplacement support is added to Autoprefixers grid translations. You can also use the `/* autoprefixer grid: autoplace */` control comment to enable autoplacement
+
+Autoprefixer will only autoplace grid cells if both `grid-template-rows` and `grid-template-columns` has been set. If `grid-template` or `grid-template-areas` has been set, Autoprefixer will use area based cell placement instead.
+
+Autoprefixer supports autoplacement by using `nth-child` CSS selectors. It creates [number of columns] x [number of rows] `nth-child` selectors. For this reason Autoplacement is only supported within the explicit grid.
+
+```css
+/* Input CSS */
+
+/* autoprefixer grid: autoplace */
+
+.autoplacement-example {
+    display: grid;
+    grid-template-columns: 1fr 1fr;
+    grid-template-rows: auto auto;
+    grid-gap: 20px;
+}
+```
+
+```css
+/* Output CSS */
+
+/* autoprefixer grid: autoplace */
+
+.autoplacement-example {
+    display: -ms-grid;
+    display: grid;
+    -ms-grid-columns: 1fr 20px 1fr;
+    grid-template-columns: 1fr 1fr;
+    -ms-grid-rows: auto 20px auto;
+    grid-template-rows: auto auto;
+    grid-gap: 20px;
+}
+
+.autoplacement-example > *:nth-child(1) {
+    -ms-grid-row: 1;
+    -ms-grid-column: 1;
+}
+
+.autoplacement-example > *:nth-child(2) {
+    -ms-grid-row: 1;
+    -ms-grid-column: 3;
+}
+
+.autoplacement-example > *:nth-child(3) {
+    -ms-grid-row: 3;
+    -ms-grid-column: 1;
+}
+
+.autoplacement-example > *:nth-child(4) {
+    -ms-grid-row: 3;
+    -ms-grid-column: 3;
+}
+```
+
+### Beware of enabling autoplacment in already existing projects
+
+Be careful about enabling autoplacement in any already established projects that have
+previously not used Autoprefixer's grid autoplacement feature before.
+
+The following CSS will not work as expected with the autoplacement feature enabled:
+
+```css
+/* Unsafe CSS when Autoplacement is enabled */
+
+.grid-cell {
+    grid-column: 2;
+    grid-row: 2;
+}
+
+.grid {
+    display: grid;
+    grid-template-columns: repeat(3, 1fr);
+    grid-template-rows: repeat(3, 1fr);
+}
+```
+
+Swapping the rules around so that the grid template styles are declared first will fix
+the issue:
+
+```css
+/* Place grid template styles before the grid cell styles to be safe */
+
+.grid {
+    display: grid;
+    grid-template-columns: repeat(3, 1fr);
+    grid-template-rows: repeat(3, 1fr);
+}
+
+.grid-cell {
+    grid-column: 2;
+    grid-row: 2;
+}
+```
+
+So as long as the grid cell styles are always declared after the grid-template styles,
+it should be safe to enable autoplacment in old projects.
+
+
+### Autoplacement limitations
+
+#### Both columns and rows must be defined
+
+Autoplacement only works inside the explicit grid. The columns and rows need to be defined
+so that Autoprefixer knows how many `nth-child` selectors to generate.
+
+```css
+.not-allowed {
+    display: grid;
+    grid-template-columns: repeat(3, 1fr);
+}
+
+.is-allowed {
+    display: grid;
+    grid-template-columns: repeat(3, 1fr);
+    grid-template-rows: repeat(10, auto);
+}
+```
+
+#### Repeat auto-fit and auto-fill are not supported
+
+The `repeat(auto-fit, ...)` and `repeat(auto-fill, ...)` grid functionality relies on
+knowledge from the browser about screen dimensions and the number of available grid
+items for it to work properly. Autoprefixer does not have access to this information
+so unfortunately this little snippet will _never_ be IE friendly.
+
+```css
+.grid {
+    /* This will never be IE friendly */
+    grid-template-columns: repeat(auto-fit, min-max(200px, 1fr))
+}
+```
+
+#### No manual cell placement or column/row spans allowed inside an autoplacement grid
+
+Elements must not be manually placed or given column/row spans inside an autoplacement
+grid. Only the most basic of autoplacement grids are supported. Grid cells can still be
+placed manually outside the the explicit grid though. Support for manually placing
+individual grid cells inside an explicit autoplacement grid is planned for a
+future release.
+
+```css
+.autoplacement-grid {
+    display: grid;
+    grid-template-columns: repeat(3, 1fr);
+    grid-template-rows: repeat(3, auto);
+}
+
+/*
+    grid cells placed inside the explicit grid
+    will break the layout in IE
+*/
+.not-permitted-grid-cell {
+    grid-column: 1;
+    grid-row: 1;
+}
+
+/*
+    grid cells placed outside the
+    explicit grid will work in IE
+*/
+.permitted-grid-cell {
+    grid-column: 1 / span 2;
+    grid-row: 4;
+}
+```
+
+If manual cell placement is required, we recommend using `grid-template` or
+`grid-template-areas` instead:
+
+```css
+.page {
+    display: grid;
+    grid-gap: 30px;
+    grid-template:
+        "head head"
+        "nav  main" minmax(100px, 1fr)
+        "foot foot" /
+        200px 1fr;
+}
+.page__head {
+    grid-area: head;
+}
+.page__nav {
+    grid-area: nav;
+}
+.page__main {
+    grid-area: main;
+}
+.page__footer {
+    grid-area: foot;
+}
+```
+
+#### Do not create `::before` and `::after` pseudo elements
+
+Let's say you have this HTML:
+
+```html
+<div class="grid">
+    <div class="grid-cell"></div>
+</div>
+```
+
+And you write this CSS:
+
+```css
+.grid {
+    display: grid;
+    grid-template-columns: 1fr 1fr;
+    grid-template-rows: auto;
+}
+
+.grid::before {
+    content: 'before';
+}
+
+.grid::after {
+    content: 'after';
+}
+```
+
+This will be the output:
+
+```css
+.grid {
+    display: -ms-grid;
+    display: grid;
+    -ms-grid-columns: 1fr 1fr;
+    grid-template-columns: 1fr 1fr;
+    -ms-grid-rows: auto;
+    grid-template-rows: auto;
+}
+
+.grid > *:nth-child(1) {
+    -ms-grid-row: 1;
+    -ms-grid-column: 1;
+}
+
+
+.grid > *:nth-child(2) {
+    -ms-grid-row: 1;
+    -ms-grid-column: 2;
+}
+
+.grid::before {
+    content: 'before';
+}
+
+.grid::after {
+    content: 'after';
+}
+```
+
+IE will place `.grid-cell`, `::before` and `::after` in row 1 column 1.
+Modern browsers on the other hand will place `::before` in row 1 column 1,
+`.grid-cell` in row 1 column 2, and `::after` in row 2 column 1.
+
+See this [Code Pen](https://codepen.io/daniel-tonon/pen/gBymVw) to see a visualization
+of the issue. View the Code Pen in both a modern browser and IE to see the difference.
+
+Note that you can still create `::before` and `::after` elements as long as you manually
+place them outside the explicit grid.
+
+#### When changing the `grid gap` value, columns and rows must be re-declared
+
+If you wish to change the size of a `grid-gap`, you will need to redeclare the grid columns and rows.
+
+```css
+.grid {
+    display: grid;
+    grid-template-columns: 1fr 1fr;
+    grid-template-rows: auto;
+    grid-gap: 50px;
+}
+
+/* This will *NOT* work in IE */
+@media (max-width: 600px) {
+    .grid {
+        grid-gap: 20px;
+    }
+}
+
+/* This will *NOT* work in IE */
+.grid.small-gap {
+    grid-gap: 20px;
+}
+```
+
+```css
+.grid {
+    display: grid;
+    grid-template-columns: 1fr 1fr;
+    grid-template-rows: auto;
+    grid-gap: 50px;
+}
+
+/* This *WILL* work in IE */
+@media (max-width: 600px) {
+    .grid {
+        grid-template-columns: 1fr 1fr;
+        grid-template-rows: auto;
+        grid-gap: 20px;
+    }
+}
+
+/* This *WILL* work in IE */
+.grid.small-gap {
+    grid-template-columns: 1fr 1fr;
+    grid-template-rows: auto;
+    grid-gap: 20px;
+}
+```
 
 ## Debug
 
diff --git a/gulpfile.js b/gulpfile.js
index 49f3c48..227e0d6 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -97,7 +97,7 @@ gulp.task('compile-playground', () => {
   let autoprefixer = require('./build')
   return gulp.src('./playground/input.css')
     .pipe(rename('output.css'))
-    .pipe(postcss([autoprefixer({ grid: true })]))
+    .pipe(postcss([autoprefixer({ grid: 'autoplace' })]))
     .pipe(gulp.dest('./playground'))
 })
 
diff --git a/lib/hacks/grid-rows-columns.js b/lib/hacks/grid-rows-columns.js
index d3e225b..0bf7976 100644
--- a/lib/hacks/grid-rows-columns.js
+++ b/lib/hacks/grid-rows-columns.js
@@ -1,13 +1,19 @@
 let Declaration = require('../declaration')
 let {
   prefixTrackProp,
-  prefixTrackValue
+  prefixTrackValue,
+  autoplaceGridItems,
+  getGridGap,
+  inheritGridGap
 } = require('./grid-utils')
+let Processor = require('../processor')
 
 class GridRowsColumns extends Declaration {
   static names = [
-    'grid-template-rows', 'grid-template-columns',
-    'grid-rows', 'grid-columns'
+    'grid-template-rows',
+    'grid-template-columns',
+    'grid-rows',
+    'grid-columns'
   ]
 
   /**
@@ -27,14 +33,90 @@ class GridRowsColumns extends Declaration {
     return prop.replace(/^grid-(rows|columns)/, 'grid-template-$1')
   }
 
-  /**
-   * Change repeating syntax for IE
-   */
-  set (decl, prefix) {
-    if (prefix === '-ms-' && decl.value.indexOf('repeat(') !== -1) {
-      decl.value = prefixTrackValue({ value: decl.value })
+  insert (decl, prefix, prefixes, result) {
+    if (prefix !== '-ms-') return super.insert(decl, prefix, prefixes)
+
+    let { parent, prop, value } = decl
+    let isRowProp = prop.includes('rows')
+    let isColumnProp = prop.includes('columns')
+
+    let hasGridTemplate = parent.some(
+      i => i.prop === 'grid-template' || i.prop === 'grid-template-areas'
+    )
+
+    /**
+     * Not to prefix rows declaration if grid-template(-areas) is present
+     */
+    if (hasGridTemplate && isRowProp) {
+      return false
+    }
+
+    let processor = new Processor({})
+    let status = processor.gridStatus(parent, result)
+    let gap = getGridGap(decl)
+    gap = inheritGridGap(decl, gap) || gap
+
+    let gapValue = isRowProp ? gap.row : gap.column
+
+    if ((status === 'no-autoplace' || status === true) && !hasGridTemplate) {
+      gapValue = null
+    }
+
+    let prefixValue = prefixTrackValue({
+      value,
+      gap: gapValue
+    })
+
+    /**
+     * Insert prefixes
+     */
+    decl.cloneBefore({
+      prop: prefixTrackProp({ prop, prefix }),
+      value: prefixValue
+    })
+
+    let autoflow = parent.nodes.find(i => i.prop === 'grid-auto-flow')
+    let autoflowValue = 'row'
+
+    if (autoflow && !processor.disabled(autoflow, result)) {
+      autoflowValue = autoflow.value.trim()
+    }
+
+    /**
+     * Show warning if grid-template-rows decl is not found
+     */
+    let rowDecl = parent.nodes.find(i => i.prop === 'grid-template-rows')
+
+    if (!rowDecl && hasGridTemplate) {
+      return undefined
+    } else if (!rowDecl && !hasGridTemplate) {
+      decl.warn(
+        result,
+        `Autoplacement does not work without grid-template-rows property`
+      )
+      return undefined
     }
-    return super.set(decl, prefix)
+
+    /**
+     * Show warning if grid-template-columns decl is not found
+     */
+    let columnDecl = parent.nodes.find(i => i.prop === 'grid-template-columns')
+    if (!columnDecl && !hasGridTemplate) {
+      decl.warn(
+        result,
+        `Autoplacement does not work without grid-template-columns property`
+      )
+    }
+
+    /**
+     * Autoplace grid items
+     */
+    let autoplaceEnabled = status === 'autoplace'
+    if (isColumnProp && !hasGridTemplate && autoplaceEnabled) {
+      autoplaceGridItems(decl, result, gap, autoflowValue)
+    }
+
+    return undefined
   }
 }
 
diff --git a/lib/hacks/grid-template-areas.js b/lib/hacks/grid-template-areas.js
index 181ba88..f8c0e48 100644
--- a/lib/hacks/grid-template-areas.js
+++ b/lib/hacks/grid-template-areas.js
@@ -26,52 +26,23 @@ class GridTemplateAreas extends Declaration {
     let hasRows = false
     let parent = decl.parent
     let gap = getGridGap(decl)
-    let inheritedGap = inheritGridGap(decl, gap)
+    gap = inheritGridGap(decl, gap) || gap
 
-    // remove already prefixed rows and columns
-    // without gutter to prevent doubling prefixes
-    parent.walkDecls(/-ms-grid-(rows|columns)/, i => i.remove())
+    // remove already prefixed rows
+    // to prevent doubling prefixes
+    parent.walkDecls(/-ms-grid-rows/, i => i.remove())
 
-    // add empty tracks to rows and columns
+    // add empty tracks to rows
     parent.walkDecls(/grid-template-(rows|columns)/, trackDecl => {
       if (trackDecl.prop === 'grid-template-rows') {
         hasRows = true
         let { prop, value } = trackDecl
-
-        /**
-         * we must insert inherited gap values in some cases:
-         * if we are inside media query && if we have no grid-gap value
-        */
-        if (inheritedGap) {
-          trackDecl.cloneBefore({
-            prop: prefixTrackProp({ prop, prefix }),
-            value: prefixTrackValue({ value, gap: inheritedGap.row })
-          })
-        } else {
-          trackDecl.cloneBefore({
-            prop: prefixTrackProp({ prop, prefix }),
-            value: prefixTrackValue({ value, gap: gap.row })
-          })
-        }
+        trackDecl.cloneBefore({
+          prop: prefixTrackProp({ prop, prefix }),
+          value: prefixTrackValue({ value, gap: gap.row })
+        })
       } else {
         hasColumns = true
-        let { prop, value } = trackDecl
-
-        /**
-         * we must insert inherited gap values in some cases:
-         * if we are inside media query && if we have no grid-gap value
-        */
-        if (inheritedGap) {
-          trackDecl.cloneBefore({
-            prop: prefixTrackProp({ prop, prefix }),
-            value: prefixTrackValue({ value, gap: inheritedGap.column })
-          })
-        } else {
-          trackDecl.cloneBefore({
-            prop: prefixTrackProp({ prop, prefix }),
-            value: prefixTrackValue({ value, gap: gap.column })
-          })
-        }
       }
     })
 
diff --git a/lib/hacks/grid-utils.js b/lib/hacks/grid-utils.js
index 9d22523..a2ce4cf 100644
--- a/lib/hacks/grid-utils.js
+++ b/lib/hacks/grid-utils.js
@@ -525,6 +525,7 @@ function insertAreas (css, isDisabled) {
 
       if ((!rule.hasDuplicates || !hasDuplicateName) && !rule.params) {
         // grid-template has no duplicates and not inside media rule
+
         getMSDecls(area, false, false).reverse()
           .forEach(i => gridAreaRule.prepend(
             Object.assign(i, {
@@ -947,6 +948,108 @@ function warnGridGap ({
   }
 }
 
+/**
+ * normalize the grid-template-rows/columns values
+ * @param  {String} str grid-template-rows/columns value
+ * @return {Array} normalized array with values
+ * @example
+ * let normalized = normalizeRowColumn('1fr repeat(2, 20px 50px) 1fr')
+ * normalized // <= ['1fr', '20px', '50px', '20px', '50px', '1fr']
+ */
+function normalizeRowColumn (str) {
+  let normalized = parser(str)
+    .nodes
+    .reduce((result, node) => {
+      if (node.type === 'function' && node.value === 'repeat') {
+        let key = 'count'
+
+        let [count, value] = node.nodes.reduce((acc, n) => {
+          if (n.type === 'word' && key === 'count') {
+            acc[0] = Math.abs(parseInt(n.value))
+            return acc
+          }
+          if (n.type === 'div' && n.value === ',') {
+            key = 'value'
+            return acc
+          }
+          if (key === 'value') {
+            acc[1] += parser.stringify(n)
+          }
+          return acc
+        }, [0, ''])
+
+        if (count) {
+          for (let i = 0; i < count; i++) {
+            result.push(value)
+          }
+        }
+
+        return result
+      }
+      if (node.type === 'space') {
+        return result
+      }
+      return result.concat(parser.stringify(node))
+    }, [])
+
+  return normalized
+}
+
+/**
+ * Autoplace grid items
+ * @param {Declaration} decl
+ * @param {Result} result
+ * @param {Object} gap gap values
+ * @param {String} autoflowValue grid-auto-flow value
+ * @return {void}
+ * @see https://github.com/postcss/autoprefixer/issues/1148
+ */
+function autoplaceGridItems (decl, result, gap, autoflowValue = 'row') {
+  let { parent } = decl
+
+  let rowDecl = parent.nodes.find(i => i.prop === 'grid-template-rows')
+  let rows = normalizeRowColumn(rowDecl.value)
+  let columns = normalizeRowColumn(decl.value)
+
+  // Build array of area names with dummy values. If we have 3 columns and
+  // 2 rows, filledRows will be equal to ['1 2 3', '4 5 6']
+  let filledRows = rows.map((_, rowIndex) => {
+    return Array.from({ length: columns.length }, (v, k) =>
+      k + (rowIndex * columns.length) + 1).join(' ')
+  })
+
+  let areas = parseGridAreas({ rows: filledRows, gap })
+  let keys = Object.keys(areas)
+  let items = keys.map(i => areas[i])
+
+  // Change the order of cells if grid-auto-flow value is 'column'
+  if (autoflowValue.includes('column')) {
+    items = items.sort((a, b) => a.column.start - b.column.start)
+  }
+
+  // Insert new rules
+  items.reverse().forEach((item, index) => {
+    let { column, row } = item
+    let nodeSelector = parent.selectors.map(sel =>
+      sel + ` > *:nth-child(${ keys.length - index })`).join(', ')
+
+    // create new rule
+    let node = parent.clone().removeAll()
+
+    // change rule selector
+    node.selector = nodeSelector
+
+    // insert prefixed row/column values
+    node.append({ prop: '-ms-grid-row', value: row.start })
+    node.append({ prop: '-ms-grid-column', value: column.start })
+
+    // insert rule
+    parent.after(node)
+  })
+
+  return undefined
+}
+
 module.exports = {
   parse,
   translate,
@@ -961,5 +1064,6 @@ module.exports = {
   warnGridGap,
   warnTemplateSelectorNotFound,
   warnIfGridRowColumnExists,
-  inheritGridGap
+  inheritGridGap,
+  autoplaceGridItems
 }
diff --git a/lib/processor.js b/lib/processor.js
index 0889879..771f249 100644
--- a/lib/processor.js
+++ b/lib/processor.js
@@ -5,6 +5,7 @@ const OLD_LINEAR = /(^|[^-])linear-gradient\(\s*(top|left|right|bottom)/i
 const OLD_RADIAL = /(^|[^-])radial-gradient\(\s*\d+(\w*|%)\s+\d+(\w*|%)\s*,/i
 const RADIAL_BLOCK = /\(((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*)\)/i
 const IGNORE_NEXT = /(!\s*)?autoprefixer:\s*ignore\s+next/i
+const GRID_REGEX = /(!\s*)?autoprefixer\s*grid:\s*(on|off|(no-)?autoplace)/i
 
 const SIZES = [
   'width', 'height', 'min-width', 'max-width',
@@ -13,6 +14,17 @@ const SIZES = [
   'min-block-size', 'max-block-size'
 ]
 
+function hasGridTemplate (decl) {
+  return decl.parent.some(i =>
+    i.prop === 'grid-template' || i.prop === 'grid-template-areas')
+}
+
+function hasRowsAndColumns (decl) {
+  let hasRows = decl.parent.some(i => i.prop === 'grid-template-rows')
+  let hasColumns = decl.parent.some(i => i.prop === 'grid-template-columns')
+  return hasRows && hasColumns
+}
+
 class Processor {
   constructor (prefixes) {
     this.prefixes = prefixes
@@ -83,6 +95,7 @@ class Processor {
     css.walkDecls(decl => {
       if (this.disabledDecl(decl, result)) return undefined
 
+      let parent = decl.parent
       let prop = decl.prop
       let value = decl.value
 
@@ -136,6 +149,29 @@ class Processor {
               { node: decl }
             )
             return undefined
+          } else if (decl.prop === 'grid-gap') {
+            let status = this.gridStatus(decl, result)
+            if (
+              status === 'autoplace' &&
+              !hasRowsAndColumns(decl) &&
+              !hasGridTemplate(decl)
+            ) {
+              result.warn(
+                'grid-gap only works if grid-template(-areas) is being ' +
+                'used or both rows and columns have been declared ' +
+                'and cells have not been manually ' +
+                'placed inside the explicit grid',
+                { node: decl }
+              )
+            } else if (
+              (status === true || status === 'no-autoplace') &&
+              !hasGridTemplate(decl)
+            ) {
+              result.warn(
+                `grid-gap only works if grid-template(-areas) is being used`,
+                { node: decl }
+              )
+            }
           } else if (prop === 'grid-auto-columns') {
             result.warn(
               'grid-auto-columns is not supported by IE',
@@ -149,10 +185,26 @@ class Processor {
             )
             return undefined
           } else if (prop === 'grid-auto-flow') {
-            result.warn(
-              'grid-auto-flow is not supported by IE',
-              { node: decl }
-            )
+            let hasRows = parent.some(i => i.prop === 'grid-template-rows')
+            let hasCols = parent.some(i => i.prop === 'grid-template-columns')
+
+            if (hasGridTemplate(decl)) {
+              result.warn(
+                'grid-auto-flow is not supported by IE',
+                { node: decl }
+              )
+            } else if (value.includes('dense')) {
+              result.warn(
+                'grid-auto-flow: dense is not supported by IE',
+                { node: decl }
+              )
+            } else if (!hasRows && !hasCols) {
+              result.warn(
+                'grid-auto-flow works only if grid-template-rows and ' +
+                'grid-template-columns are present in the same rule',
+                { node: decl }
+              )
+            }
             return undefined
           } else if (value.indexOf('auto-fit') !== -1) {
             result.warn(
@@ -287,7 +339,7 @@ class Processor {
 
     // Insert grid-area prefixes. We need to be able to store the different
     // rules as a data and hack API is not enough for this
-    if (this.gridStatus(css, result) === true) {
+    if (this.gridStatus(css, result)) {
       insertAreas(css, this.disabled)
     }
 
@@ -569,14 +621,20 @@ class Processor {
       let status
       node.each(i => {
         if (i.type !== 'comment') return
-        if (/(!\s*)?autoprefixer\s*grid:\s*(off|on)/i.test(i.text)) {
+        if (GRID_REGEX.test(i.text)) {
+          let hasAutoplace = /:\s*autoplace/i.test(i.text)
+          let noAutoplace = /no-autoplace/i.test(i.text)
           if (typeof status !== 'undefined') {
             result.warn(
-              'Second Autoprefixer grid control comment ' +
-              'was ignored. Autoprefixer applies control ' +
-              'comment to whole block, not to next rules.',
+              `Second Autoprefixer grid control comment was ` +
+              'ignored. Autoprefixer applies control comments to the whole ' +
+              'block, not to the next rules.',
               { node: i }
             )
+          } else if (hasAutoplace) {
+            status = 'autoplace'
+          } else if (noAutoplace) {
+            status = true
           } else {
             status = /on/i.test(i.text)
           }


Test patch:
diff --git a/test/autoprefixer.test.js b/test/autoprefixer.test.js
index bad53e7..dc0de10 100644
--- a/test/autoprefixer.test.js
+++ b/test/autoprefixer.test.js
@@ -7,7 +7,7 @@ let fs = require('fs')
 let grider = autoprefixer({
   browsers: ['Chrome 25', 'Edge 12', 'IE 10'],
   cascade: false,
-  grid: true
+  grid: 'autoplace'
 })
 
 let cleaner = autoprefixer({
@@ -253,11 +253,14 @@ it('sets grid option via comment', () => {
   expect(result.css).toEqual(output)
   expect(result.warnings().map(i => i.toString())).toEqual([
     'autoprefixer: <css input>:2:1: Second Autoprefixer grid control ' +
-        'comment was ignored. Autoprefixer applies control comment ' +
-        'to whole block, not to next rules.',
+        'comment was ignored. Autoprefixer applies control comments ' +
+        'to the whole block, not to the next rules.',
     'autoprefixer: <css input>:20:3: Second Autoprefixer grid control ' +
-        'comment was ignored. Autoprefixer applies control comment ' +
-        'to whole block, not to next rules.'
+        'comment was ignored. Autoprefixer applies control comments ' +
+        'to the whole block, not to the next rules.',
+    'autoprefixer: <css input>:47:3: Second Autoprefixer grid control ' +
+        'comment was ignored. Autoprefixer applies control comments ' +
+        'to the whole block, not to the next rules.'
   ])
 })
 
@@ -418,6 +421,30 @@ it('has disabled grid options by default', () => {
   expect(result.css).toEqual(output)
 })
 
+it('has different outputs for different grid options', () => {
+  function ap (gridValue) {
+    return autoprefixer({ browsers: ['Edge 12', 'IE 10'], grid: gridValue })
+  }
+  let input = read('grid-options')
+  let outputAutoplace = read('grid-options.autoplace.out')
+  let outputNoAutoplace = read('grid-options.no-autoplace.out')
+  let outputDisabled = read('grid-options.disabled.out')
+
+  let resultAutoplace = postcss([ap('autoplace')]).process(input)
+  let resultNoAutoplace = postcss([ap('no-autoplace')]).process(input)
+  let resultEnabled = postcss([ap(true)]).process(input)
+  let resultDisabled = postcss([ap(false)]).process(input)
+
+  // output for grid: 'autoplace'
+  expect(resultAutoplace.css).toEqual(outputAutoplace)
+  // output for grid: 'no-autoplace'
+  expect(resultNoAutoplace.css).toEqual(outputNoAutoplace)
+  // output for grid: true is the same as for 'no-autoplace'
+  expect(resultEnabled.css).toEqual(outputNoAutoplace)
+  // output for grid: false
+  expect(resultDisabled.css).toEqual(outputDisabled)
+})
+
 it('has option to disable flexbox support', () => {
   let css = read('flexbox')
   let instance = autoprefixer({ browsers: ['IE 10'], flexbox: false })
@@ -556,6 +583,10 @@ describe('hacks', () => {
 
     expect(result.css).toEqual(output)
     expect(result.warnings().map(i => i.toString())).toEqual([
+      'autoprefixer: <css input>:3:3: Autoplacement does not work ' +
+        'without grid-template-rows property',
+      'autoprefixer: <css input>:12:3: Autoplacement does not work ' +
+        'without grid-template-columns property',
       'autoprefixer: <css input>:36:3: Can not prefix grid-column-end ' +
         '(grid-column-start is not found)',
       'autoprefixer: <css input>:39:3: Can not impliment grid-gap ' +
@@ -578,8 +609,6 @@ describe('hacks', () => {
         'supported by IE',
       'autoprefixer: <css input>:102:3: grid-auto-rows is not ' +
         'supported by IE',
-      'autoprefixer: <css input>:103:3: grid-auto-flow is not ' +
-        'supported by IE',
       'autoprefixer: <css input>:104:33: auto-fill value is not ' +
         'supported by IE',
       'autoprefixer: <css input>:105:30: auto-fit value is not ' +
@@ -596,7 +625,33 @@ describe('hacks', () => {
         'on grid containers',
       'autoprefixer: <css input>:140:3: IE does not support place-items ' +
         'on grid containers. Try using place-self on child elements ' +
-        'instead: .warn_place_items > * { place-self: start end }'
+        'instead: .warn_place_items > * { place-self: start end }',
+      'autoprefixer: <css input>:164:3: grid-auto-flow is not supported by IE'
+    ])
+  })
+
+  it('supports grid autoplacement', () => {
+    let input = read('grid-autoplacement')
+    let output = read('grid-autoplacement.out')
+    let instance = prefixer('grid')
+    let result = postcss([instance]).process(input)
+    expect(result.css).toEqual(output)
+
+    expect(result.warnings().map(i => i.toString())).toEqual([
+      'autoprefixer: <css input>:47:3: grid-auto-flow: dense ' +
+        'is not supported by IE',
+      'autoprefixer: <css input>:48:3: Autoplacement does not work ' +
+        'without grid-template-rows property',
+      'autoprefixer: <css input>:53:3: grid-auto-flow works only if grid-temp' +
+      'late-rows and grid-template-columns are present in the same rule',
+      'autoprefixer: <css input>:60:3: grid-gap only works if grid-temp' +
+      'late(-areas) is being used',
+      'autoprefixer: <css input>:64:3: Autoplacement does not work ' +
+      'without grid-template-rows property',
+      'autoprefixer: <css input>:65:3: grid-gap only works if grid-temp' +
+      'late(-areas) is being used or both rows and columns have been ' +
+      'declared and cells have not been ' +
+      'manually placed inside the explicit grid'
     ])
   })
 
diff --git a/test/cases/grid-autoplacement.css b/test/cases/grid-autoplacement.css
new file mode 100644
index 0000000..8008258
--- /dev/null
+++ b/test/cases/grid-autoplacement.css
@@ -0,0 +1,66 @@
+
+.grid-basic {
+  display: grid;
+  grid-template-columns: 1fr 1fr 1fr;
+  grid-template-rows: auto;
+  grid-gap: 30px;
+}
+
+/* Must work with repeat function */
+.grid-repeat {
+  display: grid;
+  grid-template-columns: repeat(4, 1fr 2fr);
+  grid-template-rows: repeat(2, auto);
+  grid-gap: 30px;
+}
+
+/* Complex case */
+.grid-complex {
+  display: grid;
+  grid-template-columns: 1fr repeat(2, minmax(100px, 200px)) 1fr;
+  grid-template-rows: 100px repeat(2, auto);
+  grid-gap: 30px 5px;
+}
+
+/* Must work inside media */
+@media (min-width: 400px) {
+  .grid-media {
+    display: grid;
+    grid-template-columns: 1fr 1fr 1fr;
+    grid-template-rows: auto;
+    grid-gap: 30px;
+  }
+}
+
+/* Must consider autoflow value */
+.grid-flow-column {
+  display: grid;
+  grid-auto-flow: column;
+  grid-template-columns: 1fr 1fr 1fr;
+  grid-template-rows: auto auto;
+  grid-gap: 30px;
+}
+
+/* Show warning if rows are not defined
+   and dense value is used */
+.grid-warning-dense {
+  grid-auto-flow: column dense;
+  grid-template-columns: 1fr 1fr 1fr;
+}
+
+/* Show warning autoflow used without rows/columns */
+.grid-warning-autoflow {
+  grid-auto-flow: column;
+}
+
+.grid-autoplace-disabled {
+  /* autoprefixer grid: no-autoplace */
+  grid-template-columns: 1fr 1fr 1fr;
+  grid-template-rows: auto;
+  grid-gap: 30px;
+}
+
+.grid-autoplace-gap-warn {
+  grid-template-columns: 1fr 1fr 1fr;
+  grid-gap: 30px;
+}
\ No newline at end of file
diff --git a/test/cases/grid-autoplacement.out.css b/test/cases/grid-autoplacement.out.css
new file mode 100644
index 0000000..6e3347a
--- /dev/null
+++ b/test/cases/grid-autoplacement.out.css
@@ -0,0 +1,213 @@
+
+.grid-basic {
+  display: -ms-grid;
+  display: grid;
+  -ms-grid-columns: 1fr 30px 1fr 30px 1fr;
+  grid-template-columns: 1fr 1fr 1fr;
+  -ms-grid-rows: auto;
+  grid-template-rows: auto;
+  grid-gap: 30px;
+}
+.grid-basic > *:nth-child(1) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 1;
+}
+.grid-basic > *:nth-child(2) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 3;
+}
+.grid-basic > *:nth-child(3) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 5;
+}
+
+/* Must work with repeat function */
+.grid-repeat {
+  display: -ms-grid;
+  display: grid;
+  -ms-grid-columns: 1fr 30px 2fr 30px 1fr 30px 2fr 30px 1fr 30px 2fr 30px 1fr 30px 2fr;
+  grid-template-columns: repeat(4, 1fr 2fr);
+  -ms-grid-rows: auto 30px auto;
+  grid-template-rows: repeat(2, auto);
+  grid-gap: 30px;
+}
+.grid-repeat > *:nth-child(1) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 1;
+}
+.grid-repeat > *:nth-child(2) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 3;
+}
+.grid-repeat > *:nth-child(3) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 5;
+}
+.grid-repeat > *:nth-child(4) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 7;
+}
+.grid-repeat > *:nth-child(5) {
+  -ms-grid-row: 3;
+  -ms-grid-column: 1;
+}
+.grid-repeat > *:nth-child(6) {
+  -ms-grid-row: 3;
+  -ms-grid-column: 3;
+}
+.grid-repeat > *:nth-child(7) {
+  -ms-grid-row: 3;
+  -ms-grid-column: 5;
+}
+.grid-repeat > *:nth-child(8) {
+  -ms-grid-row: 3;
+  -ms-grid-column: 7;
+}
+
+/* Complex case */
+.grid-complex {
+  display: -ms-grid;
+  display: grid;
+  -ms-grid-columns: 1fr 5px minmax(100px, 200px) 5px minmax(100px, 200px) 5px 1fr;
+  grid-template-columns: 1fr repeat(2, minmax(100px, 200px)) 1fr;
+  -ms-grid-rows: 100px 30px auto 30px auto;
+  grid-template-rows: 100px repeat(2, auto);
+  grid-gap: 30px 5px;
+}
+.grid-complex > *:nth-child(1) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 1;
+}
+.grid-complex > *:nth-child(2) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 3;
+}
+.grid-complex > *:nth-child(3) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 5;
+}
+.grid-complex > *:nth-child(4) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 7;
+}
+.grid-complex > *:nth-child(5) {
+  -ms-grid-row: 3;
+  -ms-grid-column: 1;
+}
+.grid-complex > *:nth-child(6) {
+  -ms-grid-row: 3;
+  -ms-grid-column: 3;
+}
+.grid-complex > *:nth-child(7) {
+  -ms-grid-row: 3;
+  -ms-grid-column: 5;
+}
+.grid-complex > *:nth-child(8) {
+  -ms-grid-row: 3;
+  -ms-grid-column: 7;
+}
+.grid-complex > *:nth-child(9) {
+  -ms-grid-row: 5;
+  -ms-grid-column: 1;
+}
+.grid-complex > *:nth-child(10) {
+  -ms-grid-row: 5;
+  -ms-grid-column: 3;
+}
+.grid-complex > *:nth-child(11) {
+  -ms-grid-row: 5;
+  -ms-grid-column: 5;
+}
+.grid-complex > *:nth-child(12) {
+  -ms-grid-row: 5;
+  -ms-grid-column: 7;
+}
+
+/* Must work inside media */
+@media (min-width: 400px) {
+  .grid-media {
+    display: -ms-grid;
+    display: grid;
+    -ms-grid-columns: 1fr 30px 1fr 30px 1fr;
+    grid-template-columns: 1fr 1fr 1fr;
+    -ms-grid-rows: auto;
+    grid-template-rows: auto;
+    grid-gap: 30px;
+  }
+  .grid-media > *:nth-child(1) {
+    -ms-grid-row: 1;
+    -ms-grid-column: 1;
+  }
+  .grid-media > *:nth-child(2) {
+    -ms-grid-row: 1;
+    -ms-grid-column: 3;
+  }
+  .grid-media > *:nth-child(3) {
+    -ms-grid-row: 1;
+    -ms-grid-column: 5;
+  }
+}
+
+/* Must consider autoflow value */
+.grid-flow-column {
+  display: -ms-grid;
+  display: grid;
+  grid-auto-flow: column;
+  -ms-grid-columns: 1fr 30px 1fr 30px 1fr;
+  grid-template-columns: 1fr 1fr 1fr;
+  -ms-grid-rows: auto 30px auto;
+  grid-template-rows: auto auto;
+  grid-gap: 30px;
+}
+.grid-flow-column > *:nth-child(1) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 1;
+}
+.grid-flow-column > *:nth-child(2) {
+  -ms-grid-row: 3;
+  -ms-grid-column: 1;
+}
+.grid-flow-column > *:nth-child(3) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 3;
+}
+.grid-flow-column > *:nth-child(4) {
+  -ms-grid-row: 3;
+  -ms-grid-column: 3;
+}
+.grid-flow-column > *:nth-child(5) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 5;
+}
+.grid-flow-column > *:nth-child(6) {
+  -ms-grid-row: 3;
+  -ms-grid-column: 5;
+}
+
+/* Show warning if rows are not defined
+   and dense value is used */
+.grid-warning-dense {
+  grid-auto-flow: column dense;
+  -ms-grid-columns: 1fr 1fr 1fr;
+  grid-template-columns: 1fr 1fr 1fr;
+}
+
+/* Show warning autoflow used without rows/columns */
+.grid-warning-autoflow {
+  grid-auto-flow: column;
+}
+
+.grid-autoplace-disabled {
+  /* autoprefixer grid: no-autoplace */
+  -ms-grid-columns: 1fr 1fr 1fr;
+  grid-template-columns: 1fr 1fr 1fr;
+  -ms-grid-rows: auto;
+  grid-template-rows: auto;
+  grid-gap: 30px;
+}
+
+.grid-autoplace-gap-warn {
+  -ms-grid-columns: 1fr 30px 1fr 30px 1fr;
+  grid-template-columns: 1fr 1fr 1fr;
+  grid-gap: 30px;
+}
\ No newline at end of file
diff --git a/test/cases/grid-options.autoplace.out.css b/test/cases/grid-options.autoplace.out.css
new file mode 100644
index 0000000..8416698
--- /dev/null
+++ b/test/cases/grid-options.autoplace.out.css
@@ -0,0 +1,176 @@
+/*****************\
+  AREAS ALGORITHM
+\*****************/
+
+.grid-template-areas {
+  display: -ms-grid;
+  display: grid;
+      grid-template-areas:
+    "a-conflict a-conflict"
+    "b-conflict b-conflict";
+}
+
+.grid-template-areas.conflict {
+  display: -ms-grid;
+  display: grid;
+      grid-template-areas:
+    "a-conflict"
+    "b-conflict";
+}
+
+.a {
+  -ms-grid-row: 1;
+  -ms-grid-column: 1;
+  -ms-grid-column-span: 2;
+  grid-area: a-conflict;
+}
+
+.grid-template-areas.conflict > .a {
+  -ms-grid-row: 1;
+  -ms-grid-column: 1;
+  -ms-grid-column-span: 1;
+}
+
+.b {
+  -ms-grid-row: 2;
+  -ms-grid-column: 1;
+  -ms-grid-column-span: 2;
+  grid-area: b-conflict;
+}
+
+.grid-template-areas.conflict > .b {
+  -ms-grid-row: 2;
+  -ms-grid-column: 1;
+  -ms-grid-column-span: 1;
+}
+
+.grid-template {
+  -ms-grid-rows: 30px 1fr 30px;
+  -ms-grid-columns: 120px (250px 10px)[4];
+      grid-template:
+      [header-left] "head head" 30px [header-right]
+      [main-left]   "nav  main" 1fr  [main-right]
+      [footer-left] "nav  foot" 30px [footer-right]
+      / 120px repeat(4, 250px 10px);
+}
+
+@media (min-width: 1000px) {
+  .grid-template {
+    -ms-grid-rows: 30px auto 1fr 30px;
+    -ms-grid-columns: 1fr;
+        grid-template:
+        [header-left] "head" 30px [header-right]
+        [nav-left]    "nav"  auto  [nav-right]
+        [main-left]   "main" 1fr  [main-right]
+        [footer-left] "foot" 30px [footer-right]
+        / 1fr;
+  }
+}
+
+.grid-template.conflict {
+  -ms-grid-rows: auto 20px auto;
+  -ms-grid-columns: 1fr 1fr;
+      grid-template:
+      "head head"
+      "nav main" 20px
+      "nav foot"
+      / 1fr 1fr;
+}
+
+.head {
+  -ms-grid-row: 1;
+  -ms-grid-column: 1;
+  -ms-grid-column-span: 2;
+  grid-area: head;
+}
+
+.grid-template.conflict > .head {
+  -ms-grid-row: 1;
+  -ms-grid-column: 1;
+  -ms-grid-column-span: 2;
+}
+
+.main {
+  -ms-grid-row: 2;
+  -ms-grid-column: 2;
+  grid-area: main;
+}
+
+.grid-template.conflict > .main {
+  -ms-grid-row: 2;
+  -ms-grid-column: 2;
+}
+
+.nav {
+  -ms-grid-row: 2;
+  -ms-grid-row-span: 2;
+  -ms-grid-column: 1;
+  grid-area: nav;
+}
+
+.grid-template.conflict > .nav {
+  -ms-grid-row: 2;
+  -ms-grid-row-span: 2;
+  -ms-grid-column: 1;
+}
+
+.foot {
+  -ms-grid-row: 3;
+  -ms-grid-column: 2;
+  grid-area: foot;
+}
+
+.grid-template.conflict > .foot {
+  -ms-grid-row: 3;
+  -ms-grid-column: 2;
+}
+
+@media (min-width: 1000px) {
+  .head {
+    -ms-grid-row: 1;
+    -ms-grid-column: 1;
+    -ms-grid-column-span: 1;
+  }
+  .main {
+    -ms-grid-row: 3;
+    -ms-grid-column: 1;
+  }
+  .nav {
+    -ms-grid-row: 2;
+    -ms-grid-row-span: 1;
+    -ms-grid-column: 1;
+  }
+  .foot {
+    -ms-grid-row: 4;
+    -ms-grid-column: 1;
+  }
+}
+
+/*********************\
+  AUTOPLACE ALGORITHM
+\*********************/
+
+.grid-autoplace {
+  display: -ms-grid;
+  display: grid;
+  -ms-grid-columns: 1fr 30px 1fr 30px 1fr;
+  grid-template-columns: 1fr 1fr 1fr;
+  -ms-grid-rows: auto;
+  grid-template-rows: auto;
+  grid-gap: 30px;
+}
+
+.grid-autoplace > *:nth-child(1) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 1;
+}
+
+.grid-autoplace > *:nth-child(2) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 3;
+}
+
+.grid-autoplace > *:nth-child(3) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 5;
+}
diff --git a/test/cases/grid-options.css b/test/cases/grid-options.css
new file mode 100644
index 0000000..28c4c87
--- /dev/null
+++ b/test/cases/grid-options.css
@@ -0,0 +1,79 @@
+/*****************\
+  AREAS ALGORITHM
+\*****************/
+
+.grid-template-areas {
+  display: grid;
+  grid-template-areas:
+    "a-conflict a-conflict"
+    "b-conflict b-conflict";
+}
+
+.grid-template-areas.conflict {
+  display: grid;
+  grid-template-areas:
+    "a-conflict"
+    "b-conflict";
+}
+
+.a {
+  grid-area: a-conflict;
+}
+
+.b {
+  grid-area: b-conflict;
+}
+
+.grid-template {
+  grid-template:
+      [header-left] "head head" 30px [header-right]
+      [main-left]   "nav  main" 1fr  [main-right]
+      [footer-left] "nav  foot" 30px [footer-right]
+      / 120px repeat(4, 250px 10px);
+}
+
+@media (min-width: 1000px) {
+  .grid-template {
+    grid-template:
+        [header-left] "head" 30px [header-right]
+        [nav-left]    "nav"  auto  [nav-right]
+        [main-left]   "main" 1fr  [main-right]
+        [footer-left] "foot" 30px [footer-right]
+        / 1fr;
+  }
+}
+
+.grid-template.conflict {
+  grid-template:
+      "head head"
+      "nav main" 20px
+      "nav foot"
+      / 1fr 1fr;
+}
+
+.head {
+  grid-area: head;
+}
+
+.main {
+  grid-area: main;
+}
+
+.nav {
+  grid-area: nav;
+}
+
+.foot {
+  grid-area: foot;
+}
+
+/*********************\
+  AUTOPLACE ALGORITHM
+\*********************/
+
+.grid-autoplace {
+  display: grid;
+  grid-template-columns: 1fr 1fr 1fr;
+  grid-template-rows: auto;
+  grid-gap: 30px;
+}
diff --git a/test/cases/grid-options.disabled.out.css b/test/cases/grid-options.disabled.out.css
new file mode 100644
index 0000000..28c4c87
--- /dev/null
+++ b/test/cases/grid-options.disabled.out.css
@@ -0,0 +1,79 @@
+/*****************\
+  AREAS ALGORITHM
+\*****************/
+
+.grid-template-areas {
+  display: grid;
+  grid-template-areas:
+    "a-conflict a-conflict"
+    "b-conflict b-conflict";
+}
+
+.grid-template-areas.conflict {
+  display: grid;
+  grid-template-areas:
+    "a-conflict"
+    "b-conflict";
+}
+
+.a {
+  grid-area: a-conflict;
+}
+
+.b {
+  grid-area: b-conflict;
+}
+
+.grid-template {
+  grid-template:
+      [header-left] "head head" 30px [header-right]
+      [main-left]   "nav  main" 1fr  [main-right]
+      [footer-left] "nav  foot" 30px [footer-right]
+      / 120px repeat(4, 250px 10px);
+}
+
+@media (min-width: 1000px) {
+  .grid-template {
+    grid-template:
+        [header-left] "head" 30px [header-right]
+        [nav-left]    "nav"  auto  [nav-right]
+        [main-left]   "main" 1fr  [main-right]
+        [footer-left] "foot" 30px [footer-right]
+        / 1fr;
+  }
+}
+
+.grid-template.conflict {
+  grid-template:
+      "head head"
+      "nav main" 20px
+      "nav foot"
+      / 1fr 1fr;
+}
+
+.head {
+  grid-area: head;
+}
+
+.main {
+  grid-area: main;
+}
+
+.nav {
+  grid-area: nav;
+}
+
+.foot {
+  grid-area: foot;
+}
+
+/*********************\
+  AUTOPLACE ALGORITHM
+\*********************/
+
+.grid-autoplace {
+  display: grid;
+  grid-template-columns: 1fr 1fr 1fr;
+  grid-template-rows: auto;
+  grid-gap: 30px;
+}
diff --git a/test/cases/grid-options.no-autoplace.out.css b/test/cases/grid-options.no-autoplace.out.css
new file mode 100644
index 0000000..ba911d3
--- /dev/null
+++ b/test/cases/grid-options.no-autoplace.out.css
@@ -0,0 +1,161 @@
+/*****************\
+  AREAS ALGORITHM
+\*****************/
+
+.grid-template-areas {
+  display: -ms-grid;
+  display: grid;
+      grid-template-areas:
+    "a-conflict a-conflict"
+    "b-conflict b-conflict";
+}
+
+.grid-template-areas.conflict {
+  display: -ms-grid;
+  display: grid;
+      grid-template-areas:
+    "a-conflict"
+    "b-conflict";
+}
+
+.a {
+  -ms-grid-row: 1;
+  -ms-grid-column: 1;
+  -ms-grid-column-span: 2;
+  grid-area: a-conflict;
+}
+
+.grid-template-areas.conflict > .a {
+  -ms-grid-row: 1;
+  -ms-grid-column: 1;
+  -ms-grid-column-span: 1;
+}
+
+.b {
+  -ms-grid-row: 2;
+  -ms-grid-column: 1;
+  -ms-grid-column-span: 2;
+  grid-area: b-conflict;
+}
+
+.grid-template-areas.conflict > .b {
+  -ms-grid-row: 2;
+  -ms-grid-column: 1;
+  -ms-grid-column-span: 1;
+}
+
+.grid-template {
+  -ms-grid-rows: 30px 1fr 30px;
+  -ms-grid-columns: 120px (250px 10px)[4];
+      grid-template:
+      [header-left] "head head" 30px [header-right]
+      [main-left]   "nav  main" 1fr  [main-right]
+      [footer-left] "nav  foot" 30px [footer-right]
+      / 120px repeat(4, 250px 10px);
+}
+
+@media (min-width: 1000px) {
+  .grid-template {
+    -ms-grid-rows: 30px auto 1fr 30px;
+    -ms-grid-columns: 1fr;
+        grid-template:
+        [header-left] "head" 30px [header-right]
+        [nav-left]    "nav"  auto  [nav-right]
+        [main-left]   "main" 1fr  [main-right]
+        [footer-left] "foot" 30px [footer-right]
+        / 1fr;
+  }
+}
+
+.grid-template.conflict {
+  -ms-grid-rows: auto 20px auto;
+  -ms-grid-columns: 1fr 1fr;
+      grid-template:
+      "head head"
+      "nav main" 20px
+      "nav foot"
+      / 1fr 1fr;
+}
+
+.head {
+  -ms-grid-row: 1;
+  -ms-grid-column: 1;
+  -ms-grid-column-span: 2;
+  grid-area: head;
+}
+
+.grid-template.conflict > .head {
+  -ms-grid-row: 1;
+  -ms-grid-column: 1;
+  -ms-grid-column-span: 2;
+}
+
+.main {
+  -ms-grid-row: 2;
+  -ms-grid-column: 2;
+  grid-area: main;
+}
+
+.grid-template.conflict > .main {
+  -ms-grid-row: 2;
+  -ms-grid-column: 2;
+}
+
+.nav {
+  -ms-grid-row: 2;
+  -ms-grid-row-span: 2;
+  -ms-grid-column: 1;
+  grid-area: nav;
+}
+
+.grid-template.conflict > .nav {
+  -ms-grid-row: 2;
+  -ms-grid-row-span: 2;
+  -ms-grid-column: 1;
+}
+
+.foot {
+  -ms-grid-row: 3;
+  -ms-grid-column: 2;
+  grid-area: foot;
+}
+
+.grid-template.conflict > .foot {
+  -ms-grid-row: 3;
+  -ms-grid-column: 2;
+}
+
+@media (min-width: 1000px) {
+  .head {
+    -ms-grid-row: 1;
+    -ms-grid-column: 1;
+    -ms-grid-column-span: 1;
+  }
+  .main {
+    -ms-grid-row: 3;
+    -ms-grid-column: 1;
+  }
+  .nav {
+    -ms-grid-row: 2;
+    -ms-grid-row-span: 1;
+    -ms-grid-column: 1;
+  }
+  .foot {
+    -ms-grid-row: 4;
+    -ms-grid-column: 1;
+  }
+}
+
+/*********************\
+  AUTOPLACE ALGORITHM
+\*********************/
+
+.grid-autoplace {
+  display: -ms-grid;
+  display: grid;
+  -ms-grid-columns: 1fr 1fr 1fr;
+  grid-template-columns: 1fr 1fr 1fr;
+  -ms-grid-rows: auto;
+  grid-template-rows: auto;
+  grid-gap: 30px;
+}
diff --git a/test/cases/grid-status.css b/test/cases/grid-status.css
index a2bfd5f..3808412 100644
--- a/test/cases/grid-status.css
+++ b/test/cases/grid-status.css
@@ -33,3 +33,25 @@
     grid-auto-rows: 100px;
   }
 }
+
+.grid-autoplace-enabled {
+  /* autoprefixer grid: autoplace */
+  display: grid;
+  grid-template-columns: 1fr 1fr 1fr;
+  grid-template-rows: auto;
+  grid-gap: 30px;
+}
+
+.grid-autoplace-disabled {
+  /* autoprefixer grid: off */
+  /* autoprefixer grid: autoplace */
+  grid-template-columns: 1fr 1fr 1fr;
+  grid-template-rows: auto;
+  grid-gap: 30px;
+}
+
+.grid-autoplace-disabled-2 {
+  /* autoprefixer grid: no-autoplace */
+  grid-template-columns: 1fr 1fr 1fr;
+  grid-template-rows: auto;
+}
diff --git a/test/cases/grid-status.out.css b/test/cases/grid-status.out.css
index a07e4a5..e188c1d 100644
--- a/test/cases/grid-status.out.css
+++ b/test/cases/grid-status.out.css
@@ -11,9 +11,9 @@
   display: -ms-grid;
   display: grid;
   -ms-grid-columns: 1fr 1fr 1fr;
-      grid-template-columns: 1fr 1fr 1fr;
+  grid-template-columns: 1fr 1fr 1fr;
   -ms-grid-rows: 100px 100px;
-      grid-template-rows: 100px 100px;
+  grid-template-rows: 100px 100px;
   /* autoprefixer: ignore next */
   grid-auto-flow: column;
 }
@@ -37,3 +37,45 @@
     grid-auto-rows: 100px;
   }
 }
+
+.grid-autoplace-enabled {
+  /* autoprefixer grid: autoplace */
+  display: -ms-grid;
+  display: grid;
+  -ms-grid-columns: 1fr 30px 1fr 30px 1fr;
+  grid-template-columns: 1fr 1fr 1fr;
+  -ms-grid-rows: auto;
+  grid-template-rows: auto;
+  grid-gap: 30px;
+}
+
+.grid-autoplace-enabled > *:nth-child(1) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 1;
+}
+
+.grid-autoplace-enabled > *:nth-child(2) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 3;
+}
+
+.grid-autoplace-enabled > *:nth-child(3) {
+  -ms-grid-row: 1;
+  -ms-grid-column: 5;
+}
+
+.grid-autoplace-disabled {
+  /* autoprefixer grid: off */
+  /* autoprefixer grid: autoplace */
+  grid-template-columns: 1fr 1fr 1fr;
+  grid-template-rows: auto;
+  grid-gap: 30px;
+}
+
+.grid-autoplace-disabled-2 {
+  /* autoprefixer grid: no-autoplace */
+  -ms-grid-columns: 1fr 1fr 1fr;
+  grid-template-columns: 1fr 1fr 1fr;
+  -ms-grid-rows: auto;
+  grid-template-rows: auto;
+}
diff --git a/test/cases/grid.css b/test/cases/grid.css
index da1e7a1..31aa10f 100644
--- a/test/cases/grid.css
+++ b/test/cases/grid.css
@@ -159,3 +159,11 @@
     ". . . . . ."
     ". . . . . .";
 }
+
+.warn-auto-flow {
+  grid-auto-flow: column;
+  grid-template-columns: 1fr 1fr;
+  grid-template-areas:
+      ". ."
+      ". .";
+}
diff --git a/test/cases/grid.disabled.css b/test/cases/grid.disabled.css
index cf78178..5e9e0e0 100644
--- a/test/cases/grid.disabled.css
+++ b/test/cases/grid.disabled.css
@@ -163,3 +163,11 @@
     ". . . . . ."
     ". . . . . .";
 }
+
+.warn-auto-flow {
+  grid-auto-flow: column;
+  grid-template-columns: 1fr 1fr;
+  grid-template-areas:
+      ". ."
+      ". .";
+}
diff --git a/test/cases/grid.out.css b/test/cases/grid.out.css
index 418df6a..d6f4ef6 100644
--- a/test/cases/grid.out.css
+++ b/test/cases/grid.out.css
@@ -213,3 +213,12 @@
     ". . . . . ."
     ". . . . . .";
 }
+
+.warn-auto-flow {
+  grid-auto-flow: column;
+  -ms-grid-columns: 1fr 1fr;
+  grid-template-columns: 1fr 1fr;
+  grid-template-areas:
+      ". ."
+      ". .";
+}