壹 ❀ 引

故事的起因是这样的,某一个同事在封装了一个TableList组件,用于做表格视图渲染,但出于研发经验考虑上,他可能觉得表格若出滚动条可能会引发某些不可预估的小问题(毕竟一个基础组件会被用于很多地方),省掉滚动条也避免很多宽度不够的适配问题,于是选择了暴力做法,直接在组件样式中隐藏了双向滚动条...

// 滚动条有两个方向,width隐藏纵向,height隐藏横向
.scrollbar::-webkit-scrollbar {
width: 0;
height: 0;
}

但事实上对于纵向都还好,用户能感知到有内容被页面遮住了,即便看不到滚动条,也可以利用鼠标滚轮控制上下滚动。可是鼠标又不能横向滚动,这让没触摸板的PC用户怎么玩?于是就有客户提单,说XX页面的XX功能横向缺少滚动条无法滚动(鼠标没滚动条拖动),内容看不全。看似挺简单的问题,引发了一系列的坑,以及触碰到了我对于滚动条的知识盲区,那么本文做个简单的记录。

贰 ❀ 隐藏的滚动条如何恢复默认

我将通过一个例子来演示这个过程,比如下面这段代码展示了一个滚动条被隐藏的表格,因为我电脑有触摸板,所以还是可以通过手势进行拖拽:

<div id="test" class="scroll">
<table border="1">
<tr>
<th>Month</th>
<th>Savings</th>
<th>User</th>
</tr>
<tr>
<td>January</td>
<td>$100</td>
<td>Echo</td>
</tr>
</table>
</div>
#test::-webkit-scrollbar {
width: 0;
height: 0;
}
div.scroll {
margin: 20px auto;
height: 100px;
width: 130px;
overflow: auto;
}

既然滚动条是因为宽高都没了,那我让这个样式不生效不就好了,直接复写样式进行覆盖:

#test::-webkit-scrollbar {
width: unset;
height: unset;
}

刷新页面,然后让我产生了两个疑惑点,第一,滚动条并未出现,第二,样式怎么没有覆盖的痕迹:

正常来说,样式覆盖是会有中划线表示这条样式没起作用,比如我们覆盖宽度,你会发现生效的样式在上,被覆盖的样式被划掉了

难道用unset不行?或者权重不够?带着疑惑我将unset替换成具体的数值,升值在后面加上了!important

#test::-webkit-scrollbar {
width: 12px !important;
height: 12px !important;
}

刷新页面,滚动条依旧没出现,样式也没有出现中划线,这下确实是有点触碰我知识盲区了,毕竟以前大部分场景都是做隐藏滚动条的活,这下来个还原滚动条的操作居然把我整不会了...

带着疑惑我去问了下前端大佬,毕竟他阿里8年开发经验,我想着总比我见多识广,结果他又把我想到的可能性又重试了一遍,然后一脸疑惑的看着我,也蒙圈了....然后他说了一句我非常认可以及极有帮助的话,当你对一个问题非常疑惑的时候,那说明你不够了解它,这时候你就应该去补充对应的知识,而不是继续盲目的尝试。于是我打开了::-webkit-scrollbar的MDN,也了解到除了能让滚动条隐藏外,其实还有定义滚动条滑块,滚动轨道等等滚动条属性:

  • ::-webkit-scrollbar — 整个滚动条.
  • ::-webkit-scrollbar-button — 滚动条上的按钮 (上下箭头).
  • ::-webkit-scrollbar-thumb — 滚动条上的滚动滑块.
  • ::-webkit-scrollbar-track — 滚动条轨道.
  • ::-webkit-scrollbar-track-piece — 滚动条没有滑块的轨道部分.
  • ::-webkit-scrollbar-corner — 当同时有垂直滚动条和水平滚动条时交汇的部分.
  • ::-webkit-resizer — 某些元素的corner部分的部分样式(例:textarea的可拖动按钮).

处于好奇,我在样式中又添加了如下样式:

// 为滚动滑块添加背景色
#test::-webkit-scrollbar-thumb{
background-color: #e4393c;
}

