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

[css-flexbox] Make it easier to define margins that only apply between flex-items #592

Closed
AmeliaBR opened this issue Oct 11, 2016 · 19 comments

Comments

@AmeliaBR
Copy link
Contributor

In flexbox it is often desired to apply a fixed or minimum margin between items, without adding a margin in between items and the edges of the container. As far as I can tell, there is no non-hacky way to do this.

The justify-content property allows you to specify that extra space should only go in between, and not at the edges. But if there isn't any extra space to distribute, that items end up squished next to each other with no margin.

If you apply a fixed margin on the individual flex items, you can ensure they are spaced out, but then that margin effectively creates extra padding space inside the flex container. This can throw off your overall page alignment.

For a single-line flex container, you could use :first-child/:last-child selectors to remove the margins on the outside edge. But that's not possible in a multi-line flex layout, when you don't know which items will be at the edges.

The "best" solution I've seen so far is the one used by @heydonworks in his fukol code snippet: apply a negative margin on the flex container to cancel out the margin on the flex items inside it. And then maybe wrap the flex container in an extra div if you need to apply its own positive margins under certain conditions.

This works for most cases, but it is undeniably a hack. Can we get a neater solution? Perhaps a flex-specific margin property that overrides the regular margin in the flex-direction and has a space-around vs space-between option? Perhaps this could be part of the spec update that also figures out what to do with percentage margins in flexbox?

@rachelandrew
Copy link
Contributor

We discussed on the mailing list (pre-github) having a -gap property that works like column-gap for multi-col, and the CSS Grid grid-gap properties. It seems that this would solve this issue?

https://lists.w3.org/Archives/Public/www-style/2016Feb/0333.html

@AmeliaBR
Copy link
Contributor Author

@rachelandrew Yes, that would probably cover most use-cases.

You'd want to be able to set both a column gap and a row gap, and then spacing between flex items should never shrink below that. If any items needed additional or different margin, the regular margin properties would still apply.

@OliverJAsh
Copy link

I would also really like to see this.

@AmeliaBR I came up with an alternative to the negative margin hack, which instead uses padding inside the flex items: https://oliverjash.me/2016/12/28/gutters-for-flexible-components-with-sliced-padding

@bdsexton
Copy link

Some sort of gutter/gap property would likely result in code that is much easier to read and maintain.

@jensimmons
Copy link
Contributor

I agree flex-gap is desperately needed.

I think the lack of such a tool is part of why people struggle with Flexbox. It's common for an author to want to specify a minimum or fixed amount of space between items, and it's confusing to not be sure how we are “supposed to” accomplish such a thing. Margins and padding exist, of course, but they are old dependancies stuck in the midst of a new and better system. It feels like there is supposed to be a new better way to create and control a gap between items.

@meyerweb
Copy link
Member

I’m definitely in favor of adding flex-gap or similar to flexbox. I feel like many cases where flex gaps might be used would be at least as well served by using grid and its gaps, but by no means every case.

For reference, an example of this question being asked in the wild (May 2014): http://stackoverflow.com/questions/23433436/spacing-between-flexbox-items

@roryashfordbentley
Copy link

This would be a tremendously useful addition and a perfect solution to the problem!

In my mind there are currently 2 approaches to multiline flexbox grids:

  1. As @AmeliaBR said Grid containers with negative left margins and grid items with left padding. The issue with this method is that if you need to add padding to a grid item you have to nest an element within it and style that.

  2. Omega/last classes. The issue with this method is that for multiline grids you must write a class where the content should end on each line and you end up controlling layout within your application logic. e.g. if($i = 4){ echo 'item--last' };

flex-gap would prevent these 2 different but equally inelegant solutions in favour of something maintainable and understandable.

@dmland
Copy link

dmland commented Feb 13, 2017

As flex rightly replaces table-* rules for layout, I would appreciate a non-hacky (i.e., not requiring additional, non-semantic markup or relying on inconsistent browser behaviors), meaningfully readable way to provide gutters or gaps between flex items.

@davidcmoulton
Copy link

I support the proposal for a flex-specific margin property that overrides the regular margin in the flex-direction and has a space-around vs space-between option. This would be incredibly useful.

Is there a use case for it being available on the cross axis as well as the main axis? It feels like that would be useful but I can't think of a concrete example at this moment.

@topaxi
Copy link

topaxi commented Feb 13, 2017

Definitely saw some use-cases for this, if it's similar to grid-gap even better (less learning)!

@morganfeeney
Copy link

morganfeeney commented Feb 13, 2017

I for one would love to see a flex-gap property. It should behave in the same way as the grid-gap property.

@erikjung
Copy link

Rather than a flex- prefixed property, I would like to see a normalized property name to handle gutter definitions for columns, flex containers, and grid containers. This seems logical considering how align- and justify- properties have currently been implemented for grid.

item-gap perhaps?

example {
  display: flex;
  item-gap: 1rem;
}

example {
  display: grid;
  item-gap: 1rem;
}

example {
  columns: 4;
  item-gap: 1rem;
}

@its-me-mario
Copy link

I agree, something like flex-grid would help cut down on extra containers or hacks we may have to do.

It might be more useful if we can specify a min/max gap to have more control over the layout of the items.

@bradkemper
Copy link
Contributor

I was thinking about this recently, before I saw this thread. My thought was that there should be something like 'margin-between' that changed the computed values of margin-*. So, margin-between-x would change horizontal margins (but not the left margin of the leftmost items or the right margin of the rightmost items). margin-between-y would work similarly for vertical. Margin-between-inline and margin-between-block would be even better.

This is needed for things other than flex, such as a series of inline-block items on one or more lines. It is needed in horizontal and vertical. And it would benefit from normal margin collapsing, when some items on the line didn't have margin-between, but had some other margin.

I've needed this since before I ever started using flexbox.

@SebastianZ
Copy link
Contributor

This just came up again when talking about margin collapsing in #1324 (and that margin collapsing and gaps between flex items are two different things).

@erikjung's suggested generally applying item-gap sounds good to me. grid-gap needs to be turned into an alias for it, then, though. And there also need to be general equivalents for grid-row-gap and grid-column-gap, e.g. item-gap-block and item-gap-inline.

Sebastian

@morganfeeney
Copy link

morganfeeney commented May 11, 2017

@SebastianZ wouldn't it be more explicit to state what 'thing' the gap is for? It seems more obvious to me. i.e. flex-gap& grid-gap rather than a single item-gap for everything, e.g. what if they need to be different at some point in the future?

@SebastianZ
Copy link
Contributor

@morganfeeney Good point! Though I think it's obvious enough to what item-gap refers to. It might be even more obvious if there were a columns value for the display property to control whether the column-* properties apply. That would make item-gap always refer to the display type.

Sebastian

@SebastianZ
Copy link
Contributor

I've split out my idea about a display: columns; value into issue #1352, so it can be discussed separately.

Sebastian

@fantasai
Copy link
Collaborator

The CSSWG resolved to switch Grid to using generic row-gap and column-gap properties, and to expand these to affect Flexbox. See #1696

I'm going to close this issue as fixed; please file a new issue if there's something else to be considered here. :) Thanks everyone~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests