你真的会使用css滚动条吗

1,129 阅读3分钟

背景

在开发时,UI给了这样一张设计图,横向滚动条在滚动模块外部。

我内心os

研究了好久的滚动条,最后终于搞定了。接下来我们就看下如何实现这种设计。

首先,我们先来学习下 css 中关于滚动条的知识。

css滚动条基本知识

一、滚动条出现的位置

如下图所示,滚动条出现在 content + padding 部分,border 和 margin 是没有滚动条的。

二、css滚动条选择器

  • ::-webkit-scrollbar——整个滚动条

        

  • ::-webkit-scrollbar-button —— 滚动条上的按钮(上下箭头)。

  • ::-webkit-scrollbar-thumb —— 滚动条上的滚动滑块。

  • ::-webkit-scrollbar-track —— 滚动条轨道。

  • ::-webkit-scrollbar-track-piece —— 滚动条没有滑块的轨道部分。

  • ::-webkit-scrollbar-corner —— 当同时有垂直滚动条和水平滚动条时交汇的部分。通常是浏览器窗口的右下角。

  • ::-webkit-resizer —— 出现在某些元素底角的可拖动调整大小的滑块。

【注】基本上只能更改颜色、边框等等,不能更改滚动条的大小、内边距、外边距等。

了解了基本知识,我们来想办法让横向滚动条置于滚动模块外部。

横向滚动条置于滚动模块外部的实现

首先,我们先直接使用滚动条实现,看看是什么效果:

<div class="outside-block scrollbar">   
    <div class="content"></div>   
    <div class="content"></div>   
    <div class="content"></div>   
    <div class="content"></div>   
    <div class="content"></div>
</div>

.outside-block {   
    margin: 0 auto;   
    width: 80%;   
    height: 400px;   
    overflow: auto;   
    border: 1px solid #898989;   
    border-radius: 10px;   
    display: flex;
}
.content {   
    height: 100%;   
    flex: 0 0 30%;
}
.content:not(:last-of-type) {   
    border-right: 1px solid #898989;
}
.scrollbar::-webkit-scrollbar {   
    height: 8px;   
    width: 8px;
}
.scrollbar::-webkit-scrollbar-thumb {   
    background-color: #d6d8dc;   
    border-radius: 4.5px;
}

效果如下,滚动条在模块内部。

怎么能让滚动条处于模块外部呢?

想法一:设置一个大的父 div,在内部再设置一个小的 div,内部小 div 存放内容并显示边框,并隐藏滚动条,滚动条由外部大的 div 来显示。但仔细想想,这种方法不可行,在滚动时边框不好控制(感兴趣的可以去试试)。

想法二:想到了“相框”。以前非主流年代的时候,相框的形状是多种多样的,相框是什么形状,显示的照片就是什么形状,那我们在内容之上盖一层具有弧度的蒙版,在滚动时岂不就还是弧形。如下图所示,蓝色边框实际为隐形边框,红色为覆盖在上面的蒙版。

具体实现:

<div class="outside-block">      
    <div class="mask"></div>      
    <div class="inside-block scrollbar">        
        <div class="content"><p>111</p></div>        
        <div class="content"><p>111</p></div>        
        <div class="content"><p>111</p></div>        
        <div class="content"><p>111</p></div>        
        <div class="content"><p>111</p></div>      
    </div>
</div>

.outside-block {        
    margin: 0 auto;        
    position: relative;        
    width: 80%;      
}      
.inside-block {        
    height: 420px;        
    position: relative;        
    overflow: auto;        
    display: flex;        
    border-radius: 10px;      
}      
.content {        
    width: 25%;        
    height: 400px;        
    flex: 0 0 auto;      
}      
.content:not(:last-of-type) {        
    border-right: 1px solid #898989;      
}      
.content p {        
    margin: 20px;      
}      
.scrollbar::-webkit-scrollbar {        
    height: 8px;        
    width: 8px;      
}      
.scrollbar::-webkit-scrollbar-thumb {        
    background-color: #d6d8dc;        
    border-radius: 4.5px;      
}      
.mask {        
    width: 100%;        
    height: 400px;            
    position: absolute;        
    top: 0;        
    left: 0;        
    border-radius: 10px;        
    border: 1px solid #eeeeee;        
    background-color: #fff;      
}

效果:

成功复现!当然要细究的话,还有一点点小细节不如人意,比如当 content 的边框刚好滚动到 mask 的右侧时,会有一点点的超出,但除非仔细看,否则是看不出来的,如果介意的话,可以通过设置 margin 来控制。

再次感慨:一定要牢记 css 盒子模型啊

参考: