w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.44k stars 657 forks source link

[css-box-4] Should margin-trim have a 'floats' value? #3256

Open fantasai opened 5 years ago

fantasai commented 5 years ago

Currently the margin-trim property allows trimming only in-flow block-axis margins, or that plus float margins (in either axis) that touch the container’s content edges. Should it be possible to trim the float margins while not trimming the in-flow block-axis margins? Do we have any use cases for such?

frivoal commented 5 years ago

I think there are use cases for having different float-to-float margins than float-to-inflow, and this probably covers quite a few of them. @murakamishinyu, I know you are quite familiar with this topic thanks you your work on antenna house. Can you share a bit more about the use cases for something like https://www.antennahouse.com/product/ahf60/docs/ahf-float.html#axf.float-float-margin-y, and whether having what @fantasai is proposing would solve that need as well?

mirisuzanne commented 2 years ago

agenda+ to resolve that floats and inflow content do not need distinct values. We can work out the details of how margin-trim impacts floats separately.

css-meeting-bot commented 2 years ago

The CSS Working Group just discussed margin-trim vs floats.

The full IRC log of that discussion <fantasai> Topic: margin-trim vs floats
<fantasai> github: https://github.com/w3c/csswg-drafts/issues/3256
<fantasai> miriam: Question is should floats be able to do margin-trim
<fantasai> miriam: It seemed to us that floats that are at the edge of the box that have a box that would impact the box should be considered the same as any other margin against the edge of the box
<fantasai> miriam: there might need to be special definitions to define precisely when floats are impacted
<fantasai> miriam: but don't need ability to control separately
<fantasai> florian: I think we need some amount of independence
<fantasai> florian: Antenna House Formatter has proprietary controls
<fantasai> florian: for e.g. controlling the margin between two floats differently from margin between float and edge of the page
<fantasai> florian: when being particular about layout of complex documents with floats
<fantasai> florian: (not floats as substitute for grid, but actual floats)
<fantasai> florian: then you do want that kind of control
<fantasai> florian: float to float margins and foat to text margins are often different
<fantasai> florian: Some amount of float margin trimming explicitly is needed
<fantasai> miriam: I was thinking if we think of the trim as coming from the box edge, we could maintain the exclusion box of the float with the margin so if it's pushing anything else that margin is still there, but it's trimmed as far as the box is concerned
<fantasai> miriam: that seems to make sense to me
<fantasai> miriam: and that wouldn't need manual control
<fantasai> iank_: Should this just apply to in-flow elements?
<fantasai> iank_: That seems to be the main use case here
<fantasai> iank_: ...
<fantasai> florian: What would apply then? If I do want to trim the margins of a float
<fantasai> florian: for the purpose of not pushing other floats apart, it would work, but if not, then we'd need another property
<fantasai> iank_: It's a bit hard for me to reason when we don't have particularly strong use cases one way or another
<fantasai> iank_: use case described seems to be for in-flow children
<fantasai> iank_: consider the out of flow position case, not intending to act on that
<fantasai> iank_: floats seem in-between to me
<florian> q-
<fantasai> miriam: If the section that the float is in is wrapping the float
<fantasai> miriam: e.g. is a block formatting context root
<fantasai> miriam: then I would expect the float the behave as in-flow wrt that box
<fantasai> miriam: the margins on the float would be pushing the size of the box which is exactly what we're trying to avoid here
<florian> fantasai: it makes sense to apply the trim to the float
<florian> fantasai: you want to have precise control over what is the visible edge
<florian> fantasai: if you consider a section with some text and a float…
<Rossen_> fantasai: I think that it makes sense to apply trim to floats. You want to have a solid control of the vis edge of the new box. Considersing a section with content and float that has margin, done so content doesn't clash. If on top however you want to trim it so that it doesn't get displaced compared to rest of content.
<Rossen_> florian: You need to trim all such margins. It makes sense to trim all of margins as well as inline.
<fantasai> iank_: for that specific case I don't think trimming the float is warranted
<Rossen_> q?
<Rossen_> ack fantasai
<fantasai> iank_: e.g. suppose you put 5px margin around the float, then want that to stay all around
<Rossen_> fantasai: not sure you want that margin necessary. Mostly vis content is what you want to align to. If you want to get the edge of flow and text to align so you can put a margin around you can. That way if float comes later in flow it has it but not at the top.
<Rossen_> fantasai: you can also skip using it. Use selectors for these first elements to remove margins etc.
<fantasai> jensimmons: I think it could be confusing if margin-trim works sometimes and not other times
<fantasai> jensimmons: "it counts if it's an image in a float, but not if ..." It's a lot to keep in your head
<emeyer> +1 to @jensimmons point
<fantasai> Rossen_: I'm closer to iank_'s opinion here... generally speaking, float layout is not inline layout
<fantasai> Rossen_: They take part during inline layout, however in all implementations floats are kept separately based on whether left or right float alignment
<fantasai> Rossen_: and float layout is wrt all floats themselves
<fantasai> Rossen_: We go to great extent in float algorithm in CSS2 to avoid and minimize the dependency an inline content and floats as much as possible
<fantasai> Rossen_: Position of float wrt content ...
<fantasai> Rossen_: seems odd
<fantasai> Rossen_: because even a float that comes in the beginning of the content, that more or less guarantees part of first line
<fantasai> Rossen_: That float can be left or right
<fantasai> Rossen_: and really left margin doesn't make sense for right float and vice versa
<fantasai> Rossen_: seems very specific to make that an automatic behavior by layout algorithm
<florian> q+
<iank_> e.g. https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=9645
<Rossen_> fantasai: This is about trimming margins on content of all other layouts - block, flex items, grid items. etc.
<fantasai> fantasai: Should also trim floats
<fantasai> fantasai: Also not sure why concerned about inline layout, this isn't inline layout
<fantasai> Rossen_: Floats are out of flow
<miriam> q+
<fantasai> fantasai: Yes, they're taking out of their original position, but they're in-flow in the sense that they affect the content around them, unlike abspos
<fantasai> Rossen_: Floats create geometry for laying out content around it
<fantasai> Rossen_: Their placement takes place ahead of inline content around them
<Rossen_> q?
<fantasai> florian: You talked about inline margins
<fantasai> florian: Discussion is about block-start margin of the float being trimmed
<Rossen_> ack florian
<fantasai> florian: If you want to put a 1em margin around your floats to avoid the text of your float crashing against the surrounding text
<fantasai> florian: it doesn't necessarily mean you want your float to be 1em from the start of the block
<fantasai> florian: there's nothing to crash into above it
<fantasai> florian: it does depend on the document, but there are cases here
<fantasai> florian: Elika gave explanations already, did you want scans of books or something?
<fantasai> miriam: I would follow up with with what Jen said
<fantasai> miriam: There are interesting discussions from impl point of view
<fantasai> miriam: But from author point of view, not making sense
<fantasai> miriam: If I have a box and I want to trim the margins at the edge of the box
<fantasai> miriam: I would expect it to trim all the margins at the edge of the box
<fantasai> miriam: I wouldn't expect some difference because one is floated or not or whatever
<fantasai> miriam: ...
<fantasai> miriam: Also margin-trim is only applied at the box edges. It doesn't affect how content is flowing together
<fantasai> miriam: It determines what happens when I have a box and a float inside it or a paragraph or a header inside of it
<fantasai> miriam: I trim the margins when they are at the box edge, and those are the only margins I'm trimming
<fantasai> florian: I support miriam's position. If you simplify the value space and exclude one of them, you can still have individual control by using selectors
<fantasai> iank_: Apply to out of flow elements?
<fantasai> miriam: I would expect to things that impact the size of the box
<fantasai> florian: wrt abspos, whatever
<fantasai> Rossen_: For purposes of computing scrollable area, they do affect layout as an inline margin would
<fantasai> Rossen_: behavior that we just described with abspos element that has large margin bottom, would still create a large scroller with visibly nothing below
<Rossen_> ack miriam
<fantasai> iank_: Other thing I wanted to ask...
<fantasai> iank_: Example where using margin-trim is desirable but also margin-trim is desirable
<fantasai> iank_: How would I get that back, if it does apply to floats?
<iank_> https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=9645
<fantasai> miriam: I think you would either use padding, or you would not use margin-trim in that case
<fantasai> miriam: if you want different impact on different elements, you would do it manually instead of using margin-trim
<fantasai> iank_: other question is, now that we have nesting, it's very easy to implement effectively margin-trim now
<fantasai> iank_: does the use case for margin-trim become less due to this?
<florian> fantasai: margin trim is going to effect all elements very simply, but with selectors you'd need to drill down to descendents
<florian> fantasai: margin collapsing makes that complicated
<florian> fantasai: that's why we don't do it on table cells with selectors, and why it'd be good here too
<fantasai> iank_: If I want margin on the float and not the in-flow, then what do I do?
<Rossen_> q?
<fantasai> fantasai: Then don't use margin-trim
<Rossen_> ack fantasai
<florian> fantasai: isn't that the same question as with multiple items at the top row of a grid? at that point you can't use margin trim
<fantasai> iank_: It is common to want margin on the float and not the rest of the content
<fantasai> fantasai: I think the reason you often see margin on floats and not in-flow content that's supposed to align is because in-flow content isn't visibly flush
<fantasai> fantasai: but we're working to make that possible, so you won't need to add margin to the float to make it look like it's visually aligned with the in-flow content
<Rossen_> q?
<fantasai> iank_: I don't think that's entirely true...
<fantasai> iank_: but maybe we should discuss in the issue
<fantasai> miriam: I don't entirely understand your example, Ian.
<fantasai> iank_: I would expect padding on the content
<fantasai> s/iank_/miriam/
<fantasai> Rossen_: I think this is a great discussion and I certainly want to see progress made here
<fantasai> Rossen_: the use cases that I just understood make sense
<iank_> https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=9646 RHS still seems better?
<fantasai> Rossen_: But I also think we need to do some more careful thinking
<iank_> s/RHS/LHS
<fantasai> Rossen_: Maybe talk through use cases and narrow down what's possible and what's not, and try to figure out expectations
<fantasai> Rossen_: so maybe take up again later
mirisuzanne commented 2 years ago

