Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CSS Grid utilities #1274

Merged
merged 9 commits into from Dec 30, 2019
Merged

Add CSS Grid utilities #1274

merged 9 commits into from Dec 30, 2019

Conversation

@adamwathan
Copy link
Member

adamwathan commented Dec 24, 2019

This PR adds support for CSS Grid Layout to Tailwind CSS.

Here is an example of what it looks like to use these new utilities:

<div class="grid grid-cols-8 col-gap-6 row-gap-6">
  <div class="col-span-3"></div>
  <div class="col-span-3"></div>
  <div class="col-start-4 col-end-8"></div>
  <div class="col-span-4 col-start-2"></div>
  <div class="col-span-6 col-end-9"></div>
</div>

It adds a new grid value to the display core plugin, as well as provides new core plugins for the following CSS properties:

  • grid-template-columns
  • grid-column-gap
  • grid-column
  • grid-column-start
  • grid-column-end
  • grid-template-rows
  • grid-row-gap
  • grid-row
  • grid-row-start
  • grid-row-end

grid-template-columns

These utilities take the form grid-cols-{key} where "key" is any value configured under the gridTemplateColumns key in your theme config.

By default we provide the necessary values to create basic equal width column grids with up to 12 columns:

gridTemplateColumns: {
  '1': 'repeat(1, 1fr)',
  '2': 'repeat(2, 1fr)',
  '3': 'repeat(3, 1fr)',
  '4': 'repeat(4, 1fr)',
  '5': 'repeat(5, 1fr)',
  '6': 'repeat(6, 1fr)',
  '7': 'repeat(7, 1fr)',
  '8': 'repeat(8, 1fr)',
  '9': 'repeat(9, 1fr)',
  '10': 'repeat(10, 1fr)',
  '11': 'repeat(11, 1fr)',
  '12': 'repeat(12, 1fr)',
}

I've opted to avoid any weird magic here and instead just given the user complete control over the value of this property, so although I'm just using repeat(x, 1fr) here for each value, there's absolutely nothing stopping you from creating something more custom like so:

gridTemplateColumns: {
  // Would create a class called `grid-cols-header`
  'header': '100px minmax(min-content, 600px) 1fr',
}

Providing a basic 12 column grid seemed like the most sensible thing to do by default, as there aren't many other good ideas I can think of that are actually general purpose and not hyper-specific to one site design.

grid-column-gap

These utilities take the form col-gap-{key} where "key" is any value configured under the gridColumnGap key in your theme config.

By default, this uses your spacing config, and therefore matches all of your padding/margin/width/height utilities.

grid-column

These utilities take the form col-{key} where "key" is any value configured under the gridColumn key in your theme config.

By default we only provide values for spanning across columns:

gridColumn: {
  'span-1': 'span 1 / span 1',
  'span-2': 'span 2 / span 2',
  'span-3': 'span 3 / span 3',
  'span-4': 'span 4 / span 4',
  'span-5': 'span 5 / span 5',
  'span-6': 'span 6 / span 6',
  'span-7': 'span 7 / span 7',
  'span-8': 'span 8 / span 8',
  'span-9': 'span 9 / span 9',
  'span-10': 'span 10 / span 10',
  'span-11': 'span 11 / span 11',
  'span-12': 'span 12 / span 12',
}

Again no magic or assumptions here at all — I've included the word span explicitly in each key to make sure the utilities are generated like col-span-5 for our default values, but you can totally do whatever you want here, like:

gridColumn: {
  'logo-area': 'my-logo-area-label',
}

...to generate a class that fills a named column area like col-logo-area.

The reason I've duplicated the value (like span 2 / span 2) is so that you can easily override just the grid-column-start or grid-column-end value without losing the span value, like this:

<div class="col-span-4 col-start-2"></div>

...which would create an element that spans 4 columns but starts at grid line 2.

grid-column-start

These utilities take the form col-start-{key} where "key" is any value configured under the gridColumnStart key in your theme config.

By default we only provide values that match the grid lines created by our default gridTemplateColumns config:

gridColumnStart: {
  '1': '1',
  '2': '2',
  '3': '3',
  '4': '4',
  '5': '5',
  '6': '6',
  '7': '7',
  '8': '8',
  '9': '9',
  '10': '10',
  '11': '11',
  '12': '12',
  '13': '13',
},

grid-column-end

