音效素材网提供各类素材,打造精品素材网站!

站内导航 站长工具 投稿中心 手机访问

音效素材

纯CSS解决H5布局中的吸顶吸底的实现步骤
日期:2021-09-05 10:02:29   来源:脚本之家

哪些想啥提啥的产品们

最近做了一个需求,准确说是迭代需求:加了一个头部概览(类似下图),以更好的让用户观察到营销变化,故事的开头就这样悄悄的埋下了伏笔。

以前这个页面只是一个评价列表(可上拉加载),为了数据更易读,列表的头采用了固定布局。然而加了这个概览时,产品没提,我就简单粗暴的将这个列表头换成了相对布局,ok,提测。

纯CSS解决H5布局中的吸顶吸底的实现步骤

但第二天,我发现上拉加载数据多了,列表头部被顶上去之后,想再做筛选,就要再把列表上滑才能看到,这个体验非常之差。于是同事就说要不问问产品,要不把概览加概览做成固定。

我第一反应就是,恐怕提了之后,产品会让我 把筛选列表头部做成固定,注意那个只。

然后就有了下面的对话:

纯CSS解决H5布局中的吸顶吸底的实现步骤

果然怕什么,来什么。但就像同事说的,自己问的需求,含着泪也要接下。

后面经评论提点,又加入了sticky的方案,确实是最优解。

局部吸顶

以下代码是页面的 dom 结构

<div id="demo" className={style.demo}>
  <h3 id="title" className="title">这是一个概览头部</h3>
  <div id="content" className="content">
    <div className="filter-bar">
      <h3>这是列表头部</h3>
      <h3>可筛选</h3>
      <h3>下面是滚动列表</h3>
    </div>
    <ul className="list">
      {arr.map(({ key, label }) => <li key={key}>{label}</li>)}
    </ul>
  </div>
</div>

JS 实现

因为页面本身就有scroll事件监听,所以第一个念头是用JS完成,但当时已经下班,又是周五,感觉5分钟内搞不定,所以我就跑了。

现在来尝试用JS实现,先理一下思路:

  • 监听页面的滚动,当ul元素顶部距离页面顶部大于title 高度时,添加一个css类使筛选头部吸顶;
  • 当ul元素距离顶部小于等于title 高度时,删除添加的类,取消筛选头部吸顶

JS 代码

useEffect(() => {
  const demo = document.querySelector('#demo');
  const content = document.querySelector('#content');
  const titleHeight = document.querySelector('#title').clientHeight;
  let fixed = false;
  demo.addEventListener('scroll', (e) => {
    // 添加吸顶
    if (!fixed && e.target.scrollTop >= titleHeight) {
      fixed = true;
      content.classList.add('with-fixed');
    }
    // 取消吸顶
    if (fixed && e.target.scrollTop < titleHeight - 5) {
      content.classList.remove('with-fixed');
      fixed = false;
    }
  });
}, []);

看起也不难,但其实离代码上线,还有很大优化的空间,后面会分析补充。

CSS Viewport实现

JS 看似很简单,但就像那句热门句子: 这突如其来的噩耗,让本不富裕的家庭雪上加霜 。在这种有下拉加载的页面,我们本来就在监听里面做了很多逻辑处理,所以能用CSS实现的,就尽量不要再去麻烦JS了。

首先理一下思路,深挖产品的需求:

  • 保持筛选头在可视范围之内(吸顶), 保证可筛选;
  • 当列表数据多时,尽可能多展示列表,即概览头部就没必要看到了;
  • 列表是上拉加载的;

当理清上面思路时,我们发现,其实就是当列表很长时,隐藏概览头部,简单用伪代码表示就是(vh是视口单位 ,100vh代表整个屏幕可视高度):

 if (titleHeight + filterBarHeight + listHeight > 100vh) {
     title.hide();
   }

那又怎样实现概览头部隐藏,而筛选头和列表又正好出于视口呢?

filterBarHeight + listHeight = 100vh

当用户往上划,只需要内容(筛选头和列表)正好是一个视口高度(100vh)时,概览头就恰好被隐藏,而筛选头又正好吸顶,用CSS实现就是类似这样的:

