w3c / csswg-drafts

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

[css-overflow] [css2?] Baseline of an inline-block with overflow:clip. #6212

Open emilio opened 3 years ago

emilio commented 3 years ago

Blink and Gecko differ on what baseline should an element with display: inline-block and overflow: clip.

Example (live):

<!doctype html>

Clip:
<br>
<div style="border:1px solid red; display:inline-block">
  <div style="overflow:clip; width:10px; height:10px; background:blue; display:inline-block;">Hallo Welt</div>
</div>

<br>
Visible:
<br>
<div style="border:1px solid red; display:inline-block">
  <div style="width:10px; height:10px; background:blue; display:inline-block;">Hallo Welt</div>
</div>
<br>
Hidden:
<br>
<div style="border:1px solid red; display:inline-block">
  <div style="overflow:hidden; width:10px; height:10px; background:blue; display:inline-block;">Hallo Welt</div>
</div>

@bfgeek pointed out that CSS2.1 has:

The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible', in which case the baseline is the bottom margin edge.

However CSS2 was written before overflow: clip was a thing. I intuitively expect overflow: clip to behave like overflow: visible here (because it's not an scrollable box), but I could see the argument the other way around. Thoughts?

emilio commented 3 years ago

An interesting question, if we decide that clip and visible should behave differently, is what happens if only one of the axes is clipped.

bfgeek commented 3 years ago

I somewhat expected blink's behaviour (and have a mild preference for it) as I sort of view clip as a better hidden, but either way is fine.

Loirooriol commented 3 years ago

what happens if only one of the axes is clipped

Seems a good argument for treating clip like visible.

tabatkins commented 3 years ago

Yeah, since only one axis can be clipped, this really should continue to be treated like visible, not like hidden. Diverging from that principle will only cause us confusion in the future, I think.

And yes, older text saying "overflow other than visible" just needs to be fixed up, it should always mean "scroll container" in modern parlance.

MatsPalmgren commented 3 years ago

I agree, overflow-inline : clip should not affect the baseline, so that disqualifies the "behave as hidden" option as described above IMO. However, I don't see a reason why we can't synthesize a baseline for overflow-block : clip (which would behave roughly as hidden in that axis).

It's also worth considering what happens when the baseline is well within the size, e.g. emilio's test with height:100px instead. I'd slightly prefer the visible behavior over a synthesized baseline in this case, but I don't feel strongly about it.

There's also a third option: "clamp the baseline", which would calculate the baseline normally (as for visible) but clamp it to the clip area. That would make emilio's test behave (roughly*) as hidden but the height:100px case would still behave as visible. (I dunno how complicated that would be to implement though, so I'm not sure if it's worth it.)

(*) the clip area is typically the padding box, whereas the hidden baseline is calculated from the border box

So I see three viable options:

  1. the baseline is calculated the same as for visible (what Firefox currently implements)
  2. always synthesize a baseline for overflow-block : clip
  3. as 1 but clamp it to the clip area
bernhardf-ro commented 3 years ago

Thanks @MatsPalmgren for the list of options. I'll reference it for brevity. In PDFreactor we have implemented a variation of 3: For clip we clamp the visible baseline to the synthesized baseline. So you always have either 1 or 2 (visible or hidden behavior) in the end. We considered the clip area as clamp value, but concluded that the hidden behavior would be more expected than adding a new area affecting alignment. Maybe you can add this option for discussion as 4 or 3b.

css-meeting-bot commented 3 years ago

The CSS Working Group just discussed css-overflow] [css2?] Baseline of an inline-block with overflow:clip., and agreed to the following:

