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-box] Explicit control over margin collapsing #1324

Closed
keithjgrant opened this Issue May 4, 2017 · 9 comments

Comments

@keithjgrant
Contributor

keithjgrant commented May 4, 2017

https://www.w3.org/TR/CSS22/box.html#collapsing-margins

Margins do not collapse on grid items and flex items. I find this confusing and inconsistent. I can’t help but think these were specced this way because so many people have been frustrated by unexpected margin collapsing. Instead, the result is there are more exceptions to the rule, making the entire concept even more difficult to learn.

For example, see this question on Stack Overflow; this person expects the margins of their flex items to collapse. And rightfully so, IMO.

I think it would be great if we had a way to explicitly set (or disallow) margin collapsing for an element, perhaps similar to border collapsing on tables. Proposed syntax examples:

.foo {
    margin-collapse: collapse;
}

.bar {
  margin-collapse: separate;
}

It might make sense if top and bottom margins could be individually controlled. margin-collapse: collapse separate could be shorthand for margin-top-collapse: collapse; margin-bottom-collapse: separate.

@SebastianZ

This comment has been minimized.

Show comment
Hide comment
@SebastianZ

SebastianZ May 5, 2017

Contributor

As there are cases where margins do not collapse, this also needs an auto value as default.

There are also use cases, in which you want to control the margin collapsing between container and inner elements separatedly from the collapsing between elements. Therefore, there should be a second keyword allowing to define this.

I.e. the syntax would then be something like this:

[ auto | collapse | separate ] [ auto | collapse | separate ]?

where the first keyword controls the collapsing between elements and the second keyword the collapsing between inner and outer elements.

Example: https://jsfiddle.net/SebastianZ/k7ndbrt0/.

Sebastian

Contributor

SebastianZ commented May 5, 2017

As there are cases where margins do not collapse, this also needs an auto value as default.

There are also use cases, in which you want to control the margin collapsing between container and inner elements separatedly from the collapsing between elements. Therefore, there should be a second keyword allowing to define this.

I.e. the syntax would then be something like this:

[ auto | collapse | separate ] [ auto | collapse | separate ]?

where the first keyword controls the collapsing between elements and the second keyword the collapsing between inner and outer elements.

Example: https://jsfiddle.net/SebastianZ/k7ndbrt0/.

Sebastian

@Loirooriol

This comment has been minimized.

Show comment
Hide comment
@Loirooriol

Loirooriol May 5, 2017

Collaborator

How exactly do you want to collapse margins in a flex formatting context? Between flex items in the main axis? Between flex items in the cross axis? Between flex items in both axis? Between flex items and the flex container?

The Stack Overflow question you linked seems about getting rid of margins between flex items and the flex container, which is a thing different than collapsing margins, and is tracked in #592.

Collaborator

Loirooriol commented May 5, 2017

How exactly do you want to collapse margins in a flex formatting context? Between flex items in the main axis? Between flex items in the cross axis? Between flex items in both axis? Between flex items and the flex container?

The Stack Overflow question you linked seems about getting rid of margins between flex items and the flex container, which is a thing different than collapsing margins, and is tracked in #592.

@keithjgrant

This comment has been minimized.

Show comment
Hide comment
@keithjgrant

keithjgrant May 5, 2017

Contributor

Looking at it now, I think I originally mis-read the Stack Overflow post. I thought they were talking more about the space between each flex row (on the cross axis), which is primarily what I had in mind. Though it would be on the main axis if the flex direction is “column” or “column reverse”. I don’t know if there’s a use case for horizontal margin collapsing.

I like Sebastian’s idea about controlling collapsing between siblings separately than collapsing outside a container.

Contributor

keithjgrant commented May 5, 2017

Looking at it now, I think I originally mis-read the Stack Overflow post. I thought they were talking more about the space between each flex row (on the cross axis), which is primarily what I had in mind. Though it would be on the main axis if the flex direction is “column” or “column reverse”. I don’t know if there’s a use case for horizontal margin collapsing.

I like Sebastian’s idea about controlling collapsing between siblings separately than collapsing outside a container.

@SelenIT

This comment has been minimized.

Show comment
Hide comment
@SelenIT

SelenIT May 11, 2017

Collaborator

I generally don't like the idea of introducing margin collapsing concept into contexts other than block layout and prefer the idea of the *-gap property for everything (maybe even for paragraphs, instead of collapsed margins, in order to distribute paragraphs regularly, while margins can still be used to tweak this distribution).

