写点什么

[极致用户体验] 我又来帮掘金修专栏 bug 了,顺便教你个超牛逼的分割线 CSS!

作者:HullQin
  • 2022 年 8 月 25 日
    广东
  • 本文字数:1893 字

    阅读完需:约 6 分钟

[极致用户体验] 我又来帮掘金修专栏bug了,顺便教你个超牛逼的分割线CSS!

我是 HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,发送加微信,交个朋友),转发本文前需获得作者 HullQin 授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋等游戏,不收费没广告。还独立开发了《合成大西瓜重制版》。还开发了《Dice Crush》参加 Game Jam 2022。喜欢可以关注我 HullQin 噢~我有空了会分享做游戏的相关技术。

掘金专栏页面

你先进入一个用户的专栏列表,比如:HullQin 的专栏 - 掘金。展示如下图所示:



发现不对劲了吗?放大看!



它的底部有一条分割线,跟整个白色背景卡片的底部紧挨着,强迫症属实不能忍!


这不像是设计师给出的设计稿。这个结果,更像是前端开发者的一种妥协的实现方案(看完下一节,你就知道原因了)。虽然我们掘金用户拿不到设计稿,但是不妨假设这里跟设计稿不符,姑且称之为一个样式 bug 吧。

导致 bug 的原因

我们检查一下 dom,这条线是怎么实现的?



哦吼,原来是写在这个 div 的 border-bottom 里面。


看到 data-v 这个标签,我们不妨大胆假设掘金是用 Vue 框架开发的。


而每个掘金专栏的 html 都长得很像,不妨大胆假设每一个掘金专栏都是一个 Vue 组件。


因为掘金的前端开发者把「一个专栏」封装成了组件,所以每个组件都必须长得一样。而且开发者也没有开发这种逻辑:判断是最后一个专栏,就把 border 样式删掉。就导致出现了这个结果。


可能是没人注意到,或者 bug 不严重,就直接发布上线了。


为什么我开头说这是前端开发者的一种妥协的实现方案呢?因为加判断逻辑,还挺麻烦的,而产品可能也没有明确要求你这么做,前端开发者就没加这个逻辑。这样省下了一点点时间去做别的更重要的需求。

直接解决方案

  1. 我们需要给这个「一个专栏」组件增加一个输入参数,告知你是否需要底部的分割线。默认是需要分割线的。如果传入参数不需要分割线,则用border-bottom: 0覆盖border-bottom的样式。

  2. 这种循环展示同一个组件的情况,通常都是用 v-for 实现的。我们只需要在写 v-for 时,判断一下是否时最后一个 item,如果是最后一个 item,就把上述参数设置为不需要分割线,即可。


当然,以上只是针对掘金现有的技术实现,提出的最快的解决方案。其实,这种实现不太合适,我们还杂糅了 js 逻辑到 css 判断里。而这些 css 其实是可以在内部闭环的,不必依赖 JS,如果能解藕 JS 和 css,通常被认为是更优的实现方案。

更优的实现方式

如果让你实现专栏的分割线,你会有哪些实现方式?

css 伪类选择器

针对列表项目的子元素,设置样式border-top


再通过:first-child:nth-child(1)选中第一个子元素,给它设置样式border-top: 0


这样即可保证:相邻的元素之间有一条分割线,但是整体元素的顶部和底部是没有分割线的,这两个地方可以视需求额外添加分割线(组件放在不同的地方,外部分割线的长度或粗细可能不同,所以通常不会把这个的实现放进组件里)。

* + *这个牛逼的 css 选择器

解释一下:+在 css 选择器中,表示选择相邻兄弟结点。参考: Adjacent_sibling_combinator


比如每个专栏的 class 是column,我们用.column + .column即可自动排除第一个元素!比上一种方式更简洁!我也更推荐!效果如下:


代码片段

超牛逼的 css 选择器

上面的方法不太友好。


  • 这个样式必须写到.column + .column里面,也就是说它不够通用。如果想给其它列表用同样的分割线样式,必须把border-top: red 1px solid;这一行复制给其它的比如.xxx + .xxx里面。

  • 如果第一个列表项目被display: none隐藏掉了,那么就出岔了。因为第二个项目也会被+这个 css 选择器选中,导致出现了顶部的 border。如下:


代码片段


怎么解决呢?我们使用这种方法:


  1. 解决第一个问题,我们结合使用>这个选择子类的 css 选择器。参考: Child_combinator

  2. 解决第二个问题,我们使用~这个选择器和:not(hidden)这个伪类选择器。参考: General_sibling_combinator


不多解释了,直接上牛逼的代码!!!


.divide>:not([hidden])~:not([hidden]) {  border-top: blue 1px solid;}
复制代码


也就是说,我们只需要定义一个class,不妨叫做divide,那么divide的所有子元素之间,都会有一个分割线!并且完美解决了display: none带来的问题。


凡是你需要分割线的地方,只需要那些项目的父亲元素,定义一个class="divide"即可,分割线自动生成!!!Amazing!


代码片段

写在最后

我是 HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,发送加微信,交个朋友),转发本文前需获得作者 HullQin 授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋等游戏,不收费没广告。还独立开发了《合成大西瓜重制版》。还开发了《Dice Crush》参加 Game Jam 2022。喜欢可以关注我 HullQin 噢~我有空了会分享做游戏的相关技术。

发布于: 刚刚阅读数: 5
用户头像

HullQin

关注

公众号【线下聚会游戏】 2020.10.07 加入

game.hullqin.cn 我做了一些联机桌游网页:支持2-10人联机的UNO、2-4人联机的斗地主、2人联机的五子棋。无需下载,点开即玩!叫上朋友,即刻开局!不看广告,不做任务,享受「纯粹」的游戏!

评论

发布
暂无评论
[极致用户体验] 我又来帮掘金修专栏bug了,顺便教你个超牛逼的分割线CSS!_CSS_HullQin_InfoQ写作社区