代码优雅性反映出你的思维高度

简介: 代码优雅性反映出你的思维高度

我们常说,字如其人,而对于一个工程师,代码就是你专业形象的最好表达。养成一个良好的编码风格,至关重要。

而所谓良好的编码风格,实际上就是我们常说的 Readability(可读性),这在我们公司内部是有专门的培训和考核的,作用场景就是日常的CR(Code Review)。这块内容比较多,后面可以单开一个系列来讲,而今天主要还是介绍一些能让你的代码实现更优雅的前端编码小技巧。


选择器的艺术 01

选择器是学习CSS的第一课,属于非常基础的知识,但即便是工作多年的老前端,也不一定能玩通透,依然有很大一部分人对于“信手拈来”的选择器随意使用,不瞻前,不顾后,不做全局考虑,这就会引发一系列问题。

问题1:“这公共样式谁写的?把我样式都覆盖了!”

上述责问你肯定没少听过吧?是的,css选择器的全局性就是容易造成全局环境下的样式覆盖问题,尤其是一些公共样式的书写,如果肆意书写,很可能就会影响到具体页面内的样式。

解决方案:

step1. 基本样式(reset.css) 必须业务非相关,如color值,字体大小等,不允许定义。

step2.

全局样式(g.css)尽可能采用单层类选择器,在不十分确定的情况下,尽量不使用标签选择器。如下图,若是直接对标签p定义了颜色,那很可能会直接影响所有引用该全局样式的页面。

