dam*_*ymq 8 css css-position sticky
当我阅读有关MDN position属性的文章时,这是一个问题。我认为此处sticky描述的行为与实际行为之间存在明显的差异。
根据MDN,固定位置元素将被视为相对位置元素,直到超过指定的阈值为止;当超过阈值时,它们将被视为固定位置元素,直到达到父元素的边界为止(Link)。
粘性定位可以看作是相对定位和固定定位的混合体。粘性定位的元素将被视为相对定位,直到其超过指定的阈值为止,在该点处将其视为固定的,直到其到达其父对象的边界为止。例如...
Run Code Online (Sandbox Code Playgroud)#one { position: sticky; top: 10px; }...将相对位置为id的元素定位到视口滚动之前,以使元素距离顶部小于10个像素。超过该阈值,该元素将从顶部固定为10个像素。
因此,我创建了以下代码并确认了操作。
#one { position: sticky; top: 10px; }
Run Code Online (Sandbox Code Playgroud)
body {
margin: 0;
}
.container {
display: flex;
flex-direction: column;
}
.container>* {
width: 100%;
}
header {
background: #ffa;
height: 130vh;
}
main {
background: #faf;
height: 210vh;
}
footer {
background: #faa;
height: 8vh;
position: sticky;
bottom: 0;
}
.footer {
background: #aff;
height: 100vh;
}Run Code Online (Sandbox Code Playgroud)
根据MDN文章,此代码“是相对放置元素,直到通过滚动视口使元素的位置离视口底部小于0px为止,并且当它离底部大于0px时成为固定的放置元素“ 我刚在想。
但是,结果是“滚动到固定位置元素,直到通过滚动视口使元素的位置从视口的下端开始小于0px为止,并且当从下视点大于0px时成为相对排列的元素结束”。
为什么指定bottom:0结果与MDN中显示的行为相反?
当top: 0指定时,相对位置将在元素未到达bottom: 0视口时应用,而在到达时将应用固定位置。如果bottom: 0指定,则相反。相对位置在元素未到达bottom: 0视口时应用,而固定位置在元素到达视口时应用
我读了CSS3,但是它的机制很难读
Tem*_*fif 12
根据 MDN,固定位置元素被视为相对位置元素,直到超过指定的阈值
这完全是语言问题,因为上面的句子并不意味着元素一定会开始position:relative 然后变得固定。它说直到超过指定的阈值。那么,如果最初我们超过了指定的阈值怎么办?这实际上是你的例子的情况。
换句话说,position:sticky有两种状态。
哪个是第一个取决于您的 HTML 结构。
下面是一个基本的例子来说明:
body {
height:150vh;
margin:0;
display:flex;
flex-direction:column;
border:2px solid;
margin:50px;
}
.b {
margin-top:auto;
position:sticky;
bottom:0;
}
.a {
position:sticky;
top:0;
}Run Code Online (Sandbox Code Playgroud)
<div class="a">
I will start relative then I will be fixed
</div>
<div class="b">
I will start fixed then I will be relative
</div>Run Code Online (Sandbox Code Playgroud)
你也可以混合使用。我们开始固定,变得相对,然后再次固定:
body {
height:250vh;
margin:0;
display:flex;
flex-direction:column;
border:2px solid;
margin:50px;
}
body:before,
body:after {
content:"";
flex:1;
}
.a {
position:sticky;
top:0;
bottom:0;
}Run Code Online (Sandbox Code Playgroud)
<div class="a">
I will start fixed then relative then fixed
</div>Run Code Online (Sandbox Code Playgroud)
正如你在上面的例子中看到的,两个状态都是独立的。如果 的条件position:fixed为真,那么我们有position:fixed,如果不是,那么它是相对的。
我们可以认为浏览器会实现这个伪代码:
on_scroll_event() {
if(threshold exceeded)
position <- fixed
else
position <- relative
}
Run Code Online (Sandbox Code Playgroud)
为了更准确和完整地了解该机制,您需要考虑 3 个要素。粘性元素(以及 top/bottom/left/right 的值)、粘性元素的包含块和带有滚动框的最近祖先。
左/上/下/右是相对于滚动框计算的,包含块将定义粘性元素的限制。
下面是一个例子来说明:
on_scroll_event() {
if(threshold exceeded)
position <- fixed
else
position <- relative
}
Run Code Online (Sandbox Code Playgroud)
body {
margin:0;
}
.wrapper {
width:300px;
height:150px;
border:2px solid red;
overflow:auto;
}
.parent {
height:200%;
margin:100% 0;
border:2px solid;
}
.sticky {
position:sticky;
display:inline-block;
margin:auto;
top:20px;
background:red;
}
.non-sticky {
display:inline-block;
background:blue;
}Run Code Online (Sandbox Code Playgroud)
最初我们的元素是隐藏的,这是合乎逻辑的,因为它不能超出其包含块(其限制)。一旦我们开始滚动,我们将看到我们的粘性元素和相关元素的行为完全相同。当我们有一个距离20px的粘性元件和我们达到阈值的滚动框的上边缘之间,我们开始具有position:fixed直到我们在底部再次到达包含块的限制(即,我们没有更多的有粘性行为空间)
现在让我们用底部替换顶部
<div class="wrapper"><!-- our scrolling box -->
<div class="parent"><!-- containing block -->
<div class="sticky">I am sticky</div>
<div class="non-sticky">I am the relative position</div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
body {
margin:0;
}
.wrapper {
width:300px;
height:150px;
border:2px solid red;
overflow:auto;
}
.parent {
height:200%;
margin:100% 0;
border:2px solid;
}
.sticky {
position:sticky;
display:inline-block;
margin:auto;
bottom:20px;
background:red;
}
.non-sticky {
display:inline-block;
background:blue;
}Run Code Online (Sandbox Code Playgroud)
什么都不会发生,因为当20px元素和滚动框的底部边缘之间存在距离时,粘性元素已经接触到包含块的顶部边缘并且它不能出去。
让我们在之前添加一个元素:
<div class="wrapper"><!-- our scrolling box -->
<div class="parent"><!-- containing block -->
<div class="sticky">I am sticky</div>
<div class="non-sticky">I am the relative position</div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
body {
margin:0;
}
.wrapper {
width:300px;
height:150px;
border:2px solid red;
overflow:auto;
}
.parent {
height:200%;
margin:100% 0;
border:2px solid;
}
.sticky {
position:sticky;
display:inline-block;
margin:auto;
bottom:20px;
background:red;
}
.non-sticky {
display:inline-block;
background:blue;
}
.elem {
height:50px;
width:100%;
background:green;
}Run Code Online (Sandbox Code Playgroud)
现在我们已经创造50px了一个具有粘性行为的空间。让我们添加顶部和底部:
<div class="wrapper"><!-- our scrolling box -->
<div class="parent"><!-- containing block -->
<div class="elem">elemen before</div>
<div class="sticky">I am sticky</div>
<div class="non-sticky">I am the relative position</div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
body {
margin:0;
}
.wrapper {
width:300px;
height:150px;
border:2px solid red;
overflow:auto;
}
.parent {
height:200%;
margin:100% 0;
border:2px solid;
}
.sticky {
position:sticky;
display:inline-block;
margin:auto;
bottom:20px;
top:20px;
background:red;
}
.non-sticky {
display:inline-block;
background:blue;
}
.elem {
height:50px;
width:100%;
background:green;
}Run Code Online (Sandbox Code Playgroud)
现在我们有顶部和底部的行为,逻辑可以恢复如下:
on_scroll_event() {
if( top_sticky!=auto && distance_top_sticky_top_scrolling_box <20px && distance_bottom_sticky_bottom_containing_block >0) {
position <- fixed
} else if(bottom_sticky!=auto && distance_bottom_sticky_bottom_scrolling_box <20px && distance_top_sticky_top_containing_block >0) {
position <- fixed
} else (same for left) {
position <- fixed
} else (same for right) {
position <- fixed
} else {
position <- relative
}
}
Run Code Online (Sandbox Code Playgroud)
该规范是难以所以这里明白的是我尝试基于解释他们MDN。先说几个定义:
position: sticky一个粘性元素position: sticky; top: 100px;的位置如下:
以下示例显示了这些规则的运作方式:
body { font: medium sans-serif; text-align: center; }
body::after { content: ""; position: fixed; top: 100px; left: 0; right: 0; border: 1px solid #F00; }
header, footer { height: 75vh; background-color: #EEE; }
.containing-block { border-bottom: 2px solid #FA0; background: #DEF; }
.containing-block::after { content: ""; display: block; height: 100vh; }
.before-sticky { border-bottom: 2px solid #080; padding-top: 50px; }
.after-sticky { border-top: 2px solid #080; padding-bottom: 50px; }
.sticky { position: sticky; top: 100px; padding-top: 20px; padding-bottom: 20px; background-color: #CCC; }Run Code Online (Sandbox Code Playgroud)
<header>header</header>
<div class="containing-block">
<div class="before-sticky">content before sticky</div>
<div class="sticky">top sticky</div>
<div class="after-sticky">content after sticky</div>
</div>
<footer>footer</footer>Run Code Online (Sandbox Code Playgroud)
同样,粘性元素position: sticky; bottom: 100px;的定位如下:
body { font: medium sans-serif; text-align: center; }
body::after { content: ""; position: fixed; bottom: 100px; left: 0; right: 0; border: 1px solid #F00; }
header, footer { height: 75vh; background-color: #EEE; }
.containing-block { border-top: 2px solid #FA0; background: #DEF; }
.containing-block::before { content: ""; display: block; height: 100vh; }
.before-sticky { border-bottom: 2px solid #080; padding-top: 50px; }
.after-sticky { border-top: 2px solid #080; padding-bottom: 50px; }
.sticky { position: sticky; bottom: 100px; padding-top: 20px; padding-bottom: 20px; background-color: #CCC; }Run Code Online (Sandbox Code Playgroud)
<header>header</header>
<div class="containing-block">
<div class="before-sticky">content before sticky</div>
<div class="sticky">bottom sticky</div>
<div class="after-sticky">content after sticky</div>
</div>
<footer>footer</footer>Run Code Online (Sandbox Code Playgroud)
我希望这是足够简单的解释。