// 不是完整代码,详情请看demo:
.demo {
 :global {
   .title {
     height: 15vh;
     line-height: 15vh;
     text-align: center;
     border-bottom: 1PX solid #eee;
     background-color: #fff;
   }
   .filter-bar {
     height: 15vw;
     background-color: #888;
     display: flex;
     align-items: center;
   }
   .list {
     max-height: calc(100vh - 15vw);; // 这里的设置很重要
     overflow: scroll;
     background-color: rgba(127, 255, 212, .8);
   }

最优实现 CSS Sticky

在css中的定位( position )属性值中有个不常用的: sticky

MDN官方文档摘录 :

元素根据正常文档流进行定位,然后相对它的最近滚动祖先和最近块级祖先,包括table-related元素,基于top, right, bottom, 和 left的值进行偏移。粘性定位可以被认为是相对定位和固定定位的混合。元素在跨越特定阈值前为相对定位,之后为固定定位。

这里我们在沿用JS的方案上进行更改,只需要将filter-bar 的定位属性改为粘性定位,就可以去除对 JS 的依赖;

.demo {
  max-height: 100%;
  overflow: scroll;
  .filter-bar {
    position: sticky;
    top: 0;
  }
}

demo类作用于最外层dom( <div className={style.demo}> )上,其视高为100vh,当内容超出高度时为滚动;filter-bar 元素采用粘性定位,当高度距离demo元素大于0时,其采用相对定位,即以正常文档流的形式定位;当高度小于等于0时,其采用固定定位,就达到吸顶的效果。

对比

是不是感觉CSS很简单,稍微设置一下即搞定,只是要想到内容高度正好是 100vh 需要一点经(yun)验(qi),经常写H5的,sticky的方案相信也是新手黏来。其实不光简便,对比JS至少还有两个个优点:

  • JS 如果只是上面那样,直接将筛选头的定位改成固定定位,眼力好的人,其实是能感觉到列表有跳变的一瞬间,就是列表会突然上移filterBar高度,来填补筛选头离开正常文档流;(解决方案就是在筛选头外多套一层dom,并给一个固定高度,这样筛选头脱离正常文档流,但高度依旧还在);
  • 当用JS来操作Dom元素重排时,这每年面试官说的那些重绘重拍我就不多说了,这消耗的性能肯定高于CSS实现;

当然,viewport方案还有个ios手机的兼容性问题,由于safari的头部和底部滑动时可见性会改变,所以当Bar可见时,实际的100vh高于屏幕可见高度,就会导致吸顶头部被遮挡。到目前为止,虽然网上有很多说 height: -webkit-fill-available; ,但针对这种场景是无效的;但只要依赖100vh,都面临这种困局,safari太奇葩,下一个IE就是它了.

纯CSS解决H5布局中的吸顶吸底的实现步骤

经过上面分析,100vh在IOS safari上的致命问题,会让这种100vh这种纯CSS的方案褪色。但PC页面,或者你和我一样,要编写的页面是运行在APP中(即没有bar存在),那这种方案就是可行的。所有的方案都要具体场景,具体分析,没有谁出生就是完美。这里只是提高一种思考方式,长点见识。

而sticky方案不依赖于100vh,其可以用100%的写法,所以没有这个担忧,所以相比之下,最优解就是 sticky ; 但 height: 100% 是个无底洞,你需要从html 标签写起,一直写到具有滚动的容器元素。

弹性吸底

说完局部弹性吸顶,再说一个常见的,选择性吸底:在页面内容不足100vh时,我们希望 Footer 是吸底的,当页面内容大于100vh时, Footer 处于正常文档流,让内容可视区域更大,而又不会因为内容太少影响美观,见图:

纯CSS解决H5布局中的吸顶吸底的实现步骤

像第一张图那样不做定位的还是大有人在,因为他们坚信自己网站的内容不会出现不够的时候,但以前更常见做法是底部固定定位。

弹性吸底利用 min-height 加绝对定位,其实现很简单。核心代码不超过5行css:

body{
  position: relative;
  min-height: 100vh;
}

footer {
  width: 100%;
  position: absolute;
  bottom: 0;
}

原理就是内容区域最低高度为一个屏幕,然后底部相对屏幕进行绝对定位;当内容变多时,高度大于100vh,由于是依赖 bottom: 0; ,所以会一直吸底,其巧妙之处就在于此。

针对于这个场景, height: -webkit-fill-available 就是有效的。

纯CSS解决H5布局中的吸顶吸底的实现步骤

到此这篇关于纯CSS解决H5布局中的吸顶吸底的实现步骤的文章就介绍到这了,更多相关CSS 吸顶吸底内容请搜索以前的文章或继续浏览下面的相关文章,希望大家以后多多支持!

    您感兴趣的教程

    在docker中安装mysql详解

    本篇文章主要介绍了在docker中安装mysql详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编...

    详解 安装 docker mysql

    win10中文输入法仅在桌面显示怎么办?

    win10中文输入法仅在桌面显示怎么办?

    win10系统使用搜狗,QQ输入法只有在显示桌面的时候才出来,在使用其他程序输入框里面却只能输入字母数字,win10中...

    win10 中文输入法

    一分钟掌握linux系统目录结构

    这篇文章主要介绍了linux系统目录结构,通过结构图和多张表格了解linux系统目录结构,感兴趣的小伙伴们可以参考一...

    结构 目录 系统 linux

    PHP程序员玩转Linux系列 Linux和Windows安装

    这篇文章主要为大家详细介绍了PHP程序员玩转Linux系列文章,Linux和Windows安装nginx教程,具有一定的参考价值,感兴趣...

    玩转 程序员 安装 系列 PHP

    win10怎么安装杜比音效Doby V4.1 win10安装杜

    第四代杜比®家庭影院®技术包含了一整套协同工作的技术,让PC 发出清晰的环绕声同时第四代杜比家庭影院技术...

    win10杜比音效

    纯CSS实现iOS风格打开关闭选择框功能

    这篇文章主要介绍了纯CSS实现iOS风格打开关闭选择框,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作...

    css ios c

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的办法

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的

    Win7给电脑C盘扩容的办法大家知道吗?当系统分区C盘空间不足时,就需要给它扩容了,如果不管,C盘没有足够的空间...

    Win7 C盘 扩容

    百度推广竞品词的投放策略

    SEM是基于关键词搜索的营销活动。作为推广人员,我们所做的工作,就是打理成千上万的关键词,关注它们的质量度...

    百度推广 竞品词

    Visual Studio Code(vscode) git的使用教程

    这篇文章主要介绍了详解Visual Studio Code(vscode) git的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...

    教程 Studio Visual Code git

    七牛云储存创始人分享七牛的创立故事与

    这篇文章主要介绍了七牛云储存创始人分享七牛的创立故事与对Go语言的应用,七牛选用Go语言这门新兴的编程语言进行...

    七牛 Go语言

    Win10预览版Mobile 10547即将发布 9月19日上午

    微软副总裁Gabriel Aul的Twitter透露了 Win10 Mobile预览版10536即将发布,他表示该版本已进入内部慢速版阶段,发布时间目...

    Win10 预览版

    HTML标签meta总结,HTML5 head meta 属性整理

    移动前端开发中添加一些webkit专属的HTML5头部标签,帮助浏览器更好解析HTML代码,更好地将移动web前端页面表现出来...

    移动端html5模拟长按事件的实现方法

    这篇文章主要介绍了移动端html5模拟长按事件的实现方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家...

    移动端 html5 长按

    HTML常用meta大全(推荐)

    这篇文章主要介绍了HTML常用meta大全(推荐),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参...

    cdr怎么把图片转换成位图? cdr图片转换为位图的教程

    cdr怎么把图片转换成位图? cdr图片转换为

    cdr怎么把图片转换成位图?cdr中插入的图片想要转换成位图,该怎么转换呢?下面我们就来看看cdr图片转换为位图的...

    cdr 图片 位图

    win10系统怎么录屏?win10系统自带录屏详细教程

    win10系统怎么录屏?win10系统自带录屏详细

    当我们是使用win10系统的时候,想要录制电脑上的画面,这时候有人会想到下个第三方软件,其实可以用电脑上的自带...

    win10 系统自带录屏 详细教程

    + 更多教程 +
    教程标签
    HTMLCSSDreamweaverFrontpage