(页面内所有p标签都会变成白色

step3.

以组件,业务模块等粒度对样式进行抽离封装,并以统一命名规范进行命名,从而变相对样式进行虚拟的命名空间约束,达到“抵消css全局性”的功效,这里推荐采用BEM命名方式,如图:

无法抽离成组件和模块的样式,也可以用类似的方式,在具体页面内以“布局区域”来做粒度,对样式进行约束。

知识更新:

样式覆盖问题当年的确困扰了不少大型项目开发者,最根本的原因还是因为当时业界推崇“关注点分离”,在项目里将html,css,js分别进行充分的隔离和管理,避免所谓的“内联样式”的应用。但随着React和Vue等UI框架的普及,css-in-js的理念深入人心,由于其使用便捷性和天然的模块化管理,消除了开发者对此类问题的恐惧,只需要配合BEM规范,即可相对优雅的管理好项目的样式。


问题2:“这样式权重太大了,不好覆盖啊!” “谁写的important,太坑了吧!”

嗯……看语气就知道了,每次遇到这种问题是很心烦的,css权重问题处理的不好,就会让前端疲于奔命的应付在你覆盖我来我覆盖你的道路上。。。尤其是遇到这种选择器,真的想死:

(截图来自百度糯米首页)

解决方案:

step1.

参考问题1,对css进行命名约束,对于一个组件ui-dialog,全局只能有一个;对于某页面内sec-banner,此页面内也只应该存在唯一一个叫做sec-banner的区域,以此类推。这样,我们就已经把某元素限定在了一个很小的范围内,在此范围内,你就可以肆无忌惮的命名而不用担心命名重复了。

用上图的反例来举吧,这个logo-item其实是位于一个叫“精选品牌”的楼层里,那么我们可以先把这个区域定为“selected-brand”,而这个区域内,logo-item这个类名基本就完全可以做到不冲突,唯一性,那么整个选择器就会是“.selected-brand .logo-item”,当然了,要按我的词汇量,我才不会叫什么logo-item,叫brand不是更好?因为如果叫brand,那这个div里如果还有图片啊,文字啊之类的,就可以采用BEM方式进行约束:brand__img,brand__title,而整体选择器权重就只有两层class,万一有皮肤定制的需求,覆盖起来也是分分钟的事儿对吧。

我们提炼一个方法论:在确保唯一性的前提下,尽可能缩减DOM层级和选择器层级

step2. 

不要轻易使用 !important 和 * 。!important的恶心之处我就不多说了吧,至于*的使用,确实不会增加太多权重,但是!*会让你的样式定义遍布全球每一个角落!这种一棍子打死的选择器使用方式,正常人干不出这种事儿!当然了,存在即合理,并不是说哪儿都不能用,我说的是不要轻易用,除非你很清楚你在干嘛。


问题3:“咦?这样式咋被划掉了?被定义了两遍?”

这次我拿自己的项目开涮,如图:

明显可以看出来,a标签其实已经在全局范围内定义了一个hover颜色,但是在具体业务页面里又定义了一次,当然了,我可以解释其实这里是历史遗留,所以呢?历史遗留问题不应该清理一下?

解决方案:

在写样式的时候,要充分利用样式继承(当然了前提是你能hold住这个样式而不被反覆盖),避免重复定义样式。继承用得好,是可以减少好多工作量的喔~

上面几个问题,只是抛砖引玉,实际生产中,还有很多不优雅的选择器使用方式。

还是那句话,选择器很简单,但是要用好,真的不简单。技术不复杂,但需要融入很多的整体思考,大局观。


一些可以更优雅的场景 02


有很多场景,是我们经常会遇到的,这些场景总会给我们制造一些小麻烦,小困扰,每次我们都会直接针对性的hack掉就完了,实际上,只要我们多思考一点,就可以做得更优雅一些,形成一套可以随时复用的解决方案,就不用每次遇到都hack了。


场景1:子元素margin没有撑开父容器,但影响到相邻元素,从而影响距离计算。

这就是著名的BFC边距折叠问题,具体原理我就不阐述了,各位自行查资料。为什么要把这个问题拿出来说?因为在视觉还原要求较高(像素级还原)的团队,两个元素之间的距离是需要精确计算的。

举例如下图,父容器a其实没有margin,但子元素c的边距使得a与b之间产生了间距,这并不是我们预期的:

我们希望看到的标准输出应该如下图:

image.png

解决方案:

原理上就是要解决BFC折叠问题,一般来讲,我们可以用这两种方法解决,

1. 父元素添加overflow:hidden,但前提是该容器内没有需要“溢出容器”的内容,比如小箭头什么的。

2. 给父元素增加伪元素:after,并设置其display:table。其实就是我们平时说的“清除浮动clearfix”,当然原理并不是什么清除浮动,而是在相邻父子元素之间增加一个看不见的间隙,强制性阻止margin折叠。


场景2:<img>标签总会多那么1px空白。

解决方案:

这个经典问题的答案也是网上一搜一大堆,原理是img标签的特殊性(表现为块状元素的行内元素)导致其做垂直对齐时候会默认做基线对齐,而不是底部对齐,从而留出一些空白。

那照这个原理来讲,我们人为让img做底部对齐不就可以了?是的,设置verticle-align:bottom就能解决。

但是我在这里想分享另一个思路,img标签,最好使用一个父容器存放!好处如下:

  • 方便添加跳转链接。大部分有图的地方一定会有个链接或者交互动作。
  • 方便根据需求随时调整宽高。将图片100%撑满容器,调整容器宽高即可改变图片宽高。
  • 方便根据运营需求,随时切换为动态可配置图片。


  • 容器可以做占位,即使图片挂掉,布局也不会错乱,还可以设置默认背景图,优雅容灾。


将图片放入容器后,设置display:block即可解决1px空白问题。更重要的是,我们不仅仅解决了1个问题,还拥有了一套更加优雅的,可以应对各种复杂问题的图片解决方案,岂不更好?


场景3:弹窗垂直居中(泛指需要居中在整个视窗中间的绝对定位元素)

解决方案:

移动端强烈推荐使用translate(-50%,-50%)搞定,方便简单无副作用。

PC端就比较蛋疼一点,若是元素宽高固定,那传统做法使用负值margin就可以搞定,但宽高不固定呢?

给大家推荐一个非常好用的方法,给遮罩层加一个:afrer并设置其高度100%撑满容器,但由于其宽度为0所以其实不占位,然后将需要垂直居中的元素都设置为dislpay:inline-block从而将问题转换为行内元素如何垂直居中问题,如图:

image.png


       结语     03


次给大家分享的意义,其实不在于说你能学到几个解决实际问题的方法和技巧,更重要的是学到一种思维方式,即培养一种全局思维,跳出执行层面的局限性,更多的从整体收益来看待问题

代码行中悟真知,优雅的解决问题,会让你的思维高度提升一大个层级!


目录
相关文章
|
SQL NoSQL 数据库
Cassandra数据库与Cql实战笔记
Cassandra数据库与Cql实战笔记
218 1
Cassandra数据库与Cql实战笔记
|
机器学习/深度学习 自然语言处理 监控
探索深度学习在自然语言处理中的应用与挑战
本文深入分析了深度学习技术在自然语言处理(NLP)领域的应用,并探讨了当前面临的主要挑战。通过案例研究,展示了如何利用神经网络模型解决文本分类、情感分析、机器翻译等任务。同时,文章也指出了数据稀疏性、模型泛化能力以及计算资源消耗等问题,并对未来的发展趋势进行了展望。
|
运维 持续交付 开发工具
基础设施即代码(IaC):自动化基础设施管理的未来
基础设施即代码(IaC):自动化基础设施管理的未来
514 0
|
传感器 算法 安全
蓝牙中频率跳变技术的原理及其应用
蓝牙中频率跳变技术的原理及其应用
1065 9
|
监控 安全 智能硬件
智能家居技术入门:从小白到专家
在这篇文章中,我们将一起探索智能家居技术的奥秘。无论你是刚刚接触到这个领域的新手,还是已经有一定了解但希望更深入了解的中级用户,这篇文章都将为你提供有价值的信息和指导。我们将从智能家居的基本概念开始,逐步深入到如何选择设备、设置系统,以及如何利用这些技术来提高生活质量。让我们一同踏上这段旅程,解锁智能家居的无限可能吧!
Flutter 状态管理新境界:多Provider并行驱动UI
Flutter 状态管理新境界:多Provider并行驱动UI
266 0
|
前端开发 Java
SpringBoot导入和导出Csv文件(二十八)下
SpringBoot导入和导出Csv文件(二十八)下
2965 0
SpringBoot导入和导出Csv文件(二十八)下
|
运维 安全 网络架构
【专栏】NAT技术是连接私有网络与互联网的关键,缓解IPv4地址短缺,增强安全性和管理性
【4月更文挑战第28天】NAT技术是连接私有网络与互联网的关键,缓解IPv4地址短缺,增强安全性和管理性。本文阐述了五大NAT类型:全锥形NAT(安全低,利于P2P)、限制锥形NAT(增加安全性)、端口限制锥形NAT(更安全,可能影响协议)、对称NAT(高安全,可能导致兼容性问题)和动态NAT(公网IP有限时适用)。选择NAT类型需考虑安全性、通信模式、IP地址数量和设备兼容性,以确保网络高效、安全运行。
1646 1
|
存储 缓存 安全
【C/C++ 关键字 存储类说明符】C/C++ 的mutable 关键字 忽略对该数据成员的常量性检查在const函数中修改变量值
【C/C++ 关键字 存储类说明符】C/C++ 的mutable 关键字 忽略对该数据成员的常量性检查在const函数中修改变量值
227 0
|
JavaScript jenkins 持续交付
Jenkins自动构建 CI/CD流水线学习笔记(从入门到入土,理论+示例)
Jenkins自动构建 CI/CD流水线学习笔记(从入门到入土,理论+示例)
602 0