w3c / csswg-drafts

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

[CSS2] How do zero-width floats affect subsequent content #2312

Open mstensho opened 6 years ago

mstensho commented 6 years ago

https://www.w3.org/TR/CSS22/visuren.html#float-position doesn't seem to mention anything particular about zero-width floats. Should a zero-width margin box be considered to be a margin box at all?

<div style="width:100px;">
  <div style="float:right; width:0; height:50px;"></div>
  <div style="overflow:hidden; margin-right:-100px; height:200px; background:green;"></div>
</div>

Chrome, Edge and Firefox all show a green square here. The relevant spec wording:

"The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap the margin box of any floats in the same block formatting context [...]"

So a zero width float has no outer/margin box at all?

At the same time, all the browsers mentioned agree that zero-width floats should affect the block position of subsequent floats and blocks affected by clearance:

<div style="width:200px; background:green;">
  <div style="float:right; width:0; height:100px;"></div>
  <div style="float:left; clear:right; width:0; height:50px;"></div>
  <div style="float:left; width:0; height:100px;"></div>
  <div style="overflow:hidden; clear:both; height:200px; background:lime;"></div>
</div>

Here we get a green square above a lime square.

gsnedders commented 4 years ago

Is this essentially the same as #576, just the float-preceding case rather than the float-subsequent case?

mstensho commented 4 years ago

I don't think so. Please note that the examples that were meant to be part of the initial comment here were invisible, because I had forgotten a few backticks. Fixed now. The floats in my examples have non-zero height, which is an important detail (which was impossible to deduce from the text alone).

gsnedders commented 4 years ago

To be fair, I did look very quickly through all the open CSS2 issues and didn't think about them much. :)

Loirooriol commented 1 year ago

As I see it, it's still possible to overlap a float even if it has an area of 0. Along the same lines, #5641 said that boxes with an area of 0 can intersect the viewport.

It's worth noting that there are some browser differences depending on which dimension is 0:

<!DOCTYPE html>
<div style="margin-left:50px; width:100px;">
  <div style="float:left; width:0px; height:50px; outline:solid red"></div>
  <div style="float:right; width:0px; height:50px; outline:solid red;"></div>
  <div style="float:left; clear:both; width:25px; height:0px; outline:solid green"></div>
  <div style="float:right; clear:both; width:25px; height:0px; outline:solid green;"></div>
  <div style="float:left; width:0px; height:50px; outline:solid blue"></div>
  <div style="float:right; width:0px; height:50px; outline:solid blue;"></div>
  <div style="overflow:hidden; width:200px; margin:0 -50px; height:150px; background:cyan;"></div>
</div>
Gecko, WebKit Blink Spec
Loirooriol commented 1 year ago

Another testcase:

<!DOCTYPE html>
<div style="overflow: hidden; width:50px; border: solid; margin: 10px">
  <div style="float:left; clear:left; width:25px; height:10px; background:magenta"></div>
  <div style="float:left; width:0px; height:25px; outline:solid orange"></div>
  <div style="overflow:hidden; width:40px; height:50px; background:cyan;"></div>
</div>
<div style="overflow: hidden; width:50px; border: solid; margin: 10px">
  <div style="float:left; width:10px; height:25px; background:magenta"></div>
  <div style="float:left; clear:left; width:25px; height:0px; outline:solid orange"></div>
  <div style="overflow:hidden; width:40px; height:50px; background:cyan;"></div>
</div>
Gecko WebKit Blink Servo Servo+patch

I was actually interpreting the spec to mean "Servo+patch", and I have written a patch for Servo to implement that. But then I noticed this in https://drafts.csswg.org/css2/#floats

A line box is next to a float when there exists a vertical position that satisfies all of these four conditions: (a) at or below the top of the line box, (b) at or above the bottom of the line box, (c) below the top margin edge of the float, and (d) above the bottom margin edge of the float. Note: this means that floats with zero outer height or negative outer height do not shorten line boxes.

Effectively, both Blink and Servo+patch are then wrong here:

