sticky粘性布局

sticky是何物

sticky是CSS3样式中position属性的一个值。

众所周知,position通用的值有:relatvive, fixed, static, inherit值,其作用在w3shool中的介绍如下:

img

我大w2school都没有这个值,那么问题来了,sticky到底是不是position家的?

事实上,sticky确实是position家的,只不过刚出来没多久,还在试行阶段,并不被W3C推荐,因此还没有昭告天下。

sticky有何用

我们先上caniuse查明一下:

img

左上角的解释如是说道:

Keeps elements positioned as “fixed” or “relative” depending on how it appears in the viewport. As a result the element is “stuck” when necessary while scrolling.

大意是其作用是fixedrelative的合体,既能像fixed一样,恒悬浮在窗口的指定位置,又能像relative一样,具有文档流布局能力。

这简直是为移动端轻应用开发而生,因为这个场景在移动端使用太频繁。比如电商类APP就往往需要随着页面的滚动而动态固定头部的搜索框。

以往我们开发这样的功能可能需要写很多代码,而如果用这个属性可能只需要两三行CSS代码就搞定了,简直是程序猿的春天。

不过别急,上图的大片红色/绿色区域是表示各类浏览器的支持情况,可以看到,目前大部分浏览器都是不支持的。

真是有一把火烧了各浏览器的冲动,这么好的功能竟然不支持,看着Android Browser那栏全是红的就觉得残忍,简直没有人性。

talk is cheap, 抱怨总是没用的。我们还是看看它能给我们解决什么问题。

这里显示iOS上支持比较好,而我们position的fixed属性在iOS上的支持简直是渣渣,原因是iOS在页面滚动时会停止一切js代码运行,而fixed的实现其实也是通过监听浏览器的onscroll方法更新元素位置,使之保持固定在窗口的指定位置,其效果与我们手动绑定onscroll方法更新元素的位置一样的,因此fixed在安卓上使用起来比在iOS上流畅多了,而iOS渣了一地。

至少我们找到了可以解决的方法,我们可以js判断运行环境是iOS还是安卓,动态的设置position的属性,在安卓上用fixed,在iOS上用sticky,这个代码比较简单,略。

实际上我们可以更准确一点,直接判断浏览器是否支持这个属性:

function isSupportSticky() {
    var prefixTestList = ['', '-webkit-', '-ms-', '-moz-', '-o-'];
    var stickyText = '';
    for (var i = 0; i < prefixTestList.length; i++ ) {
        stickyText += 'position:' + prefixTestList[i] + 'sticky;';
    }
    // 创建一个dom来检查
    var div = document.createElement('div');
    var body = document.body;
    div.style.cssText = 'display:none;' + stickyText;
    body.appendChild(div);
    var isSupport = /sticky/i.test(window.getComputedStyle(div).position);
    body.removeChild(div);
    div = null;
    return isSupport;
}

通过临时创建一个dom元素,并设置该元素的position:sticky属性,在浏览器计算后的样式中是否有改属性。

拥有这个大法,做到全平台超流畅粘性布局,赢取白富美指日可待了。

参考例子

sticky的使用条件

  • 与fixed类似,元素的偏移属性left,right,top,bottom至少要有一个有值。而且top和bottom同时设置时,优先对标top,left和right同理,left优先。

  • sticky元素的高度/宽度要小于滚动根元素的高度/宽度,也就是说,如果sticky元素比滚动区域还要大,是不生效的。

另外还有一些条件,请直接移步这里吧.

本文的很多知识点也是来自于这位大侠的blog。

总之,sticky的使用环境还是比较苛刻的。

但是我们程序员总是以解决问题为乐。

Table of Contents