一场 position: sticky 无效引发的思考

Relate to https://stackoverflow.com/questions/43707076/how-does-the-position-sticky-property-work

一些属性会使 position: sticky 无效

  • You must specify a threshold with at least one of top, right, bottom, or left for sticky positioning to behave as expected
  • 父元素的 display: flex / overflow 属性,等会使其无效

没了 display: flex 还怎么活

使用 float: left 浮动元素
又导致了一个问题 子元素无法把父元素撑开

解决使用 float: left 出现的塌陷

Relate to https://blog.csdn.net/xiaobing_hope/article/details/50296009

在最后一个浮动子元素后面添加一个空的div,并清除其浮动

html
1<div style="float: left" class="div0">
2    <div class="div1" style="float: left;"></div>
3    <div class="div2" style="float: left;"></div>
4    <div style="clear:both;"></div>
5</div>

2022-01-06 更新

Relate to https://ishadeed.com/article/position-sticky-css-grid/

align-self: start;

demo: https://codepen.io/shadeed/pen/VwzGpRa
其实之前链接已经有较好的解决方案了 https://stackoverflow.com/a/66966273/12583084, 我却没看到, 并不需要那么多 hack 。

关于 position 的一些介绍

https://developer.mozilla.org/en-US/docs/Web/CSS/position

在CSS中,元素的 position 属性的默认值是 static

当元素的 position 被设置为 static 时,该元素将根据正常的文档流进行布局。在这种情况下,你不能使用 toprightbottomleft 属性来移动该元素。

其他 position 属性的值包括:

  1. relative: 元素会按照正常文档流进行布局,但可以使用 toprightbottomleft 属性对其进行相对于其正常位置的偏移。
  2. absolute: 元素的位置相对于最近的非 static 定位的祖先元素。如果没有这样的祖先元素,那么它会相对于<html>元素。
  3. fixed: 元素的位置相对于浏览器窗口是固定的,即使窗口滚动,它也不会移动。
  4. sticky: 这是一个相对于用户的滚动位置的混合类型。元素基于用户的滚动位置在容器内“粘贴”。

除非你为元素显式设置了其他值,否则 position 的值将默认为 static

和 z-index 的关系

z-index 是 CSS 属性,主要用于控制堆叠上下文中元素的堆叠顺序。在一个页面上,可能有多个重叠的元素,而 z-index 用于决定哪个元素应该位于最顶部,哪个元素应该在下面。

z-index 的基本作用可以从以下几个方面理解:

  1. 控制堆叠顺序:在默认情况下,后来的元素会堆叠在先前的元素上面。但使用 z-index 可以明确地指定元素的堆叠顺序。
  2. 数值z-index 的值是一个整数(可以是正数、0 或负数)。元素的堆叠顺序由这个数值决定,数值较大的元素会被放置在数值较小的元素上面。例如,一个 z-index 为 3 的元素会堆叠在一个 z-index 为 2 的元素上面。
  3. 上下文z-index 只适用于设置了 position 属性值为 relativeabsolutefixedsticky 的元素。
  4. 堆叠上下文:当元素的 position 值不是 static,并且 z-index 值不是 auto 时,该元素会创建一个新的堆叠上下文。这意味着其子元素的 z-index 仅在此父元素的堆叠上下文中有效,不会影响到其他的堆叠上下文。
  5. 默认行为:如果没有为元素指定 z-index,那么它的堆叠顺序会按照 HTML 源代码中的顺序,后面的元素会覆盖在前面的元素上。
  6. 关系:如果两个元素具有相同的 z-index 值,那么它们之间的堆叠顺序会根据它们在 HTML 中的顺序来决定。
  7. 透明度和混合模式:设置元素的 opacity 值小于 1 或使用了某些混合模式(如 mix-blend-mode)也可能创建新的堆叠上下文,即使 z-indexauto

使用 z-index 时要小心,因为过多或不合理地使用可能会导致页面的堆叠顺序变得复杂和难以管理。

position 为 static 的情况,z-index 不会生效。

  1. 元素的默认状态:在默认情况下,HTML元素的 position 属性是 static
  2. 默认堆叠顺序:对于 position: static 的元素,它们在页面上的堆叠顺序完全取决于它们在HTML源代码中的位置。一般来说,后出现在代码中的元素会覆盖前面的元素。
  3. z-index 的局限性z-index 属性只对设置了 position 属性值为 relativeabsolutefixedsticky 的元素有效。对于 position: static 的元素,设置 z-index 是无效的,它不会影响该元素的堆叠顺序。

