Open bfgeek opened 1 year ago
- Implementations (and the spec I think?) currently use border-box rect to determine if something is overconstrained (e.g.
position: sticky; left: 100px; right: 100px;
. Is this intentional/correct?
I think this is correct, since margins are not maintained from the sticky view rectangle. For example, consider the following (demo):
<style>
.scroller {
height: 400px;
overflow: auto;
border: 1px solid black;
}
.sticky {
margin: 250px 0;
height: 200px;
position: sticky;
background: green;
top: 0;
bottom:0;
}
.spacer {
height: 200px;
background: #ccf;
}
</style>
<div class="scroller">
<div class="spacer"></div>
<div class="sticky"></div>
<div class="spacer"></div>
</div>
The sticky element is not overconstrained. It can in fact be pushed up / down into the margin reserved between it and the adjacent spacers until it is 250px away from the top/bottom of the container / scroller. That said I still find it confusing that we try to preserve its margins from the container.
- Unclear from the spec how collapsing margins should be considered in the calculations above. Currently no implementations appear to look at collapsing margins.
IMO if we consider margins we should allow for them to collapse.
- The sticky view rectangle is currently defined as the border-box which seems to match what web-developers would expect. E.g. you don't expect the sticky-element to stick based on some unseen margin. Do the margins in the rest of the calculation add create more confusion than value? E.g. margins are often used for aligning content, if you use margins in this way and then make the element sticky-pos then it'll likely have un-expected behaviour (see auto-margins above as one example).
TL;DR Should the "position box" just be the border-box instead? (rather than the margin-box).
I agree, I think it would be simpler if the sticky adjustment were only constrained by the border box, and this might enable margins to be used to set the initial position. However, given that we seem to have compat on this part (with non-auto margins) there's a chance this will be breaking. In particular when the sticky element is first I could see developers being surprised if it gets pushed up into its top margin, or if last being pushed down into its bottom margin.
The CSS Working Group just discussed [css-position-3] Sticky position and margins (should margins be considered at all?).
, and agreed to the following:
RESOLVED: Don't consider margins in sticky-pos calculations
FWIW, I filed these Gecko bugs: https://bugzilla.mozilla.org/show_bug.cgi?id=1844435 on ignoring margins for sticky-positioning (pending evidence that that's web-compatible) https://bugzilla.mozilla.org/show_bug.cgi?id=1844438 as a smaller intermediate step of ignoring auto margins (which is a smaller step that seems more clearly web-compatible given that that's what Blink/WebKit already do, as discussed in the first comment here)
The dual implication of margin on sticky elements has been an issue and if it's web compatible it will be good to clean up that ambiguity. However, the margin has been our only way of controlling the "sticky constraint rectangle" (or the "sticky view rectangle" as it was called in the discussion).
jonjohnjohnson has described a couple of use cases for controlling the SCR in the issue, but I'll add another here for reference:
As it's been resolved to ignore margins in sticky-pos calculations, can we find another way to control the SCR? Something similar to scroll-margin
?
I know we have content that use margin to control the SCR, and we will have to find other solutions when this is implemented. The only solution (that I can think of) that is supported in browsers today is to add padding to the block level ancestor, and then negate that in the child nearest to the padding edge. That feels even worse than what we do today.
I respectfully disagree with this resolution and hope it ends up not web-compatible, primarily on the grounds that negative margins have allowed sticky elements to stay "stuck" (with fixed-like behavior) in webkit/gecko during overscroll animations.
See https://github.com/w3c/csswg-drafts/issues/8309#issuecomment-1443059377
I also second much of @johannesodland in https://github.com/w3c/csswg-drafts/issues/9052#issuecomment-1809658376
Returning to alternative solutions for defining the "sticky constraint rectangle":
Currently the sticky positioned element is shifted to stay within the sticky view rectangle insofar its possible while staying within its containing block inset by its margins (simplified). In other words, sticky pos operates with two insets, one inset from its scrollport, and one inset from its containing block. If margins are no longer to be considered, authors have no way of controlling that second inset.
I'm wondering if the box insets could be extended to support multiple named insets, to give a way of controlling the inset from the containing block?
/*
Make element sticky against scrollport
insofar as it can while staying 20px within its containing block
*/
position: sticky;
inset-block:
scrollport 0px,
containing-block 20px;
This could solve issue one in https://github.com/w3c/csswg-drafts/issues/2496.
(A position-container
property as mentioned in https://github.com/w3c/csswg-drafts/issues/9868 could solve issue 2 by allowing you to change the containing block.)
https://drafts.csswg.org/css-position-3/#stickypos-insets
The spec and implementations are currently a little scattered when it comes to how margins should be treated for sticky-pos elements. It's not clear if all the interactions have been thought through completely.
Implementations (and the spec I think?) currently use border-box rect to determine if something is overconstrained (e.g.
position: sticky; left: 100px; right: 100px;
. Is this intentional/correct?Implementations currently differ on if auto-margins should be considered. For example: https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=11848
Per-spec Firefox is currently correct - however this might be surprising to web-developers as it'll effectively opt-out the element being sticky by default if they are just using auto-margins to center content.
Unclear from the spec how collapsing margins should be considered in the calculations above. Currently no implementations appear to look at collapsing margins.
The sticky view rectangle is currently defined as the border-box which seems to match what web-developers would expect. E.g. you don't expect the sticky-element to stick based on some unseen margin. Do the margins in the rest of the calculation add create more confusion than value? E.g. margins are often used for aligning content, if you use margins in this way and then make the element sticky-pos then it'll likely have un-expected behaviour (see auto-margins above as one example).
TL;DR Should the "position box" just be the border-box instead? (rather than the margin-box).