The full IRC log of that discussion <dael> Topic: css-overflow] [css2?] Baseline of an inline-block with overflow:clip.
<dael> Github: https://github.com/w3c/csswg-drafts/issues/6212
<dael> fantasai: 4 proposal in the issue afaict. 1) same as visiable even if baseline of clipped text
<dael> fantasai: 2. treat like overflow hidden and synth baseline regardless of what's inside
<dael> fantasai: 3. use whatever visible text is there. If clipped or below clipping point stop at clipping point
<dael> fantasai: 4 is same but instead of clamp to clipping area we clamp to border area b/c that's how hidden behaves
<dael> iank_: I think it's margin edge
<dael> iank_: Unique thing here is inline box us by default last baseline. Not like first for flex/grid. overflow:hidden if you didn't do end margin you'd get a funny box
<dael> iank_: Question is which. We treat like overflow hidden
<dael> iank_: [missed]
<fantasai> s/hidden/hidden, Firefox treats as visible/
<dael> iank_: Basically, chrome went way of overflow:hidden for that reason and adhereing to css 3. FF went for overflow:visible behavior. Merits to both. Slightly prefer ours a little b/c if you have a lot of content and overflow:clip you'd have things way off in linebox
<dael> fantasai: So long as there's visible content makes sense to align to that visible content. One of the intentions is to not trigger a bunch of layout. Line of content and extra room for floating stuff which you clipped. Want to keep alignment
<dael> fantasai: Clamp to padding edge might make sense b/c else aligning to something can't see. overflow:clip to clip anything outside, if there's content visible want to align to that
<dael> iank_: This is also somewhat an issue for last-baseline
<dael> fantasai: Also first-baseline
<dael> iank_: Yes, rare case, but yes
<dael> fantasai: Makes sense for last and first baseline to be consistent. First we want to align to first-baseline when it's visible
<dael> astearns: If we clamp to clip area or margin edge...if clip area doesn't that give you layout changes based on clipping?
<dael> fantasai: We wanted to avoid it but idea you're aligning to something invisible we also want to avoid. Which to avoid more? clamping to visible makes sense
<dael> astearns: Thinking of animated where revealing and aligning to what you can't see if waht you want
<dael> fantasai: But in that case usually won't get clipped. Usually overflowing content you want clipped or not overflow
<dael> fantasai: Dynamic visibility you probably don't want to reveal content overflow
<dael> astearns: So option 4 calc same as visible but clamp to margin edge?
<dael> fantasai: Yeah. Margin edge is a little weird. Border edge makes more sense. Had an issue about margin or border earlier. PDF raster and browsers are inconsistent.
<dael> fantasai: I would clamp to the clip edge which is padding edge
<dael> iank_: Any other opinions? I'm weak on my opinion
<dael> florian: A little opinion. If we manage to get behavior that's really author friendly let's do that. If we're kind of author friendly but not really it's not worth another slightly different variant. If we can land exactly what you want you don't have to debug but elsewise concerned about subtlties
<dael> iank_: Discovered on FF issue tracker thinking FF was wrong. One data point a webdev expected Chrome behavior. But that's only one data point
<dael> fantasai: Pretty strong first baseline we should align to if visible, even if clip. Makes sense for last to follow that logic. If and where we clamp is more debatable
<smfr> q+
<dael> iank_: Prefer not the clampping behavior. Just pick the baseline, even if not visible or pick an edge
<astearns> ack smfr
<dael> iank_: One thing is people see overflow:clip as a dropin for overflow:hidden. THere's a weak argumenet to align to overflow:hidder
<dael> smfr: Prefer a behavior such that baseline alignment is same as if inline block had clippath inset: 000
<dael> fantasai: That's FF?
<dael> smfr: That's clip to the box
<dael> iank_: Why?
<dael> smfr: In terms of layout and rendering I consider overflow:clip as similar to clippath. Doesn't have effects, but it's a clip where I don't expect layout implications
<dael> fantasai: Fine with that
<dael> Rossen_: I wanted to pull back on smfr comment and get clearer picture in terms of behavior he would see in the attached example from emilio. Would that be, smfr , closer to FF or chromium?
<dael> smfr: Didn't examine. People said it's more like FF
<dael> Rossen_: Which has layout implications
<dael> iank_: Which does not
<dael> Rossen_: I was on an older FF
<dael> astearns: Suggest we resolve to spec option 1, FF behavior, since we have people in favor and iank_ only with weak objection. See if we can take that to the bug reporter and see if it makes sense to them
<dael> astearns: Can also talk to PDF reactor about if clampling behavior is required or they could move to non-clamp
<dael> astearns: Prop: Specify option 1; match FF current behavior
<dael> astearns: Objections?
<dael> RESOLVED: Specify option 1; match FF current behavior
bernhardf-ro commented 3 years ago

We can change the behavior of PDFreactor accordingly. Clamping was not required, just what we came up with internally.

khushalsagar commented 2 years ago

Could the spec be updated based on this resolution?

dbaron commented 2 years ago

It's worth noting that the relevant level 3 spec here is css-align-3, which both (a) has this issue fixed already and (b) makes a separate incompatible change regarding clamping the baseline to the border edge rather than always using the margin edge:

For the purposes of finding the baselines of a box, it and all its in-flow descendants with a scrolling mechanism (see the overflow property) must be considered as if scrolled to their initial scroll position. Furthermore, if, in the case of a scroll container box, the resulting position of a first/last baseline is past a box’s end/start border edge, its position is clamped to that border edge.