Margin collapsing already seems one of the weirdest CSS features for beginners, and edge cases like 'collapsing-through' zero-height blocks, overlapping of collapsed margin and the clearance created after the cleared float etc. can confuse even more experienced authors. Also, introducing margin collapsing to 2D layout contexts like Grid would cause to take many elements into account to calculate each margin, wouldn't it potentially harm the performance? And how are the collapsed margins supposed to interact with existing grid gutters? Should they collapse through them? I am afraid that introducing the concept of margin collapsing into Grid (and probably Flexbox, too) would bring too many issues like that.

Collaborator

SelenIT commented May 11, 2017

I generally don't like the idea of introducing margin collapsing concept into contexts other than block layout and prefer the idea of the *-gap property for everything (maybe even for paragraphs, instead of collapsed margins, in order to distribute paragraphs regularly, while margins can still be used to tweak this distribution).

Margin collapsing already seems one of the weirdest CSS features for beginners, and edge cases like 'collapsing-through' zero-height blocks, overlapping of collapsed margin and the clearance created after the cleared float etc. can confuse even more experienced authors. Also, introducing margin collapsing to 2D layout contexts like Grid would cause to take many elements into account to calculate each margin, wouldn't it potentially harm the performance? And how are the collapsed margins supposed to interact with existing grid gutters? Should they collapse through them? I am afraid that introducing the concept of margin collapsing into Grid (and probably Flexbox, too) would bring too many issues like that.

@SebastianZ

This comment has been minimized.

Show comment
Hide comment
@SebastianZ

SebastianZ May 11, 2017

Contributor

Margin collapsing already seems one of the weirdest CSS features for beginners, and edge cases like 'collapsing-through' zero-height blocks, overlapping of collapsed margin and the clearance created after the cleared float etc. can confuse even more experienced authors.

Yes, which speaks for the introduction of a property to control — i.e. disable — margin collapsing, but see below.

Also, introducing margin collapsing to 2D layout contexts like Grid …

Grid and Flexbox explicitly define that their containers and items do not allow margin collapsing.

Note the comment about margin collapsing related to the grid container in the Grid specification:

floats do not intrude into the grid container, and the grid container’s margins do not collapse with the margins of its contents.

And for grid items:

As adjacent grid items are independently contained within the containing block formed by their grid areas, the margins of adjacent grid items do not collapse.

The Flexbox specification has similar notes for flex containers and flex items.

I generally don't like the idea of introducing margin collapsing concept into contexts other than block layout and prefer the idea of the *-gap property for everything (maybe even for paragraphs, instead of collapsed margins, in order to distribute paragraphs regularly, while margins can still be used to tweak this distribution).

I agree that margin collapsing should be restricted to block layout and that Flexbox should rather get a flex-gap property controlling the distances between the flex items, which would serve the given use case and also align it more with the Grid specification. And this approach is already discussed in #592.

Sebastian

Contributor

SebastianZ commented May 11, 2017

Margin collapsing already seems one of the weirdest CSS features for beginners, and edge cases like 'collapsing-through' zero-height blocks, overlapping of collapsed margin and the clearance created after the cleared float etc. can confuse even more experienced authors.

Yes, which speaks for the introduction of a property to control — i.e. disable — margin collapsing, but see below.

Also, introducing margin collapsing to 2D layout contexts like Grid …

Grid and Flexbox explicitly define that their containers and items do not allow margin collapsing.

Note the comment about margin collapsing related to the grid container in the Grid specification:

floats do not intrude into the grid container, and the grid container’s margins do not collapse with the margins of its contents.

And for grid items:

As adjacent grid items are independently contained within the containing block formed by their grid areas, the margins of adjacent grid items do not collapse.

The Flexbox specification has similar notes for flex containers and flex items.

I generally don't like the idea of introducing margin collapsing concept into contexts other than block layout and prefer the idea of the *-gap property for everything (maybe even for paragraphs, instead of collapsed margins, in order to distribute paragraphs regularly, while margins can still be used to tweak this distribution).

I agree that margin collapsing should be restricted to block layout and that Flexbox should rather get a flex-gap property controlling the distances between the flex items, which would serve the given use case and also align it more with the Grid specification. And this approach is already discussed in #592.

Sebastian

@normanzb

This comment has been minimized.

Show comment
Hide comment
@normanzb

normanzb Jun 26, 2017

It is a shame to not having margin collapsing in flex box.
I find it confused at the beginning but once I learnt how to use, I found that it is such a useful tool and I use it everywhere everyday in all my projects.

by using collapsing you don't have to do the math to sum up or deduct the margin of inner elements, you don't have to use first-child last-child to cancel out the margins at both ends. and when different elements with different weight of margin sit together, they naturally reuse the maximum margin which is a brilliant idea for web page that requires flexibility to heavily combines all different kinds of element.

Confusing at the beginning doesn't mean it is not a good tool.
Take bicycle as analogy, every bicycle learner find it confusing to make bike turns, when you turn the handlebar left, the bike actually leaning to the right! But once you mastered it, it gives you great fun and it is great agile tool to take you around town.

