您的当前位置:首页正文

position:sticky的用法详解

2020-11-27 来源:筏尚旅游网
CSS中的position: sticky让我们可以在很少的代码行中构建一些非常简洁的交互。当用户滚动时希望UI元素在视图中留在任何时候它都很有用,但是直到该元素与滚动视窗的顶部/底部/左侧/右侧的egde达到特定距离时才变得粘性。

我们可以如何来设置一个position: sticky?

position: sticky非常适合iOS样式列表标题。滚动内容并在标题0px从top边缘击中后观察标题。

.heading{
 background: #ccc;
 height: 50px;
 line-height: 50px;
 margin-top: 10px;
 font-size: 30px;
 padding-left: 10px;
 position: -webkit-sticky;
 position: sticky;
 top: 0px;
}

如果用户向下滚动,您希望列表标题保持可见。如果向上滚动,您还希望“添加项目”页脚可见。试试吧!向上和向下滚动并观察这些元素在到达视口边缘后如何粘附:

header{
 background: #ccc;
 font-size: 20px;
 color: #282a37;
 padding: 10px;
 position: -webkit-sticky;
 position: sticky;
 top: 0;
}
footer{
 background: #ccc;
 padding: 10px;
 color: #ae81fe;
 position: relative;
 position: -webkit-sticky;
 position: sticky;
}
footer{
 bottom: 0;
}
list{
 border: 1px solid #ccc;
 border-radius: 5px;
 width: 200px;
 margin-left: 20px;
 background: #282a37;
}
item{
 padding: 10px;
 color: #fff;
 display: block;
}
body{
 padding-top: 20px;
 display: flex;
 align-items: flex-start;
}
.abs{
 position: absolute;
 right: 0;
 top: 10px;
}

您还可以将项目粘贴到左侧或右侧边缘。这是一个侧面图像查看器,带有图像的旋转文本描述。将其向侧面滚动并观察,因为描述停靠在左侧,在视图中,直到新描述将其推开。

div[description]{
 max-width: 40px;
 height: 300px;
 position: -webkit-sticky;
 position: sticky;
 left: 0; /* become sticky once touching left edge */
}
sidescroller{
 display: flex;
 align-items: center;
 overflow-x: auto;
 overflow-y: hidden;
 background: #000;
}
div[wrapper]{
 flex: 0 0 40px;
 max-width: 40px;
 height: 300px;
 position: -webkit-sticky;
 position: sticky;
 left: 0;
 white-space: nowrap;
 color: #fff;
}
div[item]{
 display: flex;
}
div[description] span{
 display: inline-block;
 background: rgba(0,0,0,.5);
 width: 300px;
 height: 40px;
 transform: rotate(-90deg) translateX(-300px);
 transform-origin: left top 0;
 padding-top: 11px;
 text-align: center;
 text-transform: uppercase;
 color: #fff;
 font-size: 14px;
}
img{
 max-height: 300px;
}

当部分或全部元素滚动出视图时,您甚至可以指定元素变为粘性时指定负数!这可能是有用的,例如侧边栏菜单在滚出视图时变得粘滞,留下一个小按钮,当点击时可以跳回侧边栏:

.sidebar{
 background: purple;
 width: 200px;
 height: 300px;
 padding: 20px;
 flex-shrink: 0;
 overflow: visible;
 position: -webkit-sticky;
 position: sticky;
 left: -200px;
}
.sidebar .handle{
 height: 30px;
 width: 30px;
 position: absolute;
 right: -30px;
 top: 0;
 background: purple;
 color: #fff;
 font-weight: bold;
 font-size: 20px;
 padding-left: 8px;
 cursor: pointer;
}
p{
 padding: 20px;
}
.site{
 display: flex;
}

使用position: sticky很简单。

1、将元素声明为sticky position:sticky(加上所需的任何浏览器前缀position: -webkit-sticky)

2、指定要“粘贴”的项目的边(顶部|右侧|底部|左侧)。

3、输入距所述边缘的距离,当到达时将激活粘性。

例如,假设您希望标题在距离滚动区域顶部20px时变为粘性:

.header{
 position: -webkit-sticky;
 position: sticky;
 top: 20px;
}

或者像上面的例子一样滚动到视图之外的左边缘菜单:

.menu{
 width: 200px;
 position: -webkit-sticky;
 position: sticky;
 left: -200px;
}

position: sticky的注意事项

同级元素

如果将同级(相邻)元素设置为position: sticky,则它们的行为与嵌套项目中的元素略有不同。粘性兄弟元素不会为新元素移动。相反,它们会重叠到位:

360截图20181105164307294.jpg

有时候你可能会想要这种行为,但是如果你确实要设置一个背景颜色,否则用户会看到所有的项目一下子被打包到同一个小空间里,看起来就像一团糟。

在另一方面,如果你把粘性元素嵌套到父元素中,就像我们在SsiDelLoad例子中所做的那样,然后一旦另一个粘性元素开始接触它,粘性元素将开始移动,这是一个很好的做法,效果有点像IMO:

360截图20181105164541781.jpg

Overflow(溢出)

不要使用overflow: auto|scroll|hidden在position:sticky元素的父元素上,这会完全打破了粘性,但是overflow: visible可以。

绝对定位(position:absolute)

如果你想在一个粘性元素内部使用position:absolute元素,你必须要仔细了。如果您的应用程序在不支持的旧浏览器中运行position:sticky,那么该粘性元素将不会像相对定位元素那样运行。因此,绝对定位元素将跳过它并查找DOM树,直到找到下一个非静态元素(绝对|相对固定位置),html如果没有找到则默认为元素。换句话说,您的绝对定位元素将在屏幕上与您预期的不同。如果你正在建设一些旧的浏览器,有人可能会认为这种情况的解决方法就是相对定位和粘性定位都设置:

.footerwithAbsolutePositionedeChildren{
position: relative;/*don't forgot this*/
}
/*NOTE: @supports has to be at the root,not nested*/
@supports(position:sticky){
.footerwithAbsolutePositionedeChildren{
position: sticky;
bottom: 20px;/now this won't mess with position in non-sticky browsers*/
}
}

为什么不使用JavaScript?

利用JS你绝对可以实现这个。但这将涉及一个scroll事件监听器,这仍然是一个非常昂贵的东西添加到您的应用程序。滚动是用户执行的最常见操作之一,并且在这些事件期间执行JavaScript使得难以维持稳定的60 FPS(每秒帧数)滚动。UI与用户的鼠标/手指/手写笔不同步。这称为滚动jank。有一种特殊的事件监听器称为被动事件监听器,它让浏览器知道您的事件不会停止滚动,因此浏览器可以更好地优化这些事件。但是在IE或Edge中它们还不支持,无论如何你都需要JS后备方法。

此外,由于position:sticky您在滚动期间没有写入DOM,因此您不会导致任何强制布局和布局重新计算。因此,浏览器能够将此操作移动到GPU,即使粘性元素在播放中,您也可以非常流畅地滚动。它在移动Sarari中特别流畅。

另外,编写两行声明式CSS比使用JS替代方案更容易。

我现在可以用吗?

position:sticky很多浏览器都支持,但Edge中还没有。除非您在Enterprise Town承担合同义务,否则IE在此处无关紧要。如果你必须有这种行为,那里有很多polyfill,但它们都使用JavaScript,所以你将获得上面提到的性能。一个更好的选择是设计你的应用程序,以便粘性位置是一个光滑的添加,但应用程序仍然没有它的功能。

显示全文