I understand that there are use-cases where an author might want to exclude some elements/margins from the impact of margin-trim. I do not think it's true that those use-cases align cleanly with a distinction between flow-types (in-flow, float, or abspos). In all cases, I would expect the default of margin-trim to trim all box-edge margins. From there, it seems to me like the more important question is: do we need a way for some elements to override that container-imposed trimming.

On the call, @bfgeek linked this example:

https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=9645

This "image-with-whitespace next to text" is a common pattern, although neither box in the demo reflects a clearly desirable outcome.

In both cases, this same basic pattern is now achieved with a variety layout methods -- float, flexbox, and grid -- depending on subtle details of sizing and alignment and content. From an author perspective, there is not a consistent relationship between which layout technique is used, and how the author would want box-edge margins handled.

In the case where one child element does need to keep margins intact, there are several options:

That last option would make sense to me. But attempting to auto-opt-out an entire category of elements (based on their relationship to flow) feels like an unreliable heuristic, and doesn't match any consistent author patterns that I've seen.

bfgeek commented 2 years ago

There are a few more complexities here for this feature:

Determining the "end" of content is complicated for floats, and atomic-inlines (anything on a line) and makes this difficult to implement. E.g. consider: https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=9695

Floats can end up in quasi states where their margin might be trimmed, however they aren't at the "end" of the content. E.g. https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=9693 getting this case correct for block layout falls into the "very difficult" category, as you may have to walk arbitrarily back in the content.