奇迹出现了,现在多了一个红色的滑动块,我们可以拖动滚动条了,我突然恍然大悟!!在我设置unset时会不会滚动条其实存在了,但它无色无形我才没能感知到它的存在。

于是我去除了滑动块的颜色,查看了DOM结构,发现确实有滚动条的站位,尝试拖动,果然存在。那么现在我们可以得出两条结论:

  1. 滚动条一旦被隐藏,复原时需要重写它所有的属性样式,不然它会有站位但不可见。
  2. 我们前面的unset样式覆盖其实有生效,滚动条样式覆盖很特殊,它不会有删除线。

结论虽然有了,但仍然不符合我的预期,我是希望取消隐藏后滚动条自己就恢复默认,但现在很明显我得把所有样式都复写一遍,这是我不愿意做的,当然到这里也要说一句,千万不要在一个高度复用的基础组件中写这种不可逆转的样式,真的很折磨人!!

叁 ❀ 让隐藏滚动条成为组件的可选配置

由于复写滚动条样式过于麻烦,这里我不得不想想其它更优的做法,此时脑袋中就蹦出了选择器:not(),由于组件是嵌入在一个个不同页面的,所以不同页面总会有一些特化的class,于是我就想到通过特化class配合:not()来让此页面的组件不要生效滚动条。但我有很长一段时间没写样式了,所以对于not选择器居然有点陌生,这里做个简单复习:

<ul>
<li class="new">1</li>
<li>2</li>
<li>3</li>
</ul>
li:not(.new) {
color: orange;
}

这应该是一个最基础的not选择器例子了,从li开始选择,但是不包括classnewli,所以除了1之外,其余都是橘色。

我们来看第二个例子,可能这个例子会轻量颠覆你对于此选择器的认知:

<body>
<p>我是p标签</p>
<span class="span">我是span标签</span>
</body>
:not(p){
color: #e4393c;
}

哎?奇了怪了,我们样式明明写的是除了p标签之外的所有元素颜色是红色,那为什么p元素也是红色,查看一眼控制台的样式属性,inherited from body,啥意思?p标签的颜色继承于body,也就是说样式确确实实是过滤了p,但是它会对p标签的父级body生效,而颜色是可以继承的,最终导致p继承了body的颜色。

假设我们给p额外定义一个不同的颜色,情况就符合预期了:

p{
color: orange;
}
:not(p){
color: #e4393c;
}

所以到这里你会发现,not用于解决同级元素(比如上面的为li过滤部分特殊的li)非常好用,但如果not用于过滤全局的部分元素,那你就得考虑样式继承带来的额外影响,而我在解决项目问题时,肯定不能用全局过滤,可行的肯定是利用同级class来过滤,结果看了一眼并没有什么特化的同级类型,于是我又陷入了沉思....

这个问题的根本原因,就是同事偷懒写了一个不可逆转的样式,那我何不将这个样式作为此组件的一个属性呢?考虑到这个组件在其它地方也有使用,所以修改思路是隐藏滚动条默认开关是true,而需要隐藏的地方在外层传递flase即可,而只有在开关是true时才会在这个组件上添加一个同名class,然后再在样式中结合not让不需要隐藏滚动条的地方不要生效,大概思路是:

// 组件定义处
className={classnames("table-list", { 'show-scroll-bar': this.props.isShowScrollBar })} // 使用组件的地方
<Component isShowScrollBar> //样式部分,有show-scroll-bar这个class的table组件不会隐藏滚动条
.table-list:not(.show-scroll-bar) {...}

那么到这里,我们既没有影响现有组件在其它页面的表现,也没有很麻烦的复写滚动条默认样式,同时也为组件增加了一个开启和关闭隐藏滚动条的自选配置,一举多得,此问题就告一段落了。

肆 ❀ 总

其实单站在解决问题的角度,暴力复写其实早就解决了,只是在追求一个更小影响更巨接受度的做法上,对方案进行了多次探索与推翻。所以明明是一个样式问题,但由于我对于滚动条的陌生以及部分基础知识的遗忘,这个问题我足足玩了一天....