如果你希望利用 z-index 来控制元素的堆叠顺序,你需要给那些元素设置一个非 staticposition 值。

子元素不会继承父元素的 position 属性

position 属性在 CSS 中不是一个可继承属性。这意味着子元素不会从其父元素继承 position 的值。

例如,如果你为一个父元素设置 position: relative;,它的子元素默认仍然是 position: static;,除非你明确地为子元素指定了一个不同的 position 值。

这种设计使得我们可以独立地控制每个元素的定位属性,而不必担心其子元素的布局会受到意外的影响。

  • static

    The element is positioned according to the normal flow of the document. The top, right, bottom, left, and z-index properties have no effect. This is the default value.

  • relative

    The element is positioned according to the normal flow of the document, and then offset relative to itself based on the values of top, right, bottom, and left. The offset does not affect the position of any other elements; thus, the space given for the element in the page layout is the same as if position were static.

    This value creates a new stacking context when the value of z-index is not auto. Its effect on table-*-group, table-row, table-column, table-cell, and table-caption elements is undefined.

  • absolute

    The element is removed from the normal document flow, and no space is created for the element in the page layout. The element is positioned relative to its closest positioned ancestor (if any) or to the initial containing block. Its final position is determined by the values of top, right, bottom, and left.

    This value creates a new stacking context when the value of z-index is not auto. The margins of absolutely positioned boxes do not collapse with other margins.

  • fixed

    The element is removed from the normal document flow, and no space is created for the element in the page layout. The element is positioned relative to its initial containing block, which is the viewport in the case of visual media. Its final position is determined by the values of top, right, bottom, and left.

    This value always creates a new stacking context. In printed documents, the element is placed in the same position on every page.

  • sticky

    The element is positioned according to the normal flow of the document, and then offset relative to its nearest scrolling ancestor and containing block (nearest block-level ancestor), including table-related elements, based on the values of top, right, bottom, and left. The offset does not affect the position of any other elements.

    This value always creates a new stacking context. Note that a sticky element "sticks" to its nearest ancestor that has a "scrolling mechanism" (created when overflow is hidden, scroll, auto, or overlay), even if that ancestor isn't the nearest actually scrolling ancestor.

  • A positioned element is an element whose computed position value is either relative, absolute, fixed, or sticky. (In other words, it's anything except static.)
  • A relatively positioned element is an element whose computed position value is relative. The top and bottom properties specify the vertical offset from its normal position; the left and right properties specify the horizontal offset.
  • An absolutely positioned element is an element whose computed position value is absolute or fixed. The top, right, bottom, and left properties specify offsets from the edges of the element's containing block. (The containing block is the ancestor relative to which the element is positioned.) If the element has margins, they are added to the offset. The element establishes a new block formatting context (BFC) for its contents.
  • A stickily positioned element is an element whose computed position value is sticky. It's treated as relatively positioned until its containing block crosses a specified threshold (such as setting top to value other than auto) within its flow root (or the container it scrolls within), at which point it is treated as "stuck" until meeting the opposite edge of its containing block.

Most of the time, absolutely positioned elements that have height and width set to auto are sized so as to fit their contents. However, non-replaced, absolutely positioned elements can be made to fill the available vertical space by specifying both top and bottom and leaving height unspecified (that is, auto). They can likewise be made to fill the available horizontal space by specifying both left and right and leaving width as auto.

Except for the case just described (of absolutely positioned elements filling the available space):

  • If both top and bottom are specified (technically, not auto), top wins.
  • If both left and right are specified, left wins when direction is ltr (English, horizontal Japanese, etc.) and right wins when direction is rtl (Persian, Arabic, Hebrew, etc.).

Scrolling elements containing fixed or sticky content can cause performance and accessibility issues. As a user scrolls, the browser must repaint the sticky or fixed content in a new location. Depending on the content needing to be repainted, the browser performance, and the device's processing speed, the browser may not be able to manage repaints at 60 fps, causing accessibility concerns for people with sensitivities and jank for everyone. One solution is to add will-change: transform to the positioned elements to render the element in its own layer, improving repaint speed and therefore improving performance and accessibility.