<!DOCTYPE html>
<div style="float: left; width: 10px; height: 10px; background: cyan"></div>
<div style="float: left; clear: left; width: 100px; outline: solid magenta"></div>
lorem ipsum
Gecko / WebKit / Servo Blink / Servo+patch

I'm not convinced it makes sense for independent formatting contexts to avoid 0px tall floats if text shouldn't avoid them.

And then it could be said that 0px wide floats shouldn't be avoided either for consistency? That said, consider

<!DOCTYPE html>
<div style="width: 50px">
  <div style="float: left; width: 25px; height: 1px; background: cyan"></div>
  <div style="float: left; height: 100px; outline: solid magenta"></div>
  loremipsum
</div>
Gecko / WebKit / Blink Servo / Servo+patch

By the above definition in CSS2, the line box is next to the magenta float, so it should shrink to avoid it, and then the text doesn't fit, so

If a shortened line box is too small to contain any content, then the line box is shifted downward (and its width recomputed) until either some content fits or there are no more floats present.

It seems to me that Gecko / WebKit / Blink aren't following this.

Summary table:

Avoids: 0px wide floats
for independent FC
0px wide floats
for text
0px tall floats
for independent FC
0px tall floats
for text
Gecko
WebKit Sometimes
Blink
Servo
Servo+patch
css-meeting-bot commented 5 months ago

The CSS Working Group just discussed [CSS2] How do zero-width floats affect subsequent content.