Its also quite common for atomic-inlines to have margin to adjust their position on a line, e.g. <img style="margin-bottom: 1em";> to position something as a sup of similar (this is also super common on first-letter pseudo).

This feature works well for inflow-content. Grid/flex have very simple models here and is relatively straight forward. Block-flow is a very complicated model due to how margin-collapsing, floats all interact. Block-flow layout is really 3 different layout modes combined into one.

Block-flow layout is the only thing here where we are going more than one level deep. The way that margins work for inflow-block-level content would make it very straight forward to implement for inflow block-level content. This is similar to how the prefixed -webkit-margin-collapse class of properties worked. Atomic-inlines and in particular floats make this very difficult to reason about and implement.

But attempting to auto-opt-out an entire category of elements (based on their relationship to flow) feels like an unreliable heuristic, and doesn't match any consistent author patterns that I've seen.

We've already done this for the other category of out-of-flow elements?

mitar commented 1 year ago

Could this help remove a margin on the float? I have a figure with float: right; margin-left: 10px; so that it has some space to the text on the left. But if the figure is too wide (or window too narrow) then only the figure is shown, and I would love that left margin is then trimmed.

fantasai commented 6 months ago

Retargetting for Level 5; note that the effect on floats has been completely removed, and would need to be re-introduced: see https://github.com/w3c/csswg-drafts/issues/8547.