I really hope there will be an option for us to enable it either main or cross axis but default to not collapsing, making the advanced skill to skilful devs and hide it from beginner, both wins.

If #592 and flex-gap achieve the same effect, that allows me to avoid the negative margin hacks, avoid unnecessary math and cancelling the margin, and most importantly, automatically use the maximum gap between items then I think we are talking about the same thing and I don't mind if it is called flex-gap or flex-gap-collapsing whatsoever.

normanzb commented Jun 26, 2017

It is a shame to not having margin collapsing in flex box.
I find it confused at the beginning but once I learnt how to use, I found that it is such a useful tool and I use it everywhere everyday in all my projects.

by using collapsing you don't have to do the math to sum up or deduct the margin of inner elements, you don't have to use first-child last-child to cancel out the margins at both ends. and when different elements with different weight of margin sit together, they naturally reuse the maximum margin which is a brilliant idea for web page that requires flexibility to heavily combines all different kinds of element.

Confusing at the beginning doesn't mean it is not a good tool.
Take bicycle as analogy, every bicycle learner find it confusing to make bike turns, when you turn the handlebar left, the bike actually leaning to the right! But once you mastered it, it gives you great fun and it is great agile tool to take you around town.

I really hope there will be an option for us to enable it either main or cross axis but default to not collapsing, making the advanced skill to skilful devs and hide it from beginner, both wins.

If #592 and flex-gap achieve the same effect, that allows me to avoid the negative margin hacks, avoid unnecessary math and cancelling the margin, and most importantly, automatically use the maximum gap between items then I think we are talking about the same thing and I don't mind if it is called flex-gap or flex-gap-collapsing whatsoever.

@tabatkins

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Jun 26, 2017

Member

I agree that margin collapsing should be restricted to block layout and that Flexbox should rather get a flex-gap property controlling the distances between the flex items, which would serve the given use case and also align it more with the Grid specification. And this approach is already discussed in #592.

Yup (tho it needs two - main-gap and cross-gap - just like grid has row-gap and column-gap).

In general, we do not want margin-collapsing in Grid or Flex. Collapsing in Grid simply can't happen (a grid item can border multiple elements on a given side with different margins), and in Flex it's not actually desired (you instead want to "collapse away" the margins touching the flex container, which is a different behavior). Gaps do what we want in Grid, and need to be added to Flexbox.

Closing in favor of #592

Member

tabatkins commented Jun 26, 2017

I agree that margin collapsing should be restricted to block layout and that Flexbox should rather get a flex-gap property controlling the distances between the flex items, which would serve the given use case and also align it more with the Grid specification. And this approach is already discussed in #592.

Yup (tho it needs two - main-gap and cross-gap - just like grid has row-gap and column-gap).

In general, we do not want margin-collapsing in Grid or Flex. Collapsing in Grid simply can't happen (a grid item can border multiple elements on a given side with different margins), and in Flex it's not actually desired (you instead want to "collapse away" the margins touching the flex container, which is a different behavior). Gaps do what we want in Grid, and need to be added to Flexbox.

Closing in favor of #592

@fantasai

This comment has been minimized.

Show comment
Hide comment
@fantasai

fantasai Oct 18, 2017

Contributor

The grid gap functionality has been expanded to Flexbox in #1696, which should handle most of the use cases we've encountered. Please let us know if this is an acceptable resolution to this issue or if there is something further that needs to be done.

(Wrt Grid, specifically, btw, I have no idea how one would "collapse" margins there since grid items are confined to their respective grid areas...)

Contributor

fantasai commented Oct 18, 2017

The grid gap functionality has been expanded to Flexbox in #1696, which should handle most of the use cases we've encountered. Please let us know if this is an acceptable resolution to this issue or if there is something further that needs to be done.

(Wrt Grid, specifically, btw, I have no idea how one would "collapse" margins there since grid items are confined to their respective grid areas...)

@keithjgrant

This comment has been minimized.

Show comment
Hide comment
@keithjgrant

keithjgrant Oct 18, 2017

Contributor

👍🏻 I think gaps provide the functionality developers really need here for defining space between elements. Flex and grid also prevent margins of their items from collapsing outside the flex/grid container, too, which was another concern. I’m happy with this.

Contributor

keithjgrant commented Oct 18, 2017

👍🏻 I think gaps provide the functionality developers really need here for defining space between elements. Flex and grid also prevent margins of their items from collapsing outside the flex/grid container, too, which was another concern. I’m happy with this.

@fantasai fantasai added this to the Published css-flexbox-1 2017-10-19 milestone Mar 29, 2018

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