autoprefixer: [css-grid] Idea on how to 100% support duplicate area names

I’ve realized a use case where duplicate area names makes sense.

<div class="grid">
  <div class="grid-cell a"></div>
  <div class="grid-cell b"></div>
</div>

<!-- I want this to have a slightly different layout. -->
<!-- It is the same component but this time with a modifier class on it -->
<div class="grid conflict">
  <div class="grid-cell a"></div>
  <div class="grid-cell b"></div>
</div>

Input CSS

.grid {
  display: grid;
  grid-template-areas:
    "a b";
}

.grid.conflict {
  display: grid;
  grid-template-areas:
    "a"
    "b";
}

.a { grid-area: a; }
.b { grid-area: b; }

Current Output CSS (and it warns the user that there is a duplicate area name in rule .grid.conflict)

.grid {
  display: -ms-grid;
  display: grid;
  grid-template-areas: "a b";
}

.grid.conflict {
  display: -ms-grid;
  display: grid;
  grid-template-areas:
    "a"
    "b";
}

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

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

This is my proposed output idea:

.grid {
  display: -ms-grid;
  display: grid;
  grid-template-areas: "a b";
}

.grid.conflict {
  display: -ms-grid;
  display: grid;
  grid-template-areas:
    "a"
    "b";
}

/* It uses the first area by default */
.a {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
  grid-area: a;
}
.b {
  -ms-grid-row: 1;
  -ms-grid-column: 2;
  grid-area: b;
}

/* It has detected a conflict, it now prefixes with the conflicting grid selector */
.grid.conflict > .a {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
}
.grid.conflict > .b {
  -ms-grid-row: 2;
  -ms-grid-column: 1;
}

This is what we know purely from looking at the CSS and knowing how CSS Grid works:

  • A grid cell must be a direct descendant of the parent grid container that controls it in the HTML for CSS Grid to work.
  • .grid.conflict > .a will only work on .a elements that have been placed directly inside a .grid.conflict element.
  • .grid.conflict > .a will have no effect on .a elements inside .grid elements.
  • .grid.conflict > .a will have no effect on .a elements nested deeply inside .grid.conflict elements.

If we create these additional prefixed rules with [grid-selector] > I think we can pretty safely support duplicate area names without having to give out a warning.

There is a danger in that we are increasing the rule specificity. I think specificity issues will be easier to work around than trying to work around not being able to use duplicate area names though.

For example, you could work around the specificity issue by writing a rule like .grid > .a { grid-area: a; } instead of just .a { grid-area: a; }.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 25 (25 by maintainers)

Commits related to this issue

Most upvoted comments

it won’t be much of a problem to implement it. @bogdan0083

Lol, so much for not being a problem to implement. It ended up needing the entire area names part of Autoprefixer to be re-written. 😆

Thank you very much for the comments! They are really helpful and informative. I’m going to open WIP PR soon and we will work through every detail step by step 😃

Oh I just realized that display: contents; is another thing that will cause issues.

<div class="grid">
    <div class="display-contents-element">
        <div class="grid-cell a"></div>
        <div class="grid-cell b"></div>
    </div>
</div>
<div class="grid conflict">
    <div class="display-contents-element">
        <div class="grid-cell a"></div>
        <div class="grid-cell b"></div>
    </div>
</div>
/* This allows the grid to ignore .display-contents-element in modern browsers */
.display-contents-element {
  display: contents;
}

.grid {
  display: grid;
  grid-template-areas:
    "a b";
}
.grid.conflict {
  display: grid;
  grid-template-areas:
    "a"
    "b";
}
.a { grid-area: a; }
.b { grid-area: b; }
/* This will not work in this scenario */
.grid.conflict > .a {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
}
.grid.conflict > .b {
  -ms-grid-row: 2;
  -ms-grid-column: 1;
}

To avoid this issue, I think if the grid setting is enabled we should just shout out a warning not to use display: contents if someone uses it. We have no way of getting IE to replicate display: contents functionality anyway so I think preventing people from using display: contents is a fair restriction to put on people that want to use Autoprefixer grid translations.

Awesome! I wasn’t sure how difficult it would be to implement.

If we could get this issue fixed then it would open up a whole new world of new CSS Grid in IE possibilities! 🤩

Wow! This idea is looking awesome and it won’t be much of a problem to implement it. I need to think about it in my spare time.