但事实上,我们在定义一个基础组件时,确实不应该在组件内部定义一些外部很难复写的样式,或者很难扭转的逻辑,这会很让后续的开发异常头疼,当然我猜测,写这块的作者估计也不会想到滚动条复原会如此麻烦。

杂记 ❀ 迫于无奈,我吃了别人女友点的外卖

分享一个今天让我啼笑皆非的故事。由于今晚公司有一个大版本需要发布,所有研发都需要待命,所以晚6点的时候我点了一份外卖。因为疫情影响,外卖是没办法送上楼的,大楼物业也是在楼下安置了按楼层划分的桌子用于放外卖。考虑到晚上点外卖的人并不多,所以我也是不慌不忙等了好一会才下去取,当走到桌子前我傻眼了,9-15楼的桌子上一共三份外卖,反反复复看了四遍,确认过眼神,我是外卖被偷的人!!

但我又考虑到可能是外卖小哥放错了,于是立马给小哥打了个电话,当小哥精确说出我所点的外卖店家名称后,我确信他没放错,外卖确实是被人拿走了。小哥说让我等等,等他回来确认下再找大楼调监控,我想着也就20块钱的事,就不用那么麻烦了,大家都是打工人也第都不容易,赔偿就不用了,只是今晚,这个世界多了一个饿肚子的人。

当我走进电梯后来了一个陌生电话,我原以为是外卖小哥打过来告诉我外卖真的放错了,不禁内心狂喜!!!接通后,对方就是那个拿错外卖并已经吃完的人....他说他跟我同姓,然后我和他的公司只相隔一层,所以我俩的外卖在同一个桌子,晚上他也没多想,看到姓氏正确就拿上去吃掉了,吃完了才发现吃错了外卖,跟我道歉的同时表示要赔偿我,并把他的外卖给我吃。我说赔偿就不必了,把你的饭给我吃就行;他让我在15楼等会,出于歉意,他会帮我送上来。

电话挂断后我心里一想,不对啊,自己点的外卖自己难道不清楚吗,怎么吃完才发现,这什么脑回路...但又一想到有饭吃就行了,不管那么多了,等了一会后,电话另一头的人真的送外卖上来了,他说他的外卖是他女朋友帮他点的,所以其实他也不知道具体点的什么,吃完了才发现号码不对。我接过外卖一看,我自己点的拌饭,他女朋友给他点的也是拌饭,只是店家不同,而且我俩一个姓,拿错也确实情有可原了。

迫于无奈,我吃了她女朋友点给他的外卖,但不得不说,45一顿的外卖还真就比20一顿的要香!虽然吃外卖的时候,被迫还吃了一顿狗粮。

PS:封面原图地址

