css粘性布局
如果您已阅读Annarita Tranfici的文章“ 显而易见的设计总是赢家”,则您可能会同意她的说法:
人们希望看到常见的模式:在页面顶部找到主菜单,在右上角找到搜索框,在底部找到页脚,依此类推。
我同意人们期望将网站的某些组件放置在特定位置,并且我认为,在主菜单中,这一点更为真实。
有时,由于客户的请求或我们已经确定这是最好的方法,我们可能要求主导航在页面上始终保持可见,而无需固定在位,实质上是紧随页面内容。 近年来,许多基于JavaScript的解决方案日趋成熟,因为仅CSS不能完成此任务。
在本文中,我们将讨论position: sticky
,这个问题的新CSS解决方案。
我们正在解决什么问题?
在讨论position
属性的新值之前,让我们更好地了解我们要解决的问题是什么。
让我们假装我们令人惊叹的网站的主菜单位于标题之后,但仍位于页面顶部(不在侧边栏中),并且占据了所有可用宽度。 可能看起来像这样:
请参阅CodePen上SitePoint ( @SitePoint ) 提供的不带粘滞菜单的钢笔示例 。
我们要实现的是,当用户滚动页面时,只要将菜单置于视口的顶部,菜单就不会停留在视口之外,而是停留在顶部位置-好像它有一个position: fixed
应用于它(仅当它到达视口顶部时)。
要使用传统代码实现此目的,我们需要添加一些JavaScript。 我们侦听页面的滚动事件,并使用JavaScript根据视口的当前位置更改position
和top
属性的值。 具体来说,我们需要在菜单位于视口顶部时将top: 0
和position: fixed
到菜单,然后将属性还原为默认值。
一种替代但类似的方法是在CSS中创建一个存在这些值的类,然后根据需要使用JavaScript添加和删除该类,如下所示:
var menu = document.querySelector('.menu')
var menuPosition = menu.getBoundingClientRect().top;
window.addEventListener('scroll', function() {
if (window.pageYOffset >= menuPosition) {
menu.style.position = 'fixed';
menu.style.top = '0px';
} else {
menu.style.position = 'static';
menu.style.top = '';
}
});
请注意,此代码段不适用于旧版本的Internet Explorer。 如果您需要使用这些浏览器(可怜!),我将提供一些您可以考虑使用的polyfill选项。
第二步的现场演示如下所示:
请参阅Pen 位置:在CodePen上坚持使用 SitePoint( @SitePoint )的Simply JS 。
可是等等! 您能找出该代码导致的问题吗? 我看到的许多实现,包括到目前为止我们开发的实现,都没有考虑到一个重要的问题。 当我们将元素的位置更改为fixed
,它将离开页面的流动,因此其下方的元素“向上跳跃”的像素数量大致等于元素的高度(此“跳跃”的高度取决于在边距,边界等上)。
一种可能的解决方案是注入一个与我们要“粘贴”的大小相同的占位符元素,以便在更新粘贴元素的样式时不会出现跳转。 另外,如果已经设置了正确的值,我们就不会无缘无故地重新分配值。 最后,我们要使用我在CSS类中描述的技术。
JavaScript代码的最终版本如下:
var menu = document.querySelector('.menu');
var menuPosition = menu.getBoundingClientRect();
var placeholder = document.createElement('div');
placeholder.style.width = menuPosition.width + 'px';
placeholder.style.height = menuPosition.height + 'px';
var isAdded = false;
window.addEventListener('scroll', function() {
if (window.pageYOffset >= menuPosition.top && !isAdded) {
menu.classList.add('sticky');
menu.parentNode.insertBefore(placeholder, menu);
isAdded = true;
} else if (window.pageYOffset < menuPosition.top && isAdded) {
menu.classList.remove('sticky');
menu.parentNode.removeChild(placeholder);
isAdded = false;
}
});
![](https://img-blog.csdnimg.cn/2022010615215346782.png)
免费学习PHP!
全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。
原价$ 11.95 您的完全免费
这是sticky
类的声明块:
.sticky {
top: 0;
position: fixed;
}
下一个演示显示了最终结果:
请参阅Pen的位置:对JS粘性,由CodePen上的SitePoint( @SitePoint ) 改进 。
既然您已经掌握了问题所在以及可能的基于JavaScript的解决方案,那么现在该是拥抱现代性并讨论这一position: sticky
就是问题。
position: sticky
是什么? position: sticky
吗?
如果您如此勇敢地认真地遵循上一节,您可能会想知道“为什么浏览器不能为我这样做?” 很高兴你问!
sticky
是为CSS position
属性引入的新值 。 该值应该表现得像position: static
在其父级中为position: static
,直到达到给定的偏移阈值为止,在这种情况下,它的作用就好像该值是fixed
。 换句话说,通过采用position: sticky
我们可以在没有JavaScript的情况下解决上一部分中讨论的问题。
回顾前面的示例,并使用此新值,我们可以编写:
.menu {
margin: 0;
padding: 0;
width: 100%;
background-color: #bffff3;
position: sticky;
}
浏览器将完成其余工作! 就这么简单。
浏览器支持和Polyfill
目前,对该新值的支持还很差。 以下是每种浏览器的堆叠方式:
- Firefox 26+ –通过在
about:config
下将css.sticky.enabled
设置为“ true”来支持。 - Chrome 23+ –通过启用
chrome://flags
“实验性Web平台功能”来支持。 - Chrome 38(?)– Chrome团队最近从Blink中删除了此功能 ,因此即使在带有标志的情况下,Chrome Canary(版本38.x)目前仍不可用。 您可以阅读解释此删除操作的错误报告 ,但我们怀疑该功能将在短期内重新实现,并且稳定版本的支持可能不会受到干扰。
- Safari 6.1+ –在值上使用
-webkit
供应商前缀来支持(即position: -webkit-sticky
) - Opera 23+ –通过在
about:flags
启用“实验性Web平台功能”来支持。 - Internet Explorer –不支持( 请参阅状态 )
请参阅位置:在“我可以使用...”上保留所有详细信息。
幸运的是,有多种填充料可供选择:
- 由Filament Group 固定粘贴 (需要jQuery)
- 位置-粘性-由Matthew Phillips(使用Modernizr进行检测)
- 位置:sticky ,是Philip Walton的Polyfill.js库的一部分
- 位置: Fabrice Weinberg的粘性CodePen演示 (需要jQuery)
- Stickyfill由奥列格Korsunsky(IE9 +)
演示版
以下演示显示了position: sticky
实际应用。 如前所述,要查看其工作情况,并取决于所使用的浏览器,您需要激活一个标志。
请参阅CodePen上SitePoint ( @SitePoint )的Pen 位置:粘滞(纯CSS版本) 。
结论
尽管该新功能没有很好的浏览器支持,并且您可能不愿意进行填充,但是如果您使用Modernizr定义其他样式,它将优雅地降级到默认position: static
或position: fixed
。
如果您已经尝试过使用此属性,或者知道其他任何填充,请在评论中告诉我们。
翻译自: https://www.sitepoint.com/css-position-sticky-introduction-polyfills/
css粘性布局