为什么在 `html` 上设置 `overflow-x: hidden` 会导致孩子的 `position:sticky` 元素表现不同? [英] Why does setting `overflow-x: hidden` on `html` cause a child's `position: sticky` element to behave differently?

查看:35
本文介绍了为什么在 `html` 上设置 `overflow-x: hidden` 会导致孩子的 `position:sticky` 元素表现不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的两个例子是相同的,除了第一个例子将 overflow-x: hidden 应用于 body,而第二个例子将它应用于 html, 正文.

为什么第一个示例按预期工作而第二个示例没有?

这按预期工作:

body {边距:0;溢出-x:隐藏;}p.sticky {位置:粘性;顶部:0;红色;}

<p>Lorem ipsum dolor sat amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p><p class="sticky">foo</p><p>Lorem ipsum dolor 坐在 amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p><p>Lorem ipsum dolor 坐在 amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p><p>Lorem ipsum dolor 坐在 amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p><p>Lorem ipsum dolor 坐在 amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p><p>Lorem ipsum dolor 坐在 amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p><p>Lorem ipsum dolor 坐在 amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p><p>Lorem ipsum dolor 坐在 amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p>

但是,这不会:

html, body {边距:0;溢出-x:隐藏;}p.sticky {位置:粘性;顶部:0;红色;}

<p>Lorem ipsum dolor sat amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p><p class="sticky">foo</p><p>Lorem ipsum dolor 坐在 amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p><p>Lorem ipsum dolor 坐在 amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p><p>Lorem ipsum dolor 坐在 amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p><p>Lorem ipsum dolor 坐在 amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p><p>Lorem ipsum dolor 坐在 amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p><p>Lorem ipsum dolor 坐在 amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p><p>Lorem ipsum dolor 坐在 amet consectetur,adipisicing 精英.Eius magnam odio quidem nisi?Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae.Doloribus quasi eaque consequuntur voluptatibus sunt!</p>

解决方案

以下是 CSS 定位规范对 position:sticky

<块引用>

6.2.粘性定位

粘性定位框与相对定位框的定位类似,但偏移量是根据最近的具有滚动框的祖先或视口(如果没有祖先具有滚动框)计算的.

所以这里的问题是:有滚动框的最近祖先是什么,而不是垂直滚动条滚动的框是什么?

要理解这一点,我们需要考虑溢出传播.CSS 溢出规范 说:

<块引用>

3.4.溢出视口传播

UA 必须将在根元素上设置的 overflow-* 值应用到视口.然而,当根元素是一个 [HTML] html 元素(包括 HTML 的 XML 语法),其溢出值是可见的(在两个轴上),并且该元素有一个 body 元素作为子元素时,用户代理必须改为应用溢出 -* 视口的第一个此类子元素的值.从中传播值的元素必须具有可见的溢出值.

所以,在第一种情况下

body {边距:0;溢出-x:隐藏;}

body 元素的溢出属性被传播到视口.由于这种传播,p.sticky 的祖先元素没有滚动框,因此粘性偏移是相对于视口计算的.视口也是被垂直滚动条滚动的框.

在第二种情况下,

html, body {边距:0;溢出-x:隐藏;}

传播到视口的是 html 元素的溢出属性,而 body 元素保留其指定的溢出属性,建立一个滚动框,它是 p.sticky 的祖先.然后计算相对于 body 元素的偏移量.但垂直滚动条作用的不是body元素,它仍然是视口.

所以 p.sticky 不会相对于 body 元素移动,并且随着整个元素的移动,p.sticky 不会被卡住.>

The following two example are identical except the first example applies overflow-x: hidden to only the body, while the second example applies it to both html, body.

Why does the first example works as expected while the second one does not?

This works as expected:

body {
  margin: 0;
  overflow-x: hidden;
}

p.sticky {
  position: sticky;
  top: 0;
  color: red;
}

<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>
<p class="sticky">foo</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>

But, this doesn't:

html, body {
  margin: 0;
  overflow-x: hidden;
}

p.sticky {
  position: sticky;
  top: 0;
  color: red;
}

<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>
<p class="sticky">foo</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Eius magnam odio quidem nisi? Dolorum voluptatibus voluptas dignissimos cupiditate vel voluptates ducimus ullam, cumque vitae. Doloribus quasi eaque consequuntur voluptatibus sunt!</p>

解决方案

Here's what the CSS positioning spec has to say about position:sticky

6.2. Sticky positioning

A stickily positioned box is positioned similarly to a relatively positioned box, but the offset is computed with reference to the nearest ancestor with a scrolling box, or the viewport if no ancestor has a scrolling box.

So the matter here is: what is the nearest ancestor with a scrolling box, as opposed what box is scrolled by the vertical scroll bar?

To understand that, we need to take into account overflow propagation. The CSS overflow spec says:

3.4. Overflow Viewport Propagation

UAs must apply the overflow-* values set on the root element to the viewport. However, when the root element is an [HTML] html element (including XML syntax for HTML) whose overflow value is visible (in both axes), and that element has a body element as a child, user agents must instead apply the overflow-* values of the first such child element to the viewport. The element from which the value is propagated must then have a used overflow value of visible.

So, in the first case

body {
  margin: 0;
  overflow-x: hidden;
}

the overflow properties of the body element are propagated to the viewport. Because of that propagation, there's no ancestor element of p.sticky that has a scrolling box, so the sticky offset gets computed relative to the viewport. The viewport is also the box that gets scrolled by the vertical scrollbar.

In the second case,

html, body {
  margin: 0;
  overflow-x: hidden;
}

it's the overflow properties of the html element that get propagated to the viewport, and the body element retains its specified overflow properties, establishing a scrolling box that's the ancestor of p.sticky. The offset is then computed relative to the body element. But it's not the body element that the vertical scrollbar works on, it's still the viewport.

So p.sticky doesn't move relative to the body element, and as the whole thing moves there's nothing for p.sticky to get stuck against.

这篇关于为什么在 `html` 上设置 `overflow-x: hidden` 会导致孩子的 `position:sticky` 元素表现不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