The full IRC log of that discussion <fantasai> s/since we are doing the layout viewport/since pretty much everything is laid out wrt layout viewport?/
<jarhar> oriol: this is an issue about floats. the issue that we have with floats is that fiwe have line boxes that come after floats they need to be shortened, same thing happens with block level elements that establish a formatting context
<jarhar> oriol: this question is what happens if the float has a width of zero or a height of zero or negative because of margin box
<jarhar> oriol: i started ?? web browsers in servo and they didnt get much agreement, i recommend looking at the last comment in this issue
<jarhar> oriol: basically the only case that is defined in the spec in css2 is just related to line boxes. it says that if a float has a height of zero or negative, then this shouldn't shorted line boxes
<jarhar> oriol: turns out that blink does not respect that, does the opposite
<jarhar> oriol: gecko obeys it. webkit obeys it
<jarhar> oriol: but yeah i would like to define what should happen in these cases. we should resolve that these cases should be consistent, whatever it should be
<jarhar> oriol: it would make sense for them to be the same
<jarhar> oriol: about the specific behavior, although its inconsistent with content-visibility because for that we observe for that it has an area of zero but it insertects the screen
<jarhar> oriol: im currently leaning maybe to what firefox is doing, which is that if a lfoat is zero pixels wide we allow overlapping that thing
<jarhar> oriol: it coudl be possible o handl the zero case - we could avoid overlapping that , but it would make it tricky with the zero case, so we could align with gecko. maybe others have thoughts
<jarhar> iank_: whats the issue with the negative case?
<jarhar> oriol: in the negative case we have the end of the float coming before the beginning. its tricker to define what it means to overlap that thing. if your element is before the beginning and after the end, maybe of the values in the middle
<jarhar> oriol: typically you dont consider it an intersection
<jarhar> iank_: i dont think thats a novel problem, we have overconstrained cases where one edge is befoe the other, and we just take the dom ? edge, i dont think the negative case is particuarly complex
<jarhar> oriol: i dont have a strong opinion here i think its simpler to go with firefox
<jarhar> oriol: what i think is that we should at least be consistent between shnortening line boxes and block elements in the formatting context
<jarhar> iank_: do all the engines respect clearance with zero area floats? how does that work?
<TabAtkins> table mics just cut out
<jarhar> oriol: for claranace its the block case, and then do you mean 0px wide or tall? what did yousay?
<jarhar> iank_: either. what happens with clearance in any of the case?
<astearns> s/claranace/clearance/
<jarhar> oriol: i didnt specifically test fo rthe clear property, but if you have a block level element aht is avoiding floats you move it downwards using clearance
<jarhar> iank_: no they dont. its a different mechanism
<jarhar> oriol: the spec says that its clearance
<jarhar> iank_: the spec says a lot of things
<jarhar> oriol: i didnt try using the clear property
<miriam> ack dbaron
<jarhar> dbaron: i just wanted to say that i agree with your principle that the lines going around floats and blocks going around floats in the inline direction should be consistent with whic floats they ? and which floats they dont
<jarhar> dbaron: you made another argument in the comment about zero width floats and zero height floats. widths of floats and heights of floats do different things
<jarhar> oriol: trying to be consistent seems like a good thing but yeah we could decide to do it different
<jarhar> iank_: specifically with there s a case where you can get ne wformatting context to overlap floats with negative margin. ill quickly draw it
<jarhar> iank_: so this is your formatting context and youve got a left float
<jarhar> iank_: and then you creat another block that is inset with amargin the same width as that float
<jarhar> iank_: if you have a new formatting context with a negative margin it will overlap that float
<jarhar> iank_: where this gets interseting is if you have this case but the float lives here instead then the nbew formatting context will avoid it
<jarhar> iank_: and so what happens when you shrink this down to zero which behavior do you get?
<jarhar> iank_: because then these two cases are the same
<jarhar> oriol: but are you suare about the empty margin it will float?
<jarhar> iank_: yes i have cuased regressions due to this
<jarhar> iank_: its the most annoying thing in the world
<jarhar> iank_: everyone does this
<jarhar> iank_: these two cases become the same when you go to zero
<jarhar> iank_: i think ill prefer this - youll just check that if youre at the edge, then youre not allowed to prorude into the negative space
<astearns> q+ to say that the most annoying thing in the world should have a spec issue added for it
<jarhar> iank_: so thats one quirk that needs to be considered
<jarhar> iank_: if you have a negative margin here, from this point the new formatting context point of view it can jsut see this. it doesn't see that float and it can just protrude into it
<jarhar> iank_: thats the hand wavy thing thats not in the spec
<jarhar> astearns: i just want to say that we should have a spec issue for this
<jarhar> iank_: theres lots of things in the css2 spec that don't exist
<miriam> ack astearns
<Zakim> astearns, you wanted to say that the most annoying thing in the world should have a spec issue added for it
<jarhar> iank_: clearance - the spec says that htings clear but i think that they just wrote that because they wanted to ship it down but didnt have a good way of saying that, but clearance works idfferently in most ?
<jarhar> iank_: i would test that as well. that is likely going to have compat like - ill be sad if we ignore floats geometry but then dont ignore clearance for example, we might ahve compat with clearance and zero area things if that makes sense
<jarhar> iank_: people will create zero width things because they dont want a thing to show up at all but want to move it down without margins. i think wikipedia
<jarhar> iank_: if you test explicit clearance that would be good in test cases
<jarhar> oriol: so its your argument tah things with explicit clearance should be consistent with the case where we have a block that is avoiding floats without explicit clearance
<jarhar> iank_: maybe? like if we are going to - i suspect that all engines might behave the same with explicit clearance with zero area floats
<jarhar> iank_: but we should check that i might be wrong
<jarhar> iank_: so if thats the case, then yeah we could still for gemotry purposes ignore floats but that might be a bit weird
<jarhar> iank_: ?? what you tried with servo and blink and it wasnt too difficult. you have two valid things that do correct things but then when it goes to zero you have to choose a behavior
<jarhar> oriol: you would prefer that we would not allow overlapping flaot that is zero pixels tall or wide?
<astearns> s/??/I think I tried/
<jarhar> iank_: i would prefer it t overlap with zero width because at least the way that wedected this internally because the new formatting context is doconsidring the area here. if my left edge is here then im allowed to retreat into it. if youre trying to block on a zero width float, ? and so you cant detect it easily,
<jarhar> iank_: if you go down the path where you respect zero width floats ?
<jarhar> iank_: thats just from an implementation complexity point of view
<jarhar> iank_: is this opportunithy the full width? then allow it top protrude left and right
<jarhar> iank_: if you have a float on the right then you want it to protrude out this side and this side
<jarhar> nicole: and thats only if the floated thing is zero width?
<jarhar> iank_: yeah but it happens today also with regular things with width that line up with this boundary
<jarhar> nicole: in believe you but when im trying that im not seeing it
<jarhar> iank_: i can quickly chalk one up
<jarhar> nicole: i couldnt get it to work in a codepen
<jarhar> nicole: it was different in safari and chrome, didnt try firefox yet
<nicole> https://codepen.io/stubbornella_old/pen/ExzwbNy
<iank_> https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=12813
<jarhar> iank_: youve gotta inset the inner block ? inset the width of the block by the float
<jarhar> iank_: the red formatting context overlaps the line ? in all browsers
<jarhar> iank_: which is great we have compat
<jarhar> iank_: yay!
<jarhar> iank_: oh the spec needs updating
<jarhar> fantasai: lets record a very clear resolution
<jarhar> miriam: whats the path forward?
<jarhar> oriol: i guess we could resolve that the two cases, line box and block should be consistent. if different browsers are doing different things they are consistent except blink in some cases
<jarhar> iank_: which case?
<jarhar> oriol: when you have 0px wide float in an independent formatting context, webkit sometimes avoids it and sometimes doesnt. for text i coudlnt get it to avoid the float
<jarhar> iank_: so webkits inconsistent but link is ok?
<astearns> s/link/Blink/
<jarhar> oriol: webkit is a bit self inconsistent i woudl say. in the case of zero pixels wide floats browsers are inconsistent
<jarhar> oriol: for zero pixels tall floats, blink is different from webkit and gecko since its avoids overlapping them against the spec
<jarhar> iank_: test cases for explicit clearance would help
<jarhar> iank_: i think your august 9 2023 comment is the triggerint that behavior tha ti just described
<jarhar> iank_: except that blink is avoiding the horizontal lines
<jarhar> oriol: i think that your case here is different because the float isnt zero or relative, the margin belongs to the other element
<jarhar> iank_: i think your august 9 comment is the same because all browsers today you iknow like if theres a zero width float here then all browwers alllow a new formatting context to overlap and intrude it because its on that edge
<jarhar> iank_: is the start of the opportunity the same as the available space? then allow it to go over otherwise not
<jarhar> iank_: thats i think like - i suspec tht at all browsers are doing this case by default
<jarhar> iank_: the only thtnig thats different is that blink when theres a float like this will try to avoid that
<miriam> q?
<jarhar> iank_: but i suspect that if you hadd clearance then browsers all might clear that for example. i could try ....
<jarhar> oriol: i guess you are saying that we should allow oferlapping flaots that are zero px wiwde except with clearance, all browsers agree except webit sometimes
<jarhar> iank_: what would be the resolution?
<jarhar> oriol: floats that are zero px wide are negative should not shorten line boxes or shift blocks that are independent
<jarhar> iank_: that might not be true though
<jarhar> iank_: i think thats only true in engines if they are on the edge of the available space. its possible to create a zero width float that isnt on the edge of the available space, you might get different results in different engines there
<jarhar> oriol: in the case i was trying it was not the edge and it was only webkit that was inconsistent
<jarhar> oriol: if yiou look at the last comment in the issue
<jarhar> oriol: for text all browsers agree
<jarhar> oriol: iank_: i think they are - they all avoid it if its a new formatting context
<jarhar> iank_: if its a block formattig context, then gecko and blink are still not avoid it, and webkit sometimes does and sometimes not
<jarhar> iank_/oriol/s
<iank_> https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=12815
<jarhar> oriol: it should be the first table of images in the last comment - in gecko and blink they overlap
<jarhar> iank_: the test case i just pasted everyones avoiding it right?
<jarhar> oriol: in what browser?
<jarhar> iank_: all browsers
<emilio> Doesn't look like it?
<jarhar> iank_: or maybe everyones avoiding the ?
<jarhar> oriol: not sure if i should put my laptop in the ? or something becuase im not sure we are talking about the same thing
<dholbert> s/the ?/the cyan/
<dholbert> (that 'the ?' is for iank's last scribed comment^)
<jarhar> iank_: i think theres at least two passes of test cases that lead to ? layout
<jarhar> iank_: one is explicit clearance with all interactions
<jarhar> flackr: im presenting firefox safari and chrome
<jarhar> oriol: so this is the text case which i guess i was using a smaller container because it seems like its ? on the side
<jarhar> iank_: i took the line test case and then just added anew formatting context
<jarhar> iank_: the line and the formatting context behave differently across browsers
<jarhar> iank_: i think that there maybe more ? that we wil need to consider
<jarhar> oriol: so what i was referring to beforehand in this case is that we have this orange float that is zero px wide and then the blue box is overlapping it
<jarhar> oriol: in this case i only saw a different behavior in webkit
<jarhar> oriol: for the text case...
<jarhar> oriol: the text is overlapping the magenta float
<jarhar> iank_: there might be a sublte difference between those two cases
<jarhar> iank_: i think test cases that we need - feel more comfrotable making a decision
<jarhar> iank_: new formatting context ?
<jarhar> nicole: and which were the various combinations?
<jarhar> iank_: basically if youve got a zero width fl-oat and then youre clearing htat zero width float what hpapens?
<jarhar> iank_: cause that will have different interactions. zero widht and height float
<jarhar> iank_: and then - we can deviate there but i suspect that explicit clearance and zero width and zero height wecan't change
<jarhar> iank_: and then what do we do based about clearance based on that
<jarhar> oriol: i guess, what im getting from you is that in this case we want to be able to overlap zero px wide floats but if theres explicit clearance we shoudln't
<jarhar> iank_: yes
<jarhar> iank_: css2 lies a lot. theyre 2 different mechanisms
<jarhar> iank_: the clearance is the way that - they walk through the entire list of floats and then pick and offset and thats different than this gemoetry calculation
<jarhar> oriol: i think ? to different things, so we could resolve on that
<jarhar> iank_: but then what are the - whats the different thing
<jarhar> oriol: if you have explicit clearance you could avoid zero px wide, you would be allowed to overlap them
<jarhar> iank_: overlapping only happens interoperably when ? is on the edge of the available space
<jarhar> iank_: it might be different ifyouave got a szero width float and a container with negative margin
<astearns> s/? to /explicit clearance and no explicit clearance are two /
<jarhar> iank_: now that float is sitting in the middle of the space and now that calculation doesn't apploy anymore
<jarhar> oriol: i didn't see a difference in webkit but in the other browsers firefox and blink they seem to allow overlapping zeropx wide floats in all the cases i tested without explicit clearance
<jarhar> iank_: maybe? id like to see the test cases
<jarhar> miriam: if we take this back to the issue can we document test cases?
<jarhar> iank_: yeah
<jarhar> oriol: im fine with going back to the issue, resolution about line boxes and independent blocks consistent would make sense?
<jarhar> iank_: i dont think theyre consistent
<jarhar> iank_: ive got a test case here where theyre doing different things in all browsers and theyre rendering the same
<jarhar> oriol: ok you can pause this issue
<jarhar> miriam: resolve to close no change?
<jarhar> oriol: not closing no change but deferring until we can continue the discussion in the issue? if we lead to some agreement then we can move on
<jarhar> iank_: yeah this area its common cases thats constrained by that
<jarhar> iank_: im pretty sure i know most of them
<jarhar> oriol: there are cases where browsers are doing different things so i guess compat is not that improtant?
<jarhar> iank_: sure but i dont think you can say that ? where there are cases that are different
<jarhar> miriam: so if we take this back to the issue we need to document compat constraints and then what other test cases are needed
<astearns> s/?/they are the same/
<jarhar> iank_: explicit clearance test cases of zero area then zero width zero height being on the availabl espace boundary and not being on the availba espace boundary since theyll be slightly different behaivors there
<jarhar> iank_: and then i think there are differences between line box and new formatting context
<jarhar> miriam: sounds like were taking it back to the issue?
<jarhar> iank_: yep