These utilities take the form col-end-{key} where "key" is any value configured under the gridColumnEnd key in your theme config.

By default we only provide values that match the grid lines created by our default gridTemplateColumns config:

gridColumnEnd: {
  '1': '1',
  '2': '2',
  '3': '3',
  '4': '4',
  '5': '5',
  '6': '6',
  '7': '7',
  '8': '8',
  '9': '9',
  '10': '10',
  '11': '11',
  '12': '12',
  '13': '13',
},

grid-template-rows

These utilities take the form grid-rows-{key} where "key" is any value configured under the gridTemplateRows key in your theme config.

By default we do not provide any values for this utility at all:

gridTemplateRows: {}

That means no grid-rows-{key} utilities are generated by default, and if you'd like to add them you need to customize your config.

This is because I just could not think of any sensible general purpose default values for this — any real-world use case I could come up with seemed too specific to a given design.

grid-row-gap

These utilities take the form row-gap-{key} where "key" is any value configured under the gridRowGap key in your theme config.

By default, this uses your spacing config, and therefore matches all of your padding/margin/width/height utilities.

grid-row

These utilities take the form row-{key} where "key" is any value configured under the gridRow key in your theme config.

By default we do not provide any values for this utility at all:

gridRow: {}

That means no row-{key} utilities are generated by default, and if you'd like to add them you need to customize your config.

This is for the same reason as grid-template-rows.

grid-row-start

These utilities take the form row-start-{key} where "key" is any value configured under the gridRowStart key in your theme config.

By default we do not provide any values for this utility at all:

gridRowStart: {}

That means no row-start-{key} utilities are generated by default, and if you'd like to add them you need to customize your config.

This is for the same reason as grid-template-rows.

grid-row-end

These utilities take the form row-end-{key} where "key" is any value configured under the gridRowEnd key in your theme config.

By default we do not provide any values for this utility at all:

gridRowEnd: {}

That means no row-end-{key} utilities are generated by default, and if you'd like to add them you need to customize your config.

This is for the same reason as grid-template-rows.

What's not included

  • grid-auto-columns utilities
  • grid-auto-rows utilities
  • grid-auto-flow utilities
  • grid-template-areas utilities

If you think any of these are super important in a utility context, please reply with a good example and any ideas you have on how it should be included and we can definitely talk about getting it in.

Try it out

Here's a simple tailwind.run where I've thrown in the pre-compiled CSS so you can play with it:

https://tailwind.run/MSuVJB/1

Any feedback appreciated!

@adarsh4d

This comment has been minimized.

Copy link

adarsh4d commented Dec 24, 2019

How about adding the grid-gap property with class name as grid-gap-{key}, this way we can set both the column and row gap using a single class.

@mtangoo

This comment has been minimized.

Copy link

mtangoo commented Dec 24, 2019

Nice one!
But I see inconsistency in using col(s) and grid-column-gap
Wasn't it supposed to be grid-col-gap?

@shaneoliver

This comment has been minimized.

Copy link

shaneoliver commented Dec 24, 2019

I think you should drop 'grid-' from grid-column-gap and grid-row-gap as the spec now defines these as simply row-gap and column-gap https://developer.mozilla.org/en-US/docs/Web/CSS/gap

Also because these properties will apply to the subgrid and flex display types soon too

@adamwathan

This comment has been minimized.

Copy link
Member Author

adamwathan commented Dec 24, 2019

There is no grid- prefix on the gap utilities already 👍🏻

@shaneoliver

This comment has been minimized.

Copy link

shaneoliver commented Dec 24, 2019

Ahh my bad, mistook the heading of the related sections. Looks like a really solid and flexible implemention

@adamwathan

This comment has been minimized.

Copy link
Member Author

adamwathan commented Dec 25, 2019

@adarsh4d Good catch on the gap-* utilities, I somehow totally missed that. I've added those and removed the default col-gap and row-gap values to keep the file size from ballooning completely unnecessarily (but the utilities are still there if you wanted to add values yourself).

One thing I'm wondering, in the latest version of the spec these properties are just gap, col-gap, and row-gap respectively, but you still need the grid- prefix in Safari and non-Chromium Edge. Unfortunately autoprefixer doesn't handle this case for some reason, so I don't feel super comfortable shipping them without the prefixes but I also don't really want to add them manually.

Should we just use the old names since they will be supported forever anyways? Should we manually prefix? Should I annoy @ai to reconsider prefixing them in autoprefixer? 👀

