SimonSapin / victor

Victor makes vectors.
Apache License 2.0
34 stars 3 forks source link

Percentages in top/left/bottom/right properties are relative to the containing block #23

Open SimonSapin opened 5 years ago

SimonSapin commented 5 years ago

In this code:

https://github.com/SimonSapin/victor/blob/dcdc5f66aba30976085eda077e06c38ab2ce893e/victor/src/layout/mod.rs#L249

The size of a block box is given as a basis to resolve percentages in offset properties if that same box is position: relative. Instead, the size of the containing block should be used. However at this point in the code, the block-direction size of the containing block might not be known yet. Therefore the computation of position: relative offsets must be delayed until later, when it is known. Options include:

The last one seems preferable to me, but requires keeping track of containing blocks in the fragment tree. (The containing block is not necessarily the direct parent fragment, again because of nested inline boxes.)

CC @nox

emilio commented 5 years ago

Does position: relative contribute to overflow in any way? What about position: sticky, which is quite similar?

I'd be wary of handling relative / sticky positioning during painting, I know Chrome handles part of the sticky positioning after layout and it's a pain for them:

In particular, for CSSOM and other layout queries like offsetFoo you don't really want to go into painting code, but you do need sticky / relative offsets.

SimonSapin commented 5 years ago

Good point. Do you mean the scrollable overflow region? I assume relpos does contribute to it since even transforms are accounted for in that spec. (Positioning is not mentioned explicitly.)

nox commented 5 years ago
  • Keep track during the main phase of a list of position: relative descendants, like we already do for postition: absolute. This has an allocation and memory cost.

We can't really do that for relatively positioned elements IMO, that would change the order of the fragments.

nox commented 5 years ago

Could we just add an Option<BoxOffsets> field in BoxFragment, with the following type:

struct BoxOffsets {
    inline_start: LengthOrPercentageOrAuto,
    inline_end: LengthOrPercentageOrAuto,
    block_start: LengthOrPercentageOrAuto,
    block_end: LengthOrPercentageOrAuto,
}
nox commented 5 years ago

The size of a block box is given as a basis to resolve percentages in offset properties if that same box is position: relative. Instead, the size of the containing block should be used. However at this point in the code, the block-direction size of the containing block might not be known yet. Therefore the computation of position: relative offsets must be delayed until later, when it is known. Options include:

Could you provide a sample exhibiting this? I couldn't reproduce.

nox commented 5 years ago

AFAICT by doing some samples, if the containing block doesn't have an non-auto height, then percentages for relative vertical positioning just resolve to 0.

SimonSapin commented 5 years ago

Oh, wonderful. It looks like at least Firefox and Chromium have interop and disagree with the spec.

For the height property there’s:

If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'.

… but nothing similar for offset properties.

SimonSapin commented 5 years ago

Test case: remove the height declaration in https://codepen.io/anon/pen/OYEWXd

emilio commented 5 years ago

Try on quirks mode / no quirks mode for fun / sadness :)

SimonSapin commented 5 years ago

@emilio Do you mean in general or in this specific case? I couldn’t reproduce a behavior change when adding or removing a doctype in the test case above.

emilio commented 5 years ago

Not in Gecko, but without the height on the <body>, different UAs size the <body> differently in quirks mode vs. not.