【CSS】如何复原被隐藏的滚动条?记一个看似简单的样式问题所引发的一系列思考的更多相关文章

  1. 使用CSS隐藏元素滚动条

    如何隐藏滚动条,同时仍然可以在任何元素上滚动? 首先,如果需要隐藏滚动条并在内容溢出时显示滚动条,只需要设置overflow:auto样式即可.想要完全隐藏滚动条只需设置overflow:hidden ...

  2. CSS字体渐变 & 隐藏浏览器滚动条 & grid布局(转载)

    字体渐变  https://www.zhangxinxu.com/study/201104/css3-text-gradient-2.html 隐藏浏览器滚动条  https://blog.csdn. ...

  3. 移动端隐藏scroll滚动条::-webkit-scrollbar

    ::-webkit-scrollbar {/*隐藏滚轮*/ display: none; } CSS3自定义滚动条样式 -webkit-scrollbar 前言 webkit支持拥有overflow属 ...

  4. 小tip:CSS vw让overflow:auto页面滚动条出现时不跳动——张鑫旭

    小tip:CSS vw让overflow:auto页面滚动条出现时不跳动 这篇文章发布于 2015年01月25日,星期日,23:08,归类于 css相关. 阅读 46274 次, 今日 91 次 by ...

  5. 隐藏jqgrid滚动条

    .ui-jqgrid .ui-jqgrid-bdiv{ overflow-x: hidden; } /* 隐藏jqgrid滚动条 */

  6. css超出多行隐藏

      单行隐藏: overflow: hidden;/*超出部分隐藏*/ text-overflow:ellipsis;/* 超出部分显示省略号 */ white-space: nowrap;/*规定段 ...

  7. vue—你必须知道的 js数据类型 前端学习 CSS 居中 事件委托和this 让js调试更简单—console AMD && CMD 模式识别课程笔记(一) web攻击 web安全之XSS JSONP && CORS css 定位 react小结

    vue—你必须知道的   目录 更多总结 猛戳这里 属性与方法 语法 计算属性 特殊属性 vue 样式绑定 vue事件处理器 表单控件绑定 父子组件通信 过渡效果 vue经验总结 javascript ...

  8. WPF 自定义滚动条(ScrollView、ScrollBar)样式

    一.滚动条基本样式 本次修改Scrollview及ScrollBar滚动条样式是通过纯样式实现的.修改的内容包含滚动条的颜色,上下按钮的隐藏.另外添加了鼠标经过滚动条动画. style样式如下: &l ...

  9. 记一个社交APP的开发过程——基础架构选型(转自一位大哥)

    记一个社交APP的开发过程——基础架构选型 目录[-] 基本产品形态 技术选型 最近两周在忙于开发一个社交App,因为之前做过一点儿社交方面的东西,就被拉去做API后端了,一个人头一次完整的去搭这么一 ...

  10. 压缩网站的css和js,合并多个文件到一个文件

    压缩网站的css和js,合并多个文件到一个文件uglifyjs index.js html5shiv.min.js -o all.min.jsuglifycss index.min.css web.c ...

随机推荐

  1. SV 数据类型-3

    联合数组 在内存中分配的空间可以是不连续的 联合数组方法 数组的方法 数组使用推荐 结构体 枚举类型 字符串变量类型String 操作符

  2. SQL函数——时间函数

    1.使用 NOW() . CURDATE().CURTIME() 获取当前时间 在这里我有一个问题想问问大家,你们平时都是怎么样子获取时间的呢?是不是通过手表.手机.电脑等设备了解到的,那么你们有没有 ...

  3. [转帖]idea配置tomcat参数,防止nvarchar保存韩文、俄文、日文等乱码

    描述下我的场景: 数据库服务器在远程机器上,数据库使用的Oracle,字符集是ZHS16GBK,但保存韩文.俄文.日文等字段A的数据类型是nvarchar(120),而nvarchar使用的是Unic ...

  4. [转帖]002、体系结构之TiDB Server

    TiDB Server 1.TiDB总览 1.1.TiDB Server架构 1.2.TiDB Server 主要功能: 2.SQL语句处理 语句的解析和编译 SQL层 协议层 上下文 解析层 逻辑优 ...

  5. [转帖]配置ftp连接对象存储bucket子目录的方法

    https://developer.jdcloud.com/article/1838 配置ftp连接对象存储bucket子目录的方法  京东云技术交付部  2021-01-27 IP归属:未知 441 ...

  6. [转帖]【jmeter】BeanShell用法详细汇总

    一.什么是Bean Shell BeanShell是用Java写成的,一个小型的.免费的.可以下载的.嵌入式的Java源代码解释器,具有对象脚本语言特性,非常精简的解释器jar文件大小为175k. B ...

  7. [转帖]Innodb存储引擎-idb文件格式解析

    文章目录 ibd 文件格式解析 idb文件 page类型和格式(File Header & Trailer) FIL_PAGE_TYPE_FSP_HDR 格式 Extent Descripto ...

  8. [转帖]Springboot容器化镜像设置堆内存大小

    参考资料:Best Practices: Java Memory Arguments for Containers - DZone Java 有三种方式设置最大堆内存大小: 1. -Xmx 2. -X ...

  9. CentOS7 RPM离线安装PG12的办法

    1. 先需要下载相应的rpm包 地址 https://pkgs.org/search/?q=postgresql12 一般至少要下载如下四个包 postgresql12-12.3-1PGDG.rhel ...

  10. [译]深入了解现代web浏览器(一)

    本文是根据Mariko Kosaka在谷歌开发者网站上的系列文章https://developer.chrome.com/blog/inside-browser-part1/ 翻译而来,共有四篇,该篇 ...