@MrJmpl3

This comment has been minimized.

Copy link

MrJmpl3 commented Dec 25, 2019

@adamwathan Remember the bug in Flexbox and CSS Grid with overflow and fr units.

Solution: Use the hack minmax(0, 1fr);

@ai

This comment has been minimized.

Copy link

ai commented Dec 25, 2019

@Dan503 do you think that it is safe to use Autoprefixer Grid in this case?

@adamwathan

This comment has been minimized.

Copy link
Member Author

adamwathan commented Dec 25, 2019

@MrJmpl3 I'm not familiar, any chance you could share something for me to learn more about it?

Edit: Looks like it's explained pretty well here:

https://css-tricks.com/preventing-a-grid-blowout/

I'll update to use minmax(0, 1fr) instead of just 1fr 👍

@adamwathan

This comment has been minimized.

Copy link
Member Author

adamwathan commented Dec 25, 2019

Pushed a change to rename the gap related core plugins, and include both the old and new property names for each utility to maintain backward compatibility with older browsers manually. I really feel like this is a great candidate for autoprefixer though, because you can detect whether or not this actually needs to happen based on the user's browserslist config.

@adamwathan adamwathan changed the base branch from v2 to master Dec 25, 2019
@Dan503

This comment has been minimized.

Copy link

Dan503 commented Dec 25, 2019

gap auto-prefixing

@ai I think Autoprefixer should support gap to grid-gap conversions. If you think about it, grid-gap is just a prefixed version of gap now that has become outdated. The only difference between this and a more typical prefix is that it doesn't have a dash at the start and isn't specific to one browser.

grid-column-end

In the documentation, you should add a note that IE does not support grid-column-end in any form even with Autoprefixer.

grid-template-rows

I've changed my mind about this

I think it is going to be really annoying for authors if absolutely no defaults are provided, especially if they just want something small like 2 or 3 rows. I think the same defaults should be applied that are being applied to columns. This provides a reasonable amount of rows for smaller row counts and you can create a square that is 12 columns by 12 rows. Higher row counts will require user configuration.

I'm using auto instead of 1fr because height is typically best determined by the content in that row rather than equal distribution of height across all rows.

gridTemplateRows: {
  '1': 'repeat(1, auto)',
  '2': 'repeat(2, auto)',
  '3': 'repeat(3, auto)',
  '4': 'repeat(4, auto)',
  '5': 'repeat(5, auto)',
  '6': 'repeat(6, auto)',
  '7': 'repeat(7, auto)',
  '8': 'repeat(8, auto)',
  '9': 'repeat(9, auto)',
  '10': 'repeat(10, auto)',
  '11': 'repeat(11, auto)',
  '12': 'repeat(12, auto)',
},

Update

... actually... IE does have implicit rows that are auto sized by default. Modern browsers also have implicit rows that are auto by default. There is no need to explicitly tell the browser how many rows to use if all the row heights are auto in height. All this would do is add needless bloat to the CSS.

grid-row / grid-row-start / grid-row-end

I think the same default values that you provide for grid-column should also be applied to grid-row as well.

Imagine a scenario where all you want to do is place a grid cell on the second row of the grid. That is a scenario that you would expect Tailwind to support. If you provide no default values at all though then that isn't going to be possible without extra configuration settings.

This provides a reasonable amount of rows for smaller row counts and you can create a square that is 12 columns by 12 rows without having to add any custom settings.

Higher row counts will require user configuration.

@Dan503

This comment has been minimized.

Copy link

Dan503 commented Dec 25, 2019

You might also want to add /* autoprefixer: off */ control comments to the grid-[column/row]-end classes to prevent Autoprefixer from displaying warnings about not supporting grid-[column/row]-end.

If not, people will be flooded with the following warning message:

autoprefixer: C:\xxx\src\_styles\main.css:644:3: Can not prefix grid-column-end (grid-column-start is not found)
@MrJmpl3

This comment has been minimized.

Copy link

MrJmpl3 commented Dec 26, 2019

@adamwathan Here explain the bug, https://css-tricks.com/preventing-a-grid-blowout/

Edit: I see the edit.

@Dan503

This comment was marked as resolved.

Copy link

Dan503 commented Dec 26, 2019

That is an extremely good point @MrJmpl3!

In order to make the columns more intuitive for authors to use and prevent CSS blowouts, I would recommend making these the default column values. This prevents content from breaking the grid.

