纯CSS实现标题栏、表格头水平滚动垂直不滚动

这篇文章发布于 2021年06月14日,星期一,20:44,归类于 CSS相关。 阅读 15709 次, 今日 2 次 9 条评论

 

滚动鑫空间粘性定位占位图

一、需求描述

有些报表会很宽,浏览器水平放不下,需要水平滚动显示,这个可以设置overflow-y:hidden实现,很基本的实现,没什么难度。

但是,如果同时希望垂直滚动的时候,表格头是固定的。此时该如何实现呢?

此时,使用传统的position:fixed定位是不行的,因为此时水平滚动也会纹丝不动。

此时可以试试position:sticky粘性定位试试。

二、粘性定位实现

先看下实现的效果:

实现效果截图示意

眼见为实,您可以狠狠地点击这里:sticky定位实现水平滚动垂直不滚动demo

如果demo不方便点击,也可以试试点击下面的视频看看效果。

实现的原理其实挺简单的:

  1. 使用同一个滚动容器;
  2. 导航元素设置如下CSS属性:
    .header {
        position: sticky;
        top: 0;
    }

实现的关键点就在于,只设置top:0,而不设置left:0,否则导航元素水平滚动也会被固定住。

完整CSS代码参见demo。

三、表格头同样支持

如果是<table>表格,同样可以实现类似的效果。

需要注意的是,position:sticky粘性定位设置在tr或者thead标签上是没有效果的,所幸设置在th标签上是可以的,因此,如果希望表格头水平滚动,垂直不滚动,可以使用下面的CSS代码:

th {
    position: sticky;
    top: 0;
}

有demo,您可以狠狠地点击这里:sticky定位支持表格头demo

大致效果如下截图所示(UI比较粗糙):

表格头固定效果截图

四、滚动嵌套也是一种选择

就是水平滚动和垂直滚动通过嵌套实现,这个效果的局限比较大,需要对HTML类型和结构有要求,以及比较适合移动端,或者需要隐藏滚动条的场景。

假设HTML如下:

<div class="box-1">
    <div class="box-2">
        <div class="header">
            <nav>导航1</nav>
            <nav>导航2</nav>
            <nav>导航3</nav>
        </div>
        <div class="content">
            <img src="1.jpg">
            <img src="1.jpg">
            <img src="1.jpg">
        </div>
    </div>
</div>

CSS是这样的:

.box-1 {
    max-width: 600px;
    overflow-y: hidden;
}
.box-2 {
    display: inline-table;
}
.header {
    display: flex;
}
.header nav {
    flex: auto;
    background: #333;
    color: #fff;
}
.content {
    height: 200px;
    overflow: auto;
    white-space: nowrap;
}

就可以有下面截图所示的效果:

滚动嵌套想示意

眼见为实,您可以狠狠地点击这里:通过嵌套实现水平滚动垂直不滚动demo

如果宽度已知

如果宽度已知,还可以利用绝对定位元素的包含块规则,实现水平滚动,垂直不滚动的效果。

HTML结构同上,CSS这里发生变化:

.box-1 {
    max-width: 600px;
    overflow-y: hidden;
    position: relative;
}
.box-2 {
    width: 800px; height: 200px;
    overflow: auto;
}
.header {
    display: flex;
    position: absolute;
    width: inherit;
}
.header nav {
    flex: auto;
    background: #333;
    color: #fff;
    border: 1px solid;
}

功能实现的关键就是上面代码的红色部分,同样的,有demo。

您可以狠狠地点击这里:嵌套和绝对定位实现单向滚动demo

垂直滚动固定定位,水平滚动跟随效果示意图如下:

绝对定位与滚动处理

嵌套实现最大的问题在于滚动条的位置,因此,适合用在不需要显示滚动条的场景,例如移动端。

五、端午节快乐

总的来说,最好的方法还是使用position:sticky粘性定位实现。

关于粘性定位,如果还不太了解,可以参见我之前“杀了个回马枪,还是说说position:sticky吧”这篇文章,定位原理可以参见“深入理解position sticky粘性定位的计算规则”这篇文章(此文有一定的理解门槛)。

本文内容就这么多,感谢您的阅读。

今天是端午节,祝大家端午节快乐!

(本篇完)

分享到:


发表评论(目前9 条评论)

  1. huaweip30说道:

    现在的兼容性不太好,我在项目中试过了

  2. hoythan说道:

    大部分的框架都是使用两个 table 实现的,一个负责 thead 一个负责 tbody 并用 js 保证两个 table 宽度一样.

    张老师提供的这个方法很好,但是咋说呢,基本没有这样简单的需求.

  3. liyongleihf2006说道:

    旭神
    “position:sticky粘性定位设置在tr或者thead标签上是没有效果的”
    我的机器上面在tr和thead上面都有效果
    我用的
    windows 10 64位
    intel i7-1075H
    Google Chrome
    版本 91.0.4472.114(正式版本) (64 位)

  4. Redon说道:

    不差这点流量啊,把图片放完整啊~

    之前为了兼容性的问题,都是用双 table 来实现。

  5. 大羿说道:

    在火狐上有个问题,sticky元素的right:0的条件下,当元素滚动到最右侧,sticky元素会盖住其他元素

    在其他元素上就没有这个问题

  6. admin说道:

    兼容性的事旭哥是一个字不提啊,哈哈。。。55

  7. mfk说道:

    sticky+table那个,垂直滚动时,表头的上下边框不见了。