gridTemplateColumns: {
  '1': 'repeat(1, minmax(0, 1fr))',
  '2': 'repeat(2, minmax(0, 1fr))',
  '3': 'repeat(3, minmax(0, 1fr))',
  '4': 'repeat(4, minmax(0, 1fr))',
  '5': 'repeat(5, minmax(0, 1fr))',
  '6': 'repeat(6, minmax(0, 1fr))',
  '7': 'repeat(7, minmax(0, 1fr))',
  '8': 'repeat(8, minmax(0, 1fr))',
  '9': 'repeat(9, minmax(0, 1fr))',
  '10': 'repeat(10, minmax(0, 1fr))',
  '11': 'repeat(11, minmax(0, 1fr))',
  '12': 'repeat(12, minmax(0, 1fr))',
}

Update:

oh, he has already changed it to minmax(0, 1fr) in this comment #1274 (comment)

@adamwathan

This comment has been minimized.

Copy link
Member Author

adamwathan commented Dec 26, 2019

@Dan503 Thanks a ton for your input, really appreciate it!

I think the same default values that you provide for grid-column should also be applied to grid-row as well.

My instinct is definitely to agree with you but every time I try to think of real-world practical situations where this would be useful I struggle to come up with any. To me it feels like being able to control which row an element appears on is not useful unless there are a fixed number of rows 🤔

Can you think of any good examples of layouts/designs that we can use as a reference for helping determine what default values would actually be helpful?

@Dan503

This comment has been minimized.

Copy link

Dan503 commented Dec 26, 2019

To me it feels like being able to control which row an element appears on is not useful unless there are a fixed number of rows 🤔

It is useful for creating vertical white space in the design.

Try looking through some of the crazy things Jen Simmons has done as demos.

https://labs.jensimmons.com/

IE does have implicit rows that are auto sized by default. Modern browsers also have implicit rows that are auto by default.

When I said this, I was not referring to autoplacement. You can place things on the implicit grid explicitly. This code pen shows what I mean. That pen also works in IE if you view it in Debug mode.

https://codepen.io/daniel-tonon/pen/YvjLaa

There is no need to explicitly tell the browser how many rows to use if all the row heights are auto in height.

What I meant by that is that doing something like grid-template-rows: repeat(12, auto); is pointless because the implicit grid essentially gives you infinite auto sized rows by default for free on every grid.

The one use case where this logic breaks is if you want to use grid-row-end: -1. -1 counts from the end of the explicit grid and no explicit grid has been defined. That isn't a common enough use case though to be worth bloating the CSS with things like grid-template-rows: repeat(12, auto);

@Dan503

This comment has been minimized.

Copy link

Dan503 commented Dec 26, 2019

I asked Andrey if he could add gap to grid-gap conversions to Autoprefixer but he refused since it isn't an actual vendor prefix.

He said that he would add a warning to use postcss-preset-env though. The warning would appear if gap is detected without grid-gap and the browserslist config suggests that grid-gap is needed.

postcss/autoprefixer#1274

@Dan503

This comment has been minimized.

Copy link

Dan503 commented Dec 26, 2019

Would it be possible to import the grid component of Tailwind into projects without importing all of Tailwind?

I can see myself using these grid utilities but I don't want to go all in on using Tailwind to style everything on my sites.

@brandonpittman

This comment has been minimized.

Copy link

brandonpittman commented Dec 27, 2019

@Dan503 If you use PurgeCSS, any Tailwind classes you don't use will be gone anyway.

@adamwathan

This comment has been minimized.

Copy link
Member Author

adamwathan commented Dec 27, 2019

Would it be possible to import the grid component of Tailwind into projects without importing all of Tailwind?

Yep this is totally possible, you can use the corePlugins config option to specify which Tailwind utilities you actually want.

To just get grid utilities you'd do this:

// tailwind.config.js
module.exports = {
  corePlugins: [
    'display', // to get the `.grid` utility, but you'll also get `.block`, `.inline`, etc. so consider if you actually want that
    'gridTemplateColumns',
    'gridTemplateRows',
    'gap',
    'columnGap',
    'rowGap',
    'gridColumn',
    'gridColumnStart',
    'gridColumnEnd',
    'gridRow',
    'gridRowStart',
    'gridRowEnd',
}
@adamwathan

This comment has been minimized.

Copy link
Member Author

adamwathan commented Dec 30, 2019

Just pushed an update that added none/auto values for gridColumn, gridColumnStart, and gridColumnEnd utilities, as well as a new set of grid-auto-flow utilities:

  • grid-flow-row
  • grid-flow-col
  • grid-flow-row-dense
  • grid-flow-col-dense
@adamwathan

This comment has been minimized.

Copy link
Member Author

adamwathan commented Dec 30, 2019

Gonna merge this as-is for now, we can add default values for row utilities any time without it being a breaking change so for now let's just get a canary release out that includes this stuff so people can try it and provide feedback 👍

@adamwathan adamwathan merged commit 84c3bf3 into master Dec 30, 2019
1 check passed
1 check passed
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@adamwathan adamwathan deleted the grid-utilities branch Dec 30, 2019
@Dan503

This comment has been minimized.

Copy link

Dan503 commented Dec 30, 2019

With the row stuff, what is the harm in including it when the alternative is a massive inconvenience for devs that want to use it?

I think the row stuff will be useful to a fair few people.

The only harm I can think of is a little bit of CSS bloat. So just a couple extra bytes of data.

If a user really wants to cut down on bytes, then they can edit the tailwind.config.js file to remove it.

I just think that for the average user, they would expect to be able to place something on the second row of a grid without having to worry about editing the config settings.

grid-template-rows should have no default settings because there are no sensible defaults that you don't get for free with the implicit grid. Everything else row related should match how columns work.

@adamwathan

This comment has been minimized.

Copy link
Member Author

adamwathan commented Dec 30, 2019

With the row stuff, what is the harm in including it when the alternative is a massive inconvenience for devs that want to use it?

The harm is that we provide default values that aren't actually useful in practice but can never remove them without a breaking change.

If you can provide a real example of how you'd use the 1-13 values for rowStart/rowEnd I would love to see it so I have something to use as a reference point when deciding what to include, but I still haven't seen an example of how it would be used.

A link to a CodePen/JSFiddle/whatever that shows a concrete example of a practical use case would be super helpful.

Edit: To clarify further, the examples I usually see for explicit row definitions/placement are for full page layouts with a narrow header, tall body section, and narrow footer. Us adding 1-13 rowStart/End values doesn't help people do that sort of thing at all, so I want to see some example where providing those by default actually helps someone do something. I'm not opposed to adding them at all, I just don't want to add the wrong defaults and be stuck with them forever, so we need to come up with some examples that justify the defaults.

@Dan503

This comment has been minimized.

Copy link

Dan503 commented Dec 30, 2019

A link to a CodePen/JSFiddle/whatever that shows a concrete example of a practical use case would be super helpful.

Ok but I probably won't be able to get around to it for a week or so due to new years.

@Dan503

This comment has been minimized.

Copy link

Dan503 commented Dec 30, 2019

Can you run this through Autoprefixer with IE grid conversions enabled?
(grid: "autoplace" in Autoprefixer settings or /* autoprefixer grid: autoplace */ at the top of the CSS file)

I'm certain that any user that tries to use this with autoprefixer grid settings enabled will get showered with warnings.

You just basically need to add /* autoprefixer: off; */ inside any class that triggers an Autoprefixer CSS Grid warning.

@brandonpittman

This comment has been minimized.

Copy link

brandonpittman commented Dec 30, 2019

Anybody have thoughts on ways to somehow use utility classes with grid-template? If I ever reach for grid, it’s as a template and never with explicit col-spans.

@PaulMorel

This comment has been minimized.

Copy link

PaulMorel commented Dec 30, 2019

grid-column-end

In the documentation, you should add a note that IE does not support grid-column-end in any form even with Autoprefixer.

I'm not sure if this was mentioned, but grid-column-end is supported by IE11 with Autoprefixer only when paired with a grid-column-start within the same selector.

Like @Dan503 mentionned, using grid-column-end alone makes Autoprefixer throw warnings.

I made a website back in August adding my own Tailwind style classes on top of Tailwind to get good IE11 with Autoprefixer support and use CSS Grid. However, it adds HUGE overhead. Here's an example of one of the classes.

  .col-start-1.col-end-7 {
    grid-column-end: 7;
    grid-column-start: 1;
  }

After Autoprefixer

  .col-start-1.col-end-7 {
    -ms-grid-column-span: 6;
    grid-column-end: 7;
    -ms-grid-column: 1;
        grid-column-start: 1;
  }

This works in IE11. But the file size isn't great. Accounting for every column and breakpoint my site has, this adds 115 KB to my CSS (prior to optimization). PurgeCSS / UnCSS is essential here.

If generating this kind markup could be an option, that would be really great.

For the curious, I essentially use 3 nested loops in SASS to generate the CSS. One loop for each breakpoint, one for the start index and one for the end index. Then I copied the result over to my Tailwind project. Not very clean, but it works.

@vricop

This comment has been minimized.

Copy link

vricop commented Dec 30, 2019

IE10+ does not support autoplacment. You need to place every children mamually, otherwise they'll stack. So what's the point?

I don't think it's worth it. A better approach would be 'gracefull degradation'. You could fallback to flexbox or something else.

IE10+ is holding the web back. We already have powerful tools at our disposal.

@vricop

This comment has been minimized.

Copy link

vricop commented Dec 30, 2019

Gaps are not supported either, you have to fake them with small columns and rows. Again, not worth the effort.

@adamwathan

This comment has been minimized.

Copy link
Member Author

adamwathan commented Dec 30, 2019

Personally I am not interested in supporting/catering to IE11 at all with our CSS Grid stuff. If people need IE11 support I would recommend they use Flexbox or write their own IE11-friendly grid code.

@PaulMorel

This comment has been minimized.

Copy link

PaulMorel commented Dec 30, 2019

Fair enough, I'll keep doing what I'm doing when I need the CSS Grid for IE11 in the style of Tailwind.

@vricop

This comment has been minimized.

Copy link

vricop commented Dec 30, 2019

@PaulMorel I experimented placing children elements for IE10+ in the past. This technique uses nth-child pseudo classes. I even created a sass mixing for that.

Here's a codepen demo: https://codepen.io/vrico/pen/MLzMdz
And the sass mixing: https://gist.github.com/vricop/67668eb0baaaffb2a0336fd9c6b9b6db

@Dan503

This comment has been minimized.

Copy link

Dan503 commented Dec 30, 2019

@adamwathan can you please just add /* autoprefixer: off */ to the classes that cause Autoprefixer warnings? When i make that example layout I'll show you how Tailwind can support IE11 without massively exploding the file size. I'll also create a list of properties for you that will need to be ignored by Autoprefixer.

For just a few extra comments in the CSS you can bring tremendous value to thousands of developers all over the world.

@PaulMorel This is the completely wrong way to do an IE friendly Tailwind.

.col-start-1.col-end-7 {
    grid-column-end: 7;
    grid-column-start: 1;
  }

You can still use CSS Grid with IE in Tailwind by relying on col-start and col-span rather than col-start and col-end.

For example to do an IE friendly version of the CSS posted above:

.col-start-1 {
  grid-col-start: 1;
}
.col-span-6 {
  grid-column: span 6;
}
<div class="col-start-1 col-span-6">

That will compile to this with Autoprefixer:

.col-start-1 {
  -ms-grid-column-start: 1;
  grid-columm-start: 1;
}
.col-span-6 {
  -ms-grid-column-span: 6;
  grid-column: span 6;
}
<div class="col-start-1 col-span-6">

No massive increase in file size and it works perfectly in IE 😊

PS. I'm the Author of the CSS Grid in IE series by the way. 🤓
https://css-tricks.com/css-grid-in-ie-css-grid-and-the-new-autoprefixer/

@vricop

This comment has been minimized.

Copy link

vricop commented Dec 30, 2019

@Dan503 As I already said, IE11 doesn't have full support for Grid. No autoplacement, and no gaps are implemented, and they'll never be.

I read you article some time ago. It's cool, but at the end of the day you end up doing more work than just using flexbox. It doesn't pay off.

@Dan503

This comment has been minimized.

Copy link

Dan503 commented Dec 30, 2019

Gaps are possible through Autoprefixer...though it needs to all be in the same rule so you might have a point there. I disagree in general about CSS Grid being more trouble than it is worth though.

All I'm asking for are a few Autoprefixer control comments to prevent the warnings from appearing, then developers can decide for themselves if they think it is worth the trouble or not.

@vricop

This comment has been minimized.

Copy link

vricop commented Dec 31, 2019

If I'm not wrong the grid implementation in tailwind is aiming to bring basic columns and rows. If there's no autoplacment in IE and you need a class for every cell in order to place it in the right slot, that means more code than just using flexbox.

I get it, you only need a comment in there. But maybe other devs don't want such a verbose output. I could be wrong.

@adamwathan

This comment has been minimized.

Copy link
Member Author

adamwathan commented Dec 31, 2019

can you please just add /* autoprefixer: off */ to the classes that cause Autoprefixer warnings?

These warnings will only appear with the grid: "autoplace" option enabled right? I'll explore it, it's surprisingly more complicated than it sounds to add the comments, because postcss-js (the library we use for creating the CSS) has no way of creating comment nodes.

I still think you should just not use CSS Grid if you have to support legacy browsers personally. I've literally never actually needed CSS Grid for any project I've ever worked on 👀

Somewhat related, still surprised prefixing column-gap as grid-column-gap is outside of Autoprefixer's scope but doing all this complex rule creation to try and translate grid rules for IE11 is in scope 🤔

@vricop

This comment has been minimized.

Copy link

vricop commented Dec 31, 2019

I love grid, you can build columns in a breeze with much less code. You can even (almost) build responsive columns without mediaqueries. The problem is grid-template-columns —when using minmax() function. If the min value is greater than the viewport width you'll get an horizontal overflow.

When min(), max() and clamp() get wider support we'll be able to create reponsive grid without mediaqueries. That's when people will really get onboard.

/* Now */
.mygrid {
  display: grid;
  gap: 1.5rem;
  /* Horizontal overflow in small devices */
  grid-template-column: repeat(auto-fit, minmax(400px, 1fr));
}

/* When min, max and clamp get wider support */
.mygrid {
  display: grid;
  gap: 1.5rem;
  /* No more overflow issues */
  grid-template-columns: repeat(auto-fit, minmax(min(400px, 100%), 1fr));
}
@vricop

This comment has been minimized.

Copy link

vricop commented Dec 31, 2019

@adamwathan There are some cases when using Grid makes more sense than Flexbox. Supporting IE11 in those cases is less painful. One of those scenarios could be when building masthead menus (logo on one side, menu in the other).

Wes Boss has a great free course about CSS Grid https://cssgrid.io/. In "Flexbox Vs CSS Grid" video he explains good cases for using CSS Grid over Flexbox. Worth checking out.

@Dan503

This comment has been minimized.

Copy link

Dan503 commented Jan 4, 2020

I put together a bit of a demo to demonstrate how people might make use of rows in tailwind:

https://codepen.io/daniel-tonon/pen/YzPEOWN

It is IE11 compatible. You can view the IE version by viewing in Debug mode and pasting the debug mode url into IE11.

I didn't make it responsive since the goal was just to show the use case.

The row declarations for the main outer layout aren't necessary in modern browsers but they are needed for IE compatibility.

The rows for the listing are necessary in modern browsers since the image comes after the title in the HTML for accessibility.

@gcoda

This comment has been minimized.

Copy link

gcoda commented Jan 13, 2020

How about adding negative start\end columns by default?

module.exports = {
  theme: {
    numbers: {
      '1': '1',
      '2': '2',
      '3': '3',
      // ...
    },
    extend: {
      gridColumnEnd: (theme, { negative }) => negative(theme('numbers')),
      gridColumnStart: (theme, { negative }) => negative(theme('numbers')),
    },
  },
}

imho it's really useful and rarely mentioned.

.-col-end-1 will make cell span to the end of row.
.-col-start-2.-col-end-1 and cell will be always last no matter how many columns grid have.

@terryupton

This comment has been minimized.

Copy link

terryupton commented Jan 17, 2020

Just to chime in on grid rows and why I believe that the gridRow, gridRowStart and gridRowEnd should be included in the default.

So I am currently building the following design.
Screenshot 2020-01-17 at 16 46 50

This is to a degree a standard desktop layout of a modern design, where elements sit in columns that overlap rows and sometimes will overlap columns. Looking at several of my recent designs and other designs across the web, non-symmetrical layouts and overlapping design elements are quite trendy and becoming quite common (IMO and from my observation).

So taking the above design, I started to craft this together using the current 1.2.0-canary.5 build (at the time of writing). It become apparent quite early on that I was going to need css-grid rows.
So as a starting point I included the following config:

    gridRow: theme => theme('gridColumn'),
    gridRowStart: theme => theme('gridColumnStart'),
    gridRowEnd: theme => theme('gridColumnEnd'),

What this allowed me to do was to set the rows for the main areas:

  • breadcrumbs
  • the tile image
  • content (title and accordion content)
  • decorative image

By doing this I was then able to get the breadcrumbs and content sitting next to each other without a huge gap as without setting any rows, the rows would automatically be the height of the tile. As this was the first row.

This screenshot illustrates best:
Screenshot 2020-01-17 at 18 26 52

By adding the rows into the config, I could then create the following:
Screenshot 2020-01-17 at 18 27 27

Here is the final html that was used for the above:

  <main role="main" class="container px-6 pt-12 // grid gap-6 grid-cols-1 lg:grid-cols-8">
    
    
    <div class="relative lg:col-span-2 lg:row-span-2 max-w-xs">
      {% include 'pages/staff-handbook/_partials/tile.twig' %}
    </div>
    
    
    <div class="lg:col-span-5 lg:col-start-5 lg:row-start-1 lg:row-span-1">
      {% include 'pages/staff-handbook/_partials/breadcrumbs.twig' with { homeTitle: 'Staff Handbook'} %}
    </div>
    
    <article class="lg:col-span-5 lg:col-start-5 lg:row-start-2 lg:row-span-3">
      
      <h1 class="font-sans text-24 text-brand-grue-500 font-bold">{{ entry.title }}</h1>
      
      
      <div class="max-w-xl">
        {% for entry in entries %}
          <accordion title="{{ entry.title }}" {{ loop.first ? ':open="true"' }} class="border-b border-gray-200 pb-2 mb-8">
            <template #open>
            <span class="w-8 h-8 p-1 text-white bg-brand-grue-500 inline-flex mr-2">
              {{ svg('@webroot/assets/svg/Interface/plus-ui.svg', class='fill-current flex-shrink-0') }}
            </span>
            </template>
            
            <template #close>
            <span class="w-8 h-8 p-1 text-white bg-green-500 inline-flex mr-2">
              {{ svg('@webroot/assets/svg/Interface/minus-ui.svg', class='fill-current flex-shrink-0') }}
            </span>
            </template>
            <template #content>
              {% include 'pages/staff-handbook/_partials/matrix.twig' %}
            </template>
          </accordion>
        {% endfor %}
      
      </div>
    
    </article>
    
    <figure class="lg:col-span-2 lg:col-start-3 lg:row-start-3 px-8"
    >
      {% include
        '_includes/_components/image.twig' with {
        image:entry.tileImage.one,
        transform:'base',
        alt: entry.title,
        sizes:'auto',
        lazyLoad: 0,
        classes:'',
      } %}
    
    </figure>
  </main>

I think when it comes to building layouts, including the CSS grid rows is essential. It gives much more flexibility out the box, to be able to position elements and also finer control to move the order of these items around across different devices/breakpoints.

I think without rows, you are pretty limited to building just simply grids that are equal. So things like card and tile (grid) layouts, like this:
Screenshot 2020-01-17 at 18 31 53

Based on the above @adamwathan, if you agree to implement then it also might be worth changing the naming for the gridColumn, gridColumnStart and gridColumnEnd if they were used across both columns and rows, as I did in my config.
Having said this, I do suspect the requirement for the number of rows would be less (perhaps half) of that of the columns, but as we are likely talking a few bytes, it is perhaps sensible as a default for both to be same.

@terryupton

This comment has been minimized.

Copy link

terryupton commented Jan 19, 2020

@adamwathan would you also consider including '24': 'repeat(24, 1fr)', as a default for the Grid Columns? I have often designed to a 24 column grid as I fine it gives finer control over spacing as columns are half the size.

https://www.deeson.co.uk/blog/why-i-often-use-24-column-grid

@Dan503

This comment has been minimized.

Copy link

Dan503 commented Jan 19, 2020

I feel like supporting 24 columns by default adds a bit too much bloat 😕

@adarsh4d

This comment has been minimized.

Copy link

adarsh4d commented Jan 19, 2020

In my opinion there are not a lot of people who use it on regular basis. You can always extended the column to your needs, or create a plugin and use it in all the projects.

@gcoda

This comment has been minimized.

Copy link

gcoda commented Jan 19, 2020

did i miss a note on justify\align\content ?

.content-stretch { align-content: stretch } is possible and useful on grid.
I am also missing ~ self-justify-center: { justify-self: center } and i am not sure hot this should be called, but already using it...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.