整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

正在消失的霓虹灯:世界各地的艺术家们如何挽救霓虹文化

正在消失的霓虹灯:世界各地的艺术家们如何挽救霓虹文化

文 | 新京报记者 何安安 实习生 闫晓旭

霓虹灯师傅无徒可授,

行业陷入衰落危机

近日,很多香港的霓虹灯制作师表示担心霓虹灯这门艺术会渐渐失传。从前香港街道上的特色霓虹灯招牌渐渐被LED灯所代替。胡智楷师傅,是香港仅存的其中一位霓虹灯师傅,製作霓虹招牌已超过三十年。

胡智楷师傅接受新华网的采访时表示,自己17岁开始学习制作霓虹灯。而现在他把自己原来的工作室搬到了偏僻的葵涌工业大厦里,面积只有30几平米,对于制作霓虹灯来说显得有些拥挤。胡智楷这个月只接到了少数的订单。1957年入行的刘稳也是香港霓虹招牌制作师傅,也是胡智楷的同事,他说他担心这门手艺会失传。

霓虹灯师傅胡智楷,香港第二年轻的霓虹招牌师傅,但在目前仅存的十来位霓虹灯师傅中,大家都无徒可授。“和所有行业一样,如果生意兴隆,就会有新鲜血液,”胡智楷说,“如果没有人加入这个行业,那就是没有生意做。”

世界各地的霓虹灯招牌频频被拆除

1898年,苏格兰著名化学家威廉·拉姆齐爵士发现了一种抗液化的气体,这种气体被通电时,变成了鲜红色。他将这种气体命名为“霓虹”。在我国,1926年上海南京东路伊文思图书馆柜窗上出现我国第一个霓虹灯广告。1927年我国第一支霓虹灯由上海远东化学制造厂制成,用于上海中央大旅社。20世纪30年代我国霓虹灯逐步发展,到1949年全国约有三十多家霓虹灯厂。然而现在,霓虹灯却在渐渐退出人们的视野。

霓虹灯做成的广告牌是香港独特的文化风景线。重叠交错的霓虹灯宣告着香港的繁华与热闹。看着这些色彩明艳的霓虹灯,初次来香港观光的游客更能体会到大都市的夜是多么明亮。对于很多香港人来说,霓虹灯招牌不仅仅是一个做生意的招牌,它还蕴含了香港的日常消费与影视文化。王家卫导演的《重庆森林》与《堕落天使》中,霓虹灯对剧情发展,人物心理的塑造都有重要的作用。

香港西区一家牛排餐厅上挂着的巨型霓虹灯奶牛已经成了地标。这家餐厅叫做森美餐厅。制作霓虹灯招牌的师傅认为牛还是腿长一点好看,于是这个招牌变得非常独一无二,招牌中的安格斯牛成了世界上唯一一只长着四条长腿,颜色是蓝白色的牛。但是2011年,香港屋宇署认为这个招牌不安全,要将它拆掉。2015年8月,它被拆除了。从20世纪90年代,霓虹灯开始在香港衰落,制作霓虹灯招牌的师傅说,香港的建筑规划愈来愈严格,现在新的广告牌都会选用LED灯来制作,它没有霓虹灯那种浓浓的暖意,但是胜在价格低廉,更容易维修,使用寿命更长。

香港闪烁的霓虹灯招牌现在大多被LED灯取代。图片来源:Medium

这头闪闪发光的牛将近10英尺长,8英尺高,悬挂在街头,慕名而来的游客很容易就找到这家餐厅,但是这个巨型招牌惨遭摘除。图片来源:Vice

而在以前的上海,霓虹灯也曾是一道非常著名的风景线。上海曾有一首非常著名的竹枝词流传甚广:“火树银花灿若何,西商赛会赛灯多。电光环作招牌字,万点明星遍屋罗。”这首词描绘的正是上海夜景,霓虹灯的夺目光彩使得上海的夜晚更加热闹。现在在上海也可以看到一些具有历史意义的霓虹灯,但只是这样的招牌已经少之又少了。一位名叫Victor Chiang的摄影师,慕名上海霓虹夜景,拍了很多独特的夜上海照片,很多照片中可以看到布满霓虹灯的老街道。但是我们能看到的“原汁原味”的霓虹灯却越来越少。

在西方,霓虹灯的盛况也一去不复返。加拿大温哥华曾被誉为“霓虹灯之都”,在1950年的时候,各式各样的广告是在用霓虹灯做宣传,教堂外面的装饰也是用的霓虹灯。在当时温哥华条状霓虹灯产量全球第一,平均每18个人,每12个工厂就有一个霓虹灯招牌,世界最大的霓虹灯也在这里。但是随着商业科技的进步,霓虹灯终究还是没有逃过衰退之势。

霓虹灯独特的艺术价值

霓虹灯首次亮相是在1910年的巴黎车展上,装点大楼外表的灯光散发出与以往不一样的颜色,在场所有嘉宾的注意力都被这新奇的灯光吸引了。霓虹灯不能用于室内,最佳用途就是用在商业领域和街头招牌上。霓虹灯首先应用最多的是理发店,接着便扩散城市的各个角落。巴黎的城市气质又让它和霓虹灯天生一对。过了一段时间,霓虹灯来到了美国,1939 年的纽约世界交易会上,霓虹灯装点许多招牌,很多公司都愿意用霓虹灯为他们的产品进行宣传。

霓虹灯除了在商业上大放光彩,霓虹灯还积极参与到了曾经东欧国家的“政治宣传”之中。苏联在 1960 年代实施了东欧首都的“霓虹灯化”,意在和西方国家比拼实力。在华沙,霓虹灯装点在许多公共楼房外面。因而当东欧公民出门环顾外面的世界,他们会看到非常有意思的场景:他们不仅能看到老式的政治标语,也能看到很多政治宣传海报被霓虹灯包围着。

霓虹灯不仅仅只是一种装饰,它还具有极高的艺术价值。霓虹灯成为了很多科幻小说的素材,而且极大推动了赛博朋克艺术的发展。它成了科幻赛博朋克电影的标志性背景,因为霓虹灯那绚丽的色彩可以同时表现出各种强烈的反差感:繁荣与颓废的对立,未来与现实的交错,富裕与贫穷的反差,让人产生出时空交错的感觉。

赛博朋克是科幻小说中的一个分支,倾向于描绘“高科技与低端生活的结合”。赛博朋克作者试图从侦探小说、黑色电影和后现代主义中汲取元素,描绘20世纪最后20年数码化社会不为人知的一面。赛博朋克的反乌托邦世界,被认为是20世纪中叶大部分人所设想的乌托邦未来的对立面。正是因为赛博朋克这样的风格,改编出来的电影也喜欢光影交错的感觉,霓虹灯就是他们经常选用的元素。图片来源:Cyberpunk conception via Sergii Golotovskiy

霓虹灯在20世纪也极大推动了波普艺术的发展。波普艺术虽然已经成了历史,但是它带给美国艺术界的影响是巨大的。波普艺术是美国现代文化发展的助力器,正是由于波普艺术的发展,1960和1970年代震撼美国社会的形形色色的反艺术运动才接踵不断地涌现。波普艺术家在美国消费主义浪潮的推动下,不仅受到电视或杂志上标准化的广告所影响,还受到了夜晚散发着迷离气息的霓虹灯的影响。这些艺术家在他们的作品中极大地融合了霓虹灯艺术中明艳的色彩元素。

美国雕塑家瓦尔达·克里萨(Valda Chryssa,1933年生)是一位波普艺术家,擅长创作管装雕塑。作品用红、橘红、绿、蓝色的霓虹灯管,构成一个像“8”字形的排列构图,产生霓虹灯的效果。这种商业广告性质的波普艺术作品,借助于光和氖而构成,再加上定时断联器,制造霓虹灯的效果,以新奇、精致及巧妙的艺术特色而吸引人。图片来源:jmsou.com

艺术家用多样的方式挽救这门艺术

虽然霓虹灯被越来越多的LED节能灯代替,街道上也越来越难看到霓虹灯的招牌,但是越来越多的人开始怀念起这样的文化,各个地区与艺术家开始用各种各样的方式挽救这样的一种视觉文化。

很多国家和地区专门开设霓虹灯博物馆来保存这些霓虹灯招牌。美国加州的“霓虹艺术博物馆”

(Museum of Neon Art)

中,收藏着各种各样的霓虹灯招牌,当你走进来的时候,你会从博物馆的各个位置看到各式各样的霓虹灯。博物馆里收藏了很多老旧、残破、被扔掉的霓虹灯中拯救出来的霓虹灯招牌。很多霓虹灯大部分的来源竟然是垃圾场。这个博物馆的开放在美国掀起了一股怀旧之风,这些老旧的霓虹灯招牌展示了上世纪曾经在这个城市闪耀过的光芒。在香港,一大批艺术家与策展人正在抢救这样的艺术,因为香港人曾经的身份认同中,霓虹灯也扮演了重要角色。M+博物馆就是专门收集香港霓虹灯招牌的博物馆,这家博物馆专门在线收集香港的霓虹招牌照片,也收集一些被拆除的霓虹招牌。森美餐厅的霓虹奶牛拆除令人一度惋惜,但是现在它也收藏在M+博物馆之中。

2019年2月24日到5月10日在香港岛北角油街附近正在举办名叫「城街·招牌」的艺术展览。布展人认为在香港的历史中,街道上的霓虹灯招牌一代又一代地繁衍,塑造香港的城市面貌。创办人及建筑师Ken和Kevin希望通过「城街·招牌」的灯光装置,展示霓虹灯招牌的多种特点,以提高公众对霓虹灯艺术价值的认识。

「城街.招牌」灯光装置的布展现场。图片来源:timable

为了挽救霓虹灯文化很多艺术家还另辟蹊径。2014 年 Sas Simon 和 Lena Imamura 一同创立了做定制霓虹灯的公司 NameGlo,主要将霓虹灯应用于室内设计。NameGlo 的定位是将霓虹灯打造成一件有意义的艺术品而不仅仅是一件家居装饰品。它的独特点在于将做霓虹灯标牌的过程流程化透明化,让顾客自己制作具有自己艺术风格的霓虹灯。“霓虹灯艺术对于现代艺术仍然具有重要意义,希望通过我们公司这样的服务,把霓虹灯与顾客之间的距离拉近”, Lena Imamura 说。霓虹灯艺术绝不是一种过气的艺术。有人专门在ins上成立了neonnewyorkcity(纽约城霓虹灯)的账号。在很多人心中霓虹灯不仅仅是夜生活、经济繁荣的象征,更是一种独一无二的艺术。

霓虹艺术博物馆是一个通过保存,收集和解释霓虹艺术来鼓励学习和好奇的机构。第一个致力于融合霓虹灯照明的艺术博物馆,专门展示电子媒体艺术,包括动态艺术和历史悠久的霓虹灯标志。它位于洛杉矶市中心。于2016年在加利福尼亚州格伦代尔重新开放。图片来源:tripadvisor

英国摇滚天团Blur曾经的专辑《The Magic Whip》就采用霓虹元素来表达那种“生到不能再生的生疏感”。

国内也有艺术家在积极响应这种文化的复兴。上海也在积极筹建霓虹灯博物馆,它将建在上海某创意园区内,占地约600平方米,充分展示霓虹灯艺术发展的历程,与工艺发展水平。在很多人的印象中,上海与它独特的夜景紧密相连,那些明亮夺目的夜晚,又融入了让人难忘的霓虹灯。越来越多的人为霓虹灯的消失而惋惜,但是通过艺术家们的不断努力,这门艺术一定可以被延续下来。

编译参考:

The New York Times的“Hong Kong Is Slowly Dimming Its Neon Glow”

https://www.nytimes.com/2015/10/14/world/asia/hong-kong-neon-sign-maker.html?_r=1

the Atlantic的“Neon Is the Ultimate Symbol of the 20th Century”

https://www.theatlantic.com/entertainment/archive/2019/04/being-and-neonness-neon-lights-symbol-20th-century/588184/

作者

:新京报记者 何安安 实习生 闫晓旭

编辑

:覃旦思;校对:薛京宁

能源人都在看,点击右上角加'关注'】

近几年来,随着新能源汽车行业的蓬勃发展,新能源汽车市场和国家补贴政策对锂离子动力电池的能量密度、循环寿命、安全性能和电池成本不断提出更高的要求。因此,电池厂商高度重视生产过程中的品质管控,努力提高产品的质量和一致性,并尽可能降低电池生产成本。

在锂离子电池工艺开发和品质管控过程中,极片制造属于前段工序,在整个过程中占据着重要位置。日本电池界普遍认为,电池的质量有70%与极片品质有关。究其原因,在于极片品质好坏不仅影响电池中段组装工序,而且会对后段工序、电池的电化学性能和安全性能产生关键性的影响。美国橡树岭国家实验室的研究[1]表明,在制造成本为502.8 $/kWh的电池中,采用先进的极片制造技术可减少111 $/kWh的成本支出,因此极片制造技术在降低电池制造成本中发挥着重要作用。

锂离子电池极片制造包括合浆、极片涂布和干燥、极片的辊压和裁切等工序。在之前的文章[2]中已详细讲述了锂离子电池合浆工艺的方法和技巧。除合浆工序外,极片涂布和干燥也是制备高品质极片的重要环节。在实际的极片涂布和干燥过程中可能出现各种涂布和干燥缺陷,不利于制备具有均一厚度和面密度的极片,严重影响极片性能和良品率。本文主要从各类极片缺陷的形成机制、防治措施和检测方法等三个方面进行了概括和介绍,并对极片制造技术的发展趋势进行了展望。

极片缺陷的种类、形成机制和防治措施

在极片涂布和干燥过程中,可能出现的缺陷主要分为三类:点状缺陷、线状缺陷和边缘缺陷。点状缺陷包括团聚体颗粒、针孔缺陷和缩孔缺陷等;线状缺陷主要包括划痕、竖条纹和横条纹缺陷等;边缘缺陷主要包括厚边和拖尾现象等。下面就各种缺陷的形成机制和防治措施进行介绍。

1.1 点状缺陷

1.1.1 团聚体颗粒

如图1所示,如果浆料搅拌不均匀,导电剂和粘结剂没有形成良好的分散效果,极片表面会出现大面积的凸起,即导电剂的团聚体[3]。此外,浆料、涂布设备或涂布基材中引入Fe、Cu、Zn、Al等金属粉末,极片表面会形成以金属粉末为核心、浆料物质为表层的团聚体。搅拌过程中,环境湿度太高,导致正极浆料成果冻状态,极片辊压后也会出现团聚体颗粒[4-5]

(A)极片表面光滑,(B)极片表面存在团聚体颗粒;(a,b)为(B)的细节放大图,其中导电剂的团聚体没有完全分散;(c,d)为(A)的细节放大图,其中导电剂充分分散、均匀分布

图1 由球形石墨+SUPERC65+CMC+蒸馏水制备的极片[3]

极片出现团聚体缺陷后,在辊压极片时较软的颗粒可被碾成粉末、从极片表面脱落,较硬的颗粒则会凸显出来、形成尖点,存在刺破隔膜、短路的安全隐患[6-7]。研究[8-9]表明,极片表面出现团聚体颗粒会对电池的电压、电压衰减和循环寿命等造成不利影响。此外,以Fe、Cu、Zn、Al等金属粉末为核心的团聚体也会对电池造成巨大的危害[5]。尺寸较大的金属颗粒可刺穿隔膜,导致正负极之间短路,即物理短路;当金属异物混入正极后,充电之后正极电位升高,金属发生溶解、通过电解液扩散,然后在负极表面析出,也可刺穿隔膜、造成短路,这种称为化学溶解短路。

针对团聚体缺陷的形成机制,团聚体缺陷主要通过优化合浆工艺和环境清洁除尘来消除。

1.1.2 缩孔缺陷

如图2所示,在涂布过程中,涂布基材受到较低表面张力物体(如油滴、灰尘等)的污染后,污染物周围的涂布溶液会流向具有较高表面张力的方向,形成像火山口或酒窝状的缩孔缺陷[10-13]。材料之间表面张力不匹配,是产生缩孔缺陷的主要诱因,但浆料的粘度、流动性以及干燥风速和温度等都可能改变表面张力及其作用过程,从而诱发形成缩孔缺陷。例如,过低粘度(~1 500 mPa·s)的水性浆料在涂布后,溶液因表面张力不同会脱离疏水的石墨、积聚到表面张力较高的位置,形成缩孔缺陷[13]

图2 缩孔缺陷的(a)形成机制示意图[13],(b)极片微观形貌图[13]和(c)含火山口状缺陷的极片外观图

针对缩孔缺陷的形成原因,相应的防治措施[10,12]有:(a)控制环境粉尘;(b)浆料过滤除铁、基材表面清洁;(c)选用相容性好的分散剂或分散介质;(d)提高浆料粘度和缩短干燥时间等。

1.1.3 针孔缺陷

湿膜中的气泡从内层向表面迁移,在膜表面破裂会形成针孔缺陷[11-12](图3)。气泡主要来自搅拌、涂液输运以及涂布过程[12]。针孔缺陷处活性物质涂层较薄,在电池充放电过程中最易造成微短路;正极涂层出现针孔缺陷会降低材料的库仑效率、倍率性能和循环性能。因此涂布前的浆料需做好脱泡处理。

图3 针孔缺陷的(a)极片外观图和(b)极片微观形貌图[14]

1.1.4橘皮缺陷

在涂布过程中,由于溶剂挥发,不同的区域产生温度差,浆料上层和底层形成浓度差,形成表面张力的梯度及自然对流的现象,涂布溶液就会发生迁移,最终造成涂布表面不平整、形成橘皮缺陷(图4)。烘箱的干燥速率过快或热风风速过快,溶液在流平前就提早固化,也形成橘皮缺陷[11]

图4 (a)真的橘皮和(b)具有橘皮缺陷的极片

抑制橘皮缺陷的形成,可采取以下措施[11]:(a)降低干燥速率,让溶液可以有足够的时间流平;(b)在溶液里添加一些低挥发的溶剂、表面活性剂等,减小温度差和浓度差。

1.2 线状缺陷

1.2.1 划痕

涂布过程中,大颗粒聚集在出料狭缝,所制备涂层会出现与涂布方向平行的线状薄区或漏箔线条[15]。这导致涂层不均匀,会影响电池容量的一致性。除此之外,基材质量不佳,有异物挡在涂布间隙上或模具模唇损伤也会造成划痕(图5),要注意排查原因。

图5 涂布过程中的划痕缺陷[14]

1.2.2 规律竖条纹缺陷

如图6所示,规律竖条纹缺陷是沿涂布方向出现的平行条纹,并且覆盖整个涂布幅面,就像拿个梳子或者锄地的耙子沿机器方向抓,人为地抓出了外观一样的缺陷。从流体动力学的角度来讲,涂布浆料受到本身粘弹力、惯性力和表面张力等作用力,在不同方向叠加产生的受力差异会造成涂布厚度的不均匀分布,即形成规律竖条纹。涂布后肉眼很容易观察到这种缺陷,在烘干过程中也很难通过流平消除[16]。如果极片出现团聚体、针孔和划痕等缺陷,可切割去除;但一旦发生竖条纹缺陷,极片几乎找不到一块能用的部分,产品得率就降到0%。

图6 规律竖条纹的(a)极片外观图和(b)示意图[16]

防治措施[16]主要有:(a)确定工艺是否在合理的工艺窗口内,调整涂布工艺参数,降低涂布速度;(b)降低涂辊与背辊之间的涂布间隙;(c)添加溶剂或表面活性剂,稀释浆料,降低浆料粘度;(d)减小辊子的直径。

1.2.3 横条纹缺陷

横条纹缺陷是垂直于涂布方向,固定间隔所产生的波纹或线条,主要是由于泵输送的浆料流量不稳定和涂布设备振动造成的[17]。所以避免横条纹的出现可更换泵和涂布设备,涂布头增加真空盒等来改善。

1.3 边缘缺陷

1.3.1 厚边现象

由于浆料流体特性,在涂层起始点、终止点以及两侧边缘容易形成半月形,极片边缘出现厚度突增的现象称为厚边现象[18](图7)。厚边现象形成本质是在表面张力驱动下物质发生迁移。极片干燥时,涂布边缘比内部区域溶剂挥发快,涂布浆料流向高表面张力的边缘区堆积,使得边缘过厚[10,12]

图7 厚边缺陷示意图[12]

厚边的危害比较大:(a)影响极片的辊压、分切和卷绕工艺,极片受力不均会造成极片翘曲度过大,增大后续分切、卷绕难度;(b)在充放电过程中,电流分布不均匀,容易产生极化;(c)在充放电膨胀/收缩过程中因极片受力不一致,厚边缘更易失效,影响电池性能。一般地,3C电池工艺设计时,可切除极片边缘来消除这种厚边的不利影响。动力电池要求高功率和高能量,电池设计往往需要保留涂层边缘[19],因此厚边现象需高度重视。

针对厚边缺陷,可采取以下措施[10,12,19]进行解决:(a)添加界面活性剂,降低浆料的表面张力,抑制干燥过程中浆料向边缘的流延;(b)优化狭缝垫片出口形状,改变浆料流动速度,降低边缘浆料的应力状态,减弱浆料边缘膨胀效应;(c)减小涂布间隙。以上措施效果比较有限,最重要的还是需要依靠高精度的涂布设备来改善。

1.3.2 拖尾现象

浆料粘度太低或固含量过低时,浆料发生固液分层,因液体的流动性比固体好,当固体停止流动时液体部分或者固含量低的部分还会向外流动,就会形成拖尾现象(图8)。拖尾现象又分为水印式拖尾和锯齿状拖尾。水印区域无活性物质和导电剂存在,造成面密度不均的概率较低,因此水印式拖尾危害较小。发生锯齿状拖尾现象时,极片面密度不均匀现象严重,危害较大。另外,浆料发生沉降或者正极浆料出现“果冻”现象也会出现拖尾现象。

图8 有拖尾现象的极片外观图

除浆料固含量和粘度外,基材和浆料的表面张力差异性也会引起拖尾现象。浆料在基材上润湿要求浆料的表面张力低,基材的表面能高;否则在涂布后涂层会很快脱润湿,即涂层从已涂布的地方缩回。因此,除制备固含量和粘度适宜的浆料外,还应从这两方面注意抑制拖尾或回缩现象的产生[10]:(a)基材的表面能与浆料的表面张力要匹配,基材的表面能要高,涂料液体的表面张力要低;(b)防止基材表面干燥点的出现。

极片缺陷的检测技术

前文提到的团聚体、划痕、厚边、条纹、拖尾和橘皮等极片缺陷,会严重影响电池的一致性、使用寿命和安全性能,有效地鉴别和剔除存在缺陷和瑕疵的极片,提高极片品质和一致性势在必行。传统的人工检测方法效率低、误差大,且无法保证检测质量,难以满足锂离子电池大规模生产的需求。近年来,具有精度高、速度快和非接触等优点的现代科学技术不断发展和完善起来。目前,针对极片品质的检测技术主要有:射线法测厚技术、激光测厚技术、机器视觉检测和红外热成像技术。

2.1 射线法测厚技术——采用X射线或β射线测量涂层的厚度和面密度

X射线或β射线穿透物质时,被物质反射、散射、吸收,导致穿透的射线强度相对于入射射线强度有一定衰减。衰减比例与被穿透物体的厚度/密度呈负指数关系。通过测量穿透前后的射线强度,即可推断出物质的厚度/面密度[20]。该方法可直接获得涂布极片的厚度和面密度值,测量精度高;但设备昂贵、辐射源的维护管理成本也较高,且使用不当会对人体造成伤害。

2.2 激光测厚技术——检测极片面密度和缺陷

激光测厚仪一般是由两个激光位移传感器上下对射的方式组成的,上下的两个传感器分别测量被测体上表面位置和下表面位置,通过计算得到被测体的厚度。激光在线测厚技术应用于测量极片的厚度,测量精度可达±1.0μm,还能实时显示测量厚度及厚度变化趋势,便于数据追溯和分析[20]。利用激光测厚仪[21-22]可剔除存在厚边、针孔和团聚体等缺陷的极片。

2.3 机器视觉检测技术——检测极片缺陷

所谓“机器视觉”,就是利用机器代替人眼来做测量和判断,主要是通过采用图像控制器(CCD)扫描被测物,图像实时处理及分析缺陷类别,实现对极片表面缺陷的无损在线检测。完整的机器视觉系统综合了光学、机械、电子和计算机软硬件等技术,可检测出0.2mm×0.2 mm及以上的缺陷,检测速度达60个/min,具有检查精度高、处理速度快、抗干扰能力强和运转时安稳可靠等优势,在大规模批量生产模式下可替代流水线员工进行锂离子电池极片进行全面检测。

机器视觉检测在锂离子电池制造安全检测中具有明显优势,但离大规模的普及应用还存在一定距离,主要是由于部分电池企业生产工艺、产线自动化程度和进口视觉检测设备兼容性不高,对机器视觉检测系统的功效存在疑惑。因此除少数大型电池厂商和先进企业率先开始应用之外,大多数企业仍持观望态度。

2.4 红外线热成像技术——检测极片缺陷

红外线热成像技术也可用来检测极片缺陷。红外线热成像技术将物体热辐射的红外线特定波段信号转换成人眼可见的图像,并以不同颜色显示物体表面温度分布。当物体表面存在缺陷时,该区域会出现温度偏移;在热成像技术获取的极片温度分布曲线中,具体表现为缺陷点位置出现温度尖峰,其中温度升高的尖峰对应团聚体,温度降低的尖峰对应针孔或者掉料[5,23] 。红外线热成像技术可有效鉴别一些光学探测手段无法分辨的缺陷,是一种高效的极片表面缺陷探测手段。目前,红外线热成像技术仅用于科学基础研究,距离工业化应用还存在较大距离。

展 望

极片涂布和干燥过程中可能会出现团聚体、针孔、划痕、厚边和拖尾等缺陷,抑制极片缺陷的形成和及时剔除存在缺陷的极片,对于提高锂离子电池的电化学性能、安全性能、一致性意义和降低电池制造成本意义重大。随着各种高精度、高效率在线检测技术的普及和广泛应用,极片缺陷被及时检测和剔除,涂布和干燥工况条件得到及时反馈和调整,锂离子电池在能量密度、高安全性和一致性方面将迈上新台阶。

参考文献:

[1]WOOD D L, LI J L, DANIEL C, et al. Prospectsfor reducing the processing cost of lithium ion batteries[J].Journal of Power Sources, 2015, 275: 234-242.

[2] 杨时峰,薛孟尧,曹新龙,等. 锂离子电池浆料合浆工艺研究综述[J]. 电源技术,2020,44(2):291-294.

[3] BITSCH B,WILLENBACHER N, WENZEL V, et al. Impact of mechanical process engineering onthe fabrication process of electrodes for lithium ion batteries[J]. ChemieIngenieur Technik, 2015, 87(4): 466-474.

[4] DAVIDA L,RUTHERA R E, MOHANTY D, et al. Identifying degradation mechanisms inlithium-ion batteries with coating defects at the cathode[J]. Applied Energy,2018, 231: 446-455.

[5] MOHANTY D,HOCKADAY E, LI J, et al. Effect of electrode manufacturing defects onelectrochemical performance of lithium-ion batteries: Cognizance of the batteryfailure sources[J]. Journal of Power Sources, 2016, 312: 70-79.

[6]裴敬龙. 锂离子电池正极片辊涂存在的问题及解决措施[J]. 新疆有色金属,2012(增刊2):112-113.

[7] 覃晓捷,韦京汝,王姜婷,等. 正极极片表面颗粒对电池性能影响的研究[J]. 电源技术,2017,41(10):1399-1401.

[8] 王双双,武行兵,张沿江,等. 锂离子电池循环寿命影响因素的研究[J]. 电源技术,2015,39(6):1211-1213.

[9] 宋晓娜. 锂离子电池自放电研究[J]. 电池工业,2013(1):47-50.

[10] 龚海青,郭洪猷,王平. 表面张力引起的涂层弊病(II)[J]. 现代涂料与涂装,2000(4):1-2.

[11] 李群英. 涂装工常用技术手册[M]. 上海:上海科学技术出版社,2008:293-296.

[12] 迟彩霞,张双虎,乔秀丽,等. 狭缝式涂布技术的研究进展[J]. 应用化工,2016,45(2):360-364.

[13] 成都茵地乐电源科技有限公司. 极片涂覆与干燥中的缩孔现象[EB/OL].[2013-07-03]. http://www.cd-ydl.com/index.php?go=article-26.html.

[14] KRAYTSBERG A,EIN E Y. Conveying advanced Li-ion battery materials into practice: The impactof electrode slurry preparation skills[J]. Advanced Energy Materials, 2016,6(21): 1600655

[15] SCHMITT M,BAUNACH M, WENGELER L, et al.Slot-die processing of lithium-ion battery electrodes—Coatingwindow characterization[J].Chemical Engineering and Processing: ProcessIntensification, 2013, 68: 32-37.

[16] COHEN E D. Howcan the ribbing defect be eliminated in web coating?[J]. Converting Quarterly,2015, 5(1): 16-17.

[17] 燃化部第一胶片厂. 挤压涂布弊病的防止与消除[J]. 感光材料,1973(2):9-13.

[18] SCHMITT M, SCHARFER P, SCHABEL W.Slot die coming of lithium-ionbattery electrodes: Investigations on edge effectissues for stripe and pattern coatings[J]. Journal of Coatings Technology and Research, 2014,11(1): 57-63.

[19] 新能源Leander.锂电池极片挤压涂布厚边现象及解决措施[EB/OL]. [2017-07-18]. http://www.china-nengyuan.com/tech/111508.html.

[20] 庞可可. 激光测厚仪在锂电池极片涂布生产中的应用性研究[J]. 河南科技,2016(3):144-145.

[21] 陈功,许清泉,朱锡芳. 锂电池极片质量监控系统的设计和实现[J]. 仪表技术与传感器,2013(12):87-89.

[22] 王莹. 激光测厚仪在锂电池极片生产中的应用[J]. 电源技术,2012,36(2):186-187.

[23] 王云辉,孙青山,李松鞠. β射线在锂离子电池生产中的应用[J]. 电池,2018(5):347-349.

作者:杨时峰,胥 鑫,曹新龙,邵 乐,田占元

单位:陕西煤业化工技术研究院有限责任公司

免责声明:以上内容转载自电池中国,所发内容不代表本平台立场。

全国能源信息平台联系电话:010-65367702,邮箱:hz@people-energy.com.cn,地址:北京市朝阳区金台西路2号人民日报社

用变量 currentColor 减少重复代码

需求描述

  • 移到按钮上时,改变该元素的 border-color 、 color ,还有一个具有透明度的同色背景。
  • 点击按钮之后,颜色更改为移入按钮时的同种颜色。

尝试方案

我相信任何一个前端开发者都能很快实现这个需求,不知道大家怎么样的,我在之前一直都是以下代码快速实现:

index.html 文件 :

<div class='good'>请给我点赞</div>
复制代码

index.scss 文件 :

.good {
  padding: 3px 6px;
  color: #333;
  background: rgba(#333, 0.1);
  border: 1px solid #333;
  border-radius: 3px;
  cursor: pointer;

  &:hover {
    color: #0069ff;
    background: rgba(#0069ff, 0.1);
    border: 1px solid #0069ff;
  }

  &.good-click {
    color: #0069ff;
    background: rgba(#0069ff, 0.1);
    border: 1px solid #0069ff;
  }
}
复制代码

index.js 文件 :

const goodBtn=document.querySelector('.good')

goodBtn.addEventListener('click', ()=> {
  if (goodBtn.classList.contains('good-click')) {
    goodBtn.classList.remove(['good-click'])
    return
  }
  goodBtn.classList.add(['good-click'])
})
复制代码

是的,就是那么朴实无华,缺点也暴露无遗:

  • 相同的颜色我们使用了多次,比如 #333 和 #0069ff 。如果有一天产品说把这个那个颜色改一下,细心点的你多动动手指也没啥问题,改就改了,但是这种方式很不“程序员”。

针对这个问题我们直接使用预处理器(SASS/LESS)的变量就完事了:

index.scss 文件 :

$color: #333;
$hoverColor: #0069ff;

.good {
  padding: 3px 6px;
  color: $color;
  background: rgba($color, 0.1);
  border: 1px solid $color;
  border-radius: 3px;
  cursor: pointer;

  &:hover {
    color: $hoverColor;
    background: rgba($hoverColor, 0.1);
    border: 1px solid $hoverColor;
  }

  &.good-click {
    color: $hoverColor;
    background: rgba($hoverColor, 0.1);
    border-color: $hoverColor;
  }
}
复制代码

咋一看已经是很好的实现方式了,但是也有缺点:

  • 有时候(比如我大多数时候)都不想为了某一个特殊的类下的 color 单独设置一个变量,仅仅只有它使用,我还要专门为其定义一个变量就显得代码很臃肿;
  • 在我添加了 good-click 这个类名后,我要把 color 、 border-color 、 background 全都重新设置一遍;

这个时候,css 原生变量 currentColor 即可大显身手了。

改进方案

变量 currentColor 能拿到本元素的 color 属性的值,如果没有显示设置,拿的将会是父元素的 color 属性的值,由此类推。借助这个特性,我们即可优化上述代码:

index.scss 文件 :


.good {
  position: relative;
  padding: 3px 6px;
  color: #333;
  border: 1px solid currentColor;
  border-radius: 3px;
  cursor: pointer;

  &::before {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: currentColor;
    opacity: 0.1;
    content: '';
  }

  &:hover {
    color: #0069ff;
  }

  &.good-click {
    color: #0069ff;
  }
}
复制代码

现在看起来是不是好多了,我每次要更改颜色,只需要将此元素的 color 属性更改即可,不需要再重新写一堆重复的属性,当然,原生的 css 以及功能强大的 sass/less 都还是无法支持 rgba(currentColor, 0.1) 这种写法,我还去官方提了个 issue ,官方也给了很好的回复,有兴趣的同学可以看看。

所以现在我只能添加一个 ::before 来模拟背景色块,真正做到只改 color 属性,即可改全部颜色。

现在大家就可以在 React 或 Vue 中通过状态来控制改变颜色的类名添加与否并设置 color 属性,以此来完美地进行颜色的快速变换了~

多说一句,如果我们直接使用 ele.style.color='#fff' 这种操作 dom 的形式来改变字体颜色,在未使用 currentColor 的情况下,我们是没法操作伪元素的,也就改变不了伪元素的 background 、 border-color 等其他与字体颜色一致的属性,所以这时候 currentColor 的优势就更明显了~

在线演示

使用变量 currentColor 减少重复代码 - codepen(https://codepen.io/vortesnail/pen/MWyzerK)

完美的带小箭头的聊天框

需求描述

  • 主体功能聊天气泡,需有有边框 border 、背景色 background 、阴影、带边框的小三角箭头。
  • 小三角的边框颜色和阴影颜色与主体框的颜色要一致,小三角的边框有 border-radius 。

尝试方案

给该元素加个伪元素,背景色与聊天框背景色一致,再给该伪元素添加上、左同色边框,绝对定位调整位置,再来个 border-top-left-radius: 3px ,最后 transform: rotate(-45deg) 旋转一下,代码如下:

index.html 文件 :

<div class="chat-box">大家好,我是 vortesnail,如果大家喜欢我的文章,对大家有所帮助,麻烦给个小小的赞支持一下,谢谢</div>
复制代码

index.scss 文件 :


.chat-box {
  position: relative;
  max-width: 200px;
  padding: 10px;
  color: #faae43;
  background: #fff9ed;
  border: 1px solid #ffc16b;
  border-radius: 4px;
  box-shadow: 0 2px 6px rgba(250, 174, 67, 0.8);
}

.chat-box::before {
  position: absolute;
  top: 20px;
  left: -6px;
  width: 10px;
  height: 10px;
  background: #fff9ed;
  border-color: #ffc16b;
  border-style: solid;
  border-width: 1px 0 0 1px;
  transform: rotate(-45deg);
  content: '';
  /* box-shadow: 0 2px 6px rgba(250, 174, 67, 0.8); */
}
复制代码

可以达到现在下面的效果:



细心的你一定发现了,这个小三角指示箭头是没有阴影的,如果我给其加上与主体元素一致的 box-shadow ,又因为这个属性不能像 border-color 一样分别给各边设置为透明,结果就会像下面这样:

这已经是无法满足具有相同阴影的要求了,而且大家如过想一下就知道,在我主体元素不设 padding 或设的很小的情况下,小三角的背景色会将我们的文字挡住,这种方案直接宣布失败!

改进方案

针对以上的问题,我们进行一步步改造。

首先,我们考虑到主体元素不设置 padding 的情况,为了防止内容被我们的小三角背景色覆盖,我们可通过加一个伪元素 ::before ,利用 border 来画成一个三角形,代码如下:

.chat-box {
  // 其他样式
  
  &::before {
    position: absolute;
    top: 20px;
    left: -8px; // 注意,这里做了略微调整
    width: 0;width
    height: 0;
    border-color: transparent #fff9ed transparent transparent;
    border-style: solid;
    border-width: 8px 8px 8px 0;
    content: '';
  }
}
复制代码

现在是这个样子:

注意,这里的小三角已经是没有右边部分的了,解决了我们不设置 padding 时导致内容被遮挡的问题。但是这样就没有办法实现边框,毕竟你已经是使用边框做出来的三角形了。

那我们就再使用一个伪元素呗, ::after 安排上了。接下来为大家提供一个思路:采用尝试方案中的方式再画一个正方形做旋转,但是不为其设置背景色,只设置其 border ,调整下位置即可。

.chat-box {
  // 其他样式
  
  &::before {}
  
  &::after {
    position: absolute;
    top: 22px;
    left: -7px;
    width: 10px;
    height: 10px;
    /* border-color: inherit transparent transparent inherit; */
    border-color: transparent;
    border-style: solid;
    border-width: 1px;
    border-top-color: inherit;
    border-left-color: inherit;
    border-top-left-radius: 3px;
    transform: rotate(-45deg);
    content: '';
  }
}
复制代码

可以看到,代码中我设置上和左的 border-color 为 inherit ,表示继承父级元素的 border-color ,因我注释那部分的写法不被识别,所以我们新增了几行代码实现,利用 inherit 可以在颜色更改时少写颜色值的重复代码,与 currentColor 想要达到的目的是一致的。

现在,越来越接近我们的目标:


这里小三角还是没有阴影,因为 box-shadow 并不会作用于伪元素,解决方案就是使用 filter 属性, drop-shadow 接受的参数和 box-shadow 基本一致,我们替代它即可:

// box-shadow: 0 2px 6px rgba(250, 174, 67, 0.8);box-shadow
filter: drop-shadow(0 2px 6px rgba(250, 174, 67, 0.8));
复制代码

现在已经完美实现~

在线演示

实现一个完美的带小箭头的聊天框 - codepen(https://codepen.io/vortesnail/pen/mdPQgwY)

利用 grid 实现完美的水平铺满、间隔一致的自适应布局

需求描述

  • 在一个容器元素下,有不确定数量的子元素,要求他们水平铺满,并且在当前行的最左边和最右边的子元素距离父元素左边缘和右边缘都是无缝贴合的。
  • 每个子元素之间的间隔必须一致。
  • 当浏览器窗口大小变动自适应。



尝试方案

这个问题从我入职第一份工作之后困扰了我接近半年,我基本还是惯性思维,一眼看过去就是 flex弹性盒子 一把梭,于是我有了以下这种方案:

index.html 文件 :

<body>
  <div class="father">
    <div class="child">Child1</div>
    <div class="child">Child2</div>
    <div class="child">Child3</div>
    <div class="child">Child4</div>
    <div class="child">Child5</div>
    <div class="child">Child6</div>
    <div class="child">Child7</div>
    <div class="child">Child8</div>
    <div class="child">Child9</div>
    <div class="child">Child10</div>
  </div>
</body>
复制代码

index.scss 文件 :


.father {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: flex-start;
  width: 100%;
  padding: 10px 0 10px 20px;

  .child {
    margin-right: 14px;
    margin-bottom: 14px;
    // 其他卡片样式
  }
}
复制代码

可以看到,我会为每个子元素都设置 margin-top 以及 margin-right 来固定他们之间的间距,但是因为每一行最右边的子元素也有 margin-right ,为了补偿这个,我就将父元素的 padding-right 去掉了,这样做的坏处太多了,需要自己去计算,做补偿,而且右边有时候容纳不下一个完整的子元素,就会导致换行而留下一大片白。。

为了能用弹性盒子做到想要的效果,我已经把阮一峰老师的Flex 布局教程:语法篇看烂了。。根本没法实现最佳最想要的效果,以上只是我多次尝试之后唯一能接受的方案,我就这么个方案用了好多次。

直到有一天,我又遇到了这种布局需求,我辛辛苦苦用 js 去硬算他们之间的间距,算是实现了想要的效果,但是真的非常繁琐,我就受不了了。这个时候我又偶遇了阮一峰老师的CSS Grid 网格布局教程,谢天谢地,采用 Grid 可完美实现以上需求!

改进方案

Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局。Grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局。Grid 布局远比 Flex 布局强大

首先我们需要给容器指定为 grid 网格布局,就像 flex 一样:

.father {
  display: grid;
}
复制代码

接着要为其划分列数, grid-template-columns 属性可定义每一列的列宽,假如代码如下,我们将容器划分成 3 列,每列宽度为容器的 100px :

.father {
  grid-template-columns: 100px 100px 100px;
}
复制代码

但是这个时候我们看到的效果会是下面这样:

子元素并没有把父元素占满,这显然不是我们想要的效果,幸亏有 repeat() 函数帮助我们简化重复值, 它接受两个参数,第一个参数是重复的次数,第二个参数是所要重复的值 。上面的代码完全可用以下代码代替:

.father {
  grid-template-columns: repeat(3, 100px);
}
复制代码

当然,这只是第一步,我们还需要借助 auto-fill 关键字,在我们需要容器能尽可能容纳子元素时,就需要用到它,表示自动填充,我的理解是 repeat() 接受了这个 auto-fill 的参数时,会去自动计算容纳的数量,就好像你事先算出来这个容器能容纳多少子元素,然后把这个“多少”传给该函数一样。这时候代码如下:

.father {
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
}
复制代码

现在图形如下,已经越来越接近我们的目标了:

但是很显然,右边有一个空隙, justify-content 属性拯救我们,它整个内容区域在容器里面的水平位置,当我设置其为 space-between 时,意味着子元素之间的间隔相等,而子元素与容器边框之间没有间隔

不过子元素之间还是没有间隔,简单设置一下属性 gap 即可,它是 column-gap 和 row-gap 的合并简写,分别表示列与列行与行之间的间距,现在代码如下:

.father {
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
  justify-content: space-between;
  gap: 14px 4px;
}
复制代码

由此简单的几行代码就已经完美实现了我们想要的效果:

不过 grid 网格布局的兼容性不是很好,点此查看支持的浏览器列表~

在线演示

利用 grid 实现完美的水平铺满、间隔一致的自适应布局 - codepen(https://codepen.io/vortesnail/pen/NWNEmvx)

间距可调整的虚线框

需求描述

  • 实现一个按钮,该按钮边框为虚线,且虚线的每个笔触之间的空隙和长度都是可调的。
  • 能支持有圆角,即可设置 border-radius 。

尝试方案

其实我一直很迷惑为什么 css3 不提供一些能调整虚线框的必要属性,默认的 dash-border 经常会和 ui 所需要的虚线框要求会不一致,既然官方不支持,我们只能自己寻找一些解决方案。

这个解决方案看似很多,其实每一种解决方案都会有一定的局限性,选择最合适的就是最好的,具体我列出了以下几条:

  • 利用 border-image 和自定义的图片来进行虚线框的生成,该方案在 stackoverflow 查到的,我个人也尝试了下,但是修改起来特别麻烦,我第一感觉就是不会采用这种方案,有兴趣的可以看下:Brew your own border with border-image。
  • 在所需要虚线框的元素的宽高是固定的情况下,可以让 UI 画好这个虚线框就行,弊端很明显,长度若一旦发生变化,虚线比例和原来就不会一致,特别丑。
  • 利用 4 个绝对定位的“伪元素”来模拟,代码示例如下:

index.html 文件 :

<body>
  <div id="box">
    <div class="border-horizontal top"></div>
    <div class="border-vertical right"></div>
    <div class="border-horizontal  bottom"></div>
    <div class="border-vertical left"></div>
    I am vortesnail, now i try to make a custom dashed border!
  </div>
</body>
复制代码

index.scss 文件 :

$border-color: #ccc;
$border-dashed-unit-width: 8px;
$border-dashed-unit-height: 1px;
$stroke-rate: 50%;

body {
  #box {
    width: 400px;
    background: #fff;
    padding: 10px;
    box-sizing: border-box;
    position: relative;

    .border-horizontal {
      position: absolute;
      width: 100%;
      height: $border-dashed-unit-height;
      left: 0;
      background-image: linear-gradient(
        to right,
        $border-color 0%,
        $border-color $stroke-rate,
        transparent $stroke-rate
      );
      background-size: $border-dashed-unit-width $border-dashed-unit-height;
      background-repeat: repeat-x;
    }

    .border-vertical {
      position: absolute;
      width: $border-dashed-unit-height;
      height: 100%;
      top: 0;
      background-image: linear-gradient(
        to bottom,
        $border-color $stroke-rate,
        $border-color $stroke-rate,
        transparent $stroke-rate
      );
      background-size: $border-dashed-unit-height $border-dashed-unit-width;
      background-repeat: repeat-y;
    }

    .top {
      top: 0;
    }

    .right {
      right: 0;
    }

    .bottom {
      bottom: 0;
    }

    .left {
      left: 0;
    }
  }
}

复制代码

其实其思想很简单,就是 4 个矩形,每个矩形加上渐变背景,并 repeat 即可模拟虚线效果,其间距、比例可根据我们设定的变量去调整。

但是它的弊端非常大,就是无法调整 border-radius ,即没有圆角!这里向大家展示只是为了抛砖引玉,万一你有更好的想法,或者你不需要圆角,那就可以用这个方案。效果如下:

改进方案

其实我们借助 svg 就能比较不错的实现自定义虚线框,如果不想自己写 svg 的朋友可以直接在这个网站进行调整和生成:Customize your CSS Border ,但如果你稍微了解一些 svg 的用法,也完全可以自己实现,如果你想了解一下,可阅读这篇文章:SVG入门—如何手写SVG

代码如下: index.html 文件 :

<body>
  <div id="box">I am vortesnail, now i try to draw a dashed border box.</div>
</body>
复制代码

index.scss 文件 :

body {
  #box {
    width: 400px;
    border-radius: 4px;
    padding: 10px;
    background-image: url('data:image/svg+xml,\
    <svg xmlns="http://www.w3.org/2000/svg">\
      <rect width="100%" height="100%" rx="4" ry="4" style="stroke: black; stroke-width: 2px; fill: none; stroke-dasharray: 8px 5px; stroke-dashoffset: 10px;"/>\
    </svg>');
  }
}
复制代码

可通过 stroke-width 调整虚线框宽度, stroke-dasharray 调整比例及长度、间距, stroke-dashoffset 调整偏移值。

tips:svg 方案在一些比较老的安卓机上会不兼容,即使在新的机型上,也会出现一些表现差异,虽然在 web 端支持 svg 的浏览器上表现是正常的,但若考虑到移动端用户群体时,使用请慎重。

在线演示

实现一个间距可调的虚线框 - codepen(https://codepen.io/vortesnail/pen/ZEWPwey)

自定义复选框

需求描述

  • 能够完全自定义复选框样式,就像定义一个普通的 div 元素一样。
  • disabled 状态复选框样式也可以自定义。

尝试方案

很显然,当我们使用默认的 input.checkbox 方案时,是没有办法改变其样式的,而且在不同浏览器之间,其表现也不一致,代码如下:

index.html 文件 :

<body>
  <div class="checkbox-container">
    <input type="checkbox" id="apple">  
    <label for="apple">苹果</label>
  </div>
  <div class="checkbox-container">
    <input type="checkbox" id="banana" disabled>  
    <label for="banana">香蕉</label>
  </div>
  <div class="checkbox-container">
    <input type="checkbox" id="watermelon">  
    <label for="watermelon">西瓜</label>
  </div>
</body>
复制代码

index.scss 文件 :

.checkbox-container {
  display: flex;
  align-items: center;
  
  input[type='checkbox'] {
    & + label {
      color: #333;
    }
  }

  input[type='checkbox']:disabled {
    &+ label {
      color: #c6c6c6;
    }
  }
}
复制代码

在 chrome 下表现为:

在 firefox 下表现为:

在 safari 下与在 firefox 下一致。

如果任由这种情况的发生,你们 ui 可能会找产品经理和你打一架~

改进方案

我们可以在不改变上面尝试方案中的 html 结构,只需 css 即可做到!给每一个 label 标签添加一个伪元素 ::before 作为复选框!

首先,我们给这个伪元素添加必要样式,使其符合 ui 的设计:

input[type="checkbox"] {
  & + label {
    display: flex;
    align-items: center;
  }

  & + label::before {
    box-sizing: border-box;
    content: "\a0"; /* 不换行空格 */
    width: 13px;
    height: 13px;
    margin-right: 4px;
    border-radius: 2px;
    border: 1px solid #333;
  }
}
复制代码

现在的拙劣效果如下:

我们发现,默认的复选框还是存在的,我们怎么做到将其隐藏而不破坏其可访问性呢(即不能使用 display: none )?

input[type="checkbox"] {
  position: absolute;
  clip: rect(0, 0, 0, 0);
  
  & + label {...}

  & + label::before {...}
}
复制代码

以上隐藏的方案引用至 css揭秘151页

现在点击我们自定义的复选框是没有任何效果的,接下来借助 css 的相邻兄弟选择器对 checked 状态、disabled 状态分别设置样式即可:

input[type="checkbox"]:checked {
  & + label::before {
    background-color: #1890ff;
    background-image: url("https://s1.ax1x.com/2020/10/11/0cUbi4.png");
    background-repeat: no-repeat;
    background-size: 100% 100%;
    border: none;
  }
}

input[type="checkbox"]:disabled {
  & + label {
    color: #868686;
    cursor: not-allowed;
  }

  & + label::before {
    border-color: #868686;
  }
}
复制代码

可以看到,经过此番处理后,我们可以完全自主地去设计复选框样式,比如我在上面选中时,呈现了一张对勾的图片: background-image: url("https://s1.ax1x.com/2020/10/11/0cUbi4.png"); ,这极大地方便了我们对其呈现形式的掌控。

除此之外,你还可以设置 input[type="checkbox"]:focus 时的样式哦,赶快试试吧!

在线演示

自定义复选框 - codepen(https://codepen.io/vortesnail/pen/abZOBjx)


交互式图片对比效果

需求描述

  • before 和 after 图片对比效果,可拖过拖拽中间的竖形条状进行两张图片的宽度变化。

尝试方案

css3 中引入了 resize 属性,该属性可以不通过 js 就可以改变设置该属性的元素的宽度 width ,大家一定使用过 textarea 标签把?那个右下角的可拖拽更改长宽的东西就是该属性的功劳。实际上,所有标签都可以设置该属性!

于是,简单的几段代码就可以达到交互式图片对比效果,虽然和我们想要实现的效果有点差异,但如果要求不高的话,就采用它吧:

index.html 文件 :

<div class="image-slider">
  <div class="before-container">
    <img src="https://img3.doubanio.com/view/photo/l/public/p2622600072.webp" alt="before">
  </div>
  <img src="https://img9.doubanio.com/view/photo/l/public/p2380745925.webp" alt="after">
</div>
复制代码

index.scss 文件 :

.image-slider {
  position: relative;
  
  img {
    display: block;
    width: 720px;
    user-select: none;
  }
  
  .before-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 50%;
    max-width: 100%; /* 防止容器宽度拉长至比图片还宽 */
    overflow: hidden; /* 必须不可见 */
    resize: horizontal; /* 赋予水平宽度可拉伸功能 */
    
    &::before {
      position: absolute;
      right: 0;
      bottom: 0;
      width: 12px;
      height: 12px;
      background: linear-gradient(-45deg, #000 50%, transparent 0);
      background-clip: content-box;
      cursor: ew-resize;
      content: '';
    }
  }
}
复制代码

我们利用一个伪元素 ::before 来对右下角的拉伸图标进行覆盖,以便于自定义样式,现在效果如下:

这个方案弊端就是右下角的可拖拽图标无法更改位置和大小,即使我们利用伪元素去覆盖,但是和我们需求中所需要的效果也相差甚远,于是我们不得不借助 js 了!

改进方案

在上述方案中增加一个 span 标签用于画我们的拖拽竖条,紧接着按照上述方案先将两张照片的位置和大小调好:

index.html 文件 :

<body>
  <div class="image-slider">
    <div class="before-container">
      <img src="https://img3.doubanio.com/view/photo/l/public/p2622600072.webp" alt="before">
    </div>
    <img src="https://img9.doubanio.com/view/photo/l/public/p2380745925.webp" alt="after">
    <span class="handler"></span>
  </div>
</body>
复制代码

index.scss 文件 :

body {
  .image-slider {
    position: relative;
    
    img {
      display: block;
      width: 520px;
      user-select: none;
      pointer-events: none;
    }
    
    .before-container {
      position: absolute;
      left: 0;
      top: 0;
      width: 50%;
      overflow: hidden;
    }
  }
}
复制代码

现在效果如下:

初步的效果出来了,接下来增加可拖拽改变水平宽度的功能。首先需要先在两张图片交际出添加一个竖形的条状,用于拖拽位置,更改 class='handler' 样式:

.handler {
  position: absolute;
  top: 0;
  left: 50%;
  display: block;
  width: 4px;
  height: 100%;
  background: rgba(0, 0, 0, 0.4);
  transform: translateX(-50%);
  cursor: ew-resize;
}
复制代码

注意中间的透明竖形条状即是我们可拖拽的位置:

接下来写我们的 js 脚本,首先通过原生 js 方法找到三个 dom 节点:

index.js 文件 :

const imageSlider=document.querySelector(".image-slider");
const beforeContainer=document.querySelector(".before-container");
const handler=document.querySelector(".handler");
复制代码

然后我们还需要获得 image-slider 这个最外层元素相对页面左边的距离,我们定义为变量 leftX ,并在鼠标于 handler 元素上按下时计算该值:

let leftX;

handler.onmousedown=(e)=> {
  leftX=e.pageX - handler.offsetLeft;
};
复制代码

用一张图来解释说明下:

然后在给 window 对象添加一个 mousemove 的监听事件,该回调用于改变 handler 位置和 before-image 的宽度:

handler.onmousedown=(e)=> {
  leftX=e.pageX - handler.offsetLeft;
  window.addEventListener('mousemove', moveHandler)
};

const moveHandler=e=> {
  const beforeWidth=e.pageX - leftX;
  const imageSliderWidth=imageSlider.offsetWidth;

  if (beforeWidth >=0 && beforeWidth <=imageSliderWidth) {
    handler.style.left=beforeWidth + 'px';
    beforeContainer.style.width=beforeWidth + 'px';
  }
}
复制代码

目前为止,我们拖拽 handler 已经能实现所需的效果,但是无法停止,我们需要添加一个鼠标按键抬起的监听事件,需要注意的是不能在 handler 上添加,比如: handler.onmouseup ,必须在 window 对象上添加,具体为什么,大家可以动手试试就知道了:

window.onmouseup=(e)=> {
  window.removeEventListener('mousemove', moveHandler)
};
复制代码

到此为止,就已经完美实现了该效果,大家还可以在 handler 上做更多工作,使其用户体验达到更好~

在线演示

交互式图片对比效果 - codepen(https://codepen.io/vortesnail/pen/wvWaJRB)

透明度渐变层代替滚动条提示

需求描述

  • 一个可滚动列表,在未滚动到顶部之前,需有有一个渐变层代替滚动条作为剩余内容提示,底部同理;
  • 滚到到顶部时,渐变层消失,底部同理;
  • 渐变层未矩形渐变。
  • 尝试方案


首先很明确的是,先将内容滚动条搞出来:

index.html 文件 :

<body>
  <div class="content-wrapper">
    <header>目录</header>
    <div class="list-wrapper">
      <ul>
        <li>如何长高</li>
        ...省略
      </ul>
    </div>
  </div>
</body>
复制代码

index.scss 文件 :

body {
  .content-wrapper {
    width: 248px;
    padding: 20px 0;
    background: #fafafa;

    header {
      padding: 0 20px 0 24px;
      font-weight: 500;
      font-size: 16px;
    }
    
    .list-wrapper {
      ul {
        height: 400px;
        padding: 0 20px 0 24px;
        overflow-y: auto;
        color: #595959;

        li {
          padding: 6px 0;
          font-size: 14px;
          list-style: none;
        }
      }
    }
  }
}
复制代码

现在效果如下:

接下来为滚动范围的顶部和底部都先加上我们所需要的渐变层,通过父容器的 ::before 和 ::after 伪元素来实现,同时动态为 list-wrapper 这个元素增加两个类名,用于控制渐变层的显隐:

.list-wrapper {
  position: relative;
  
  &::before {
    position: absolute;
    right: 0;
    left: 0;
    z-index: 1;
    height: 60px;
    content: '';
    pointer-events: none;
  }
  
  &.top-gradient::before {
    top: 0;
    background: linear-gradient(to bottom,#fafafa,hsla(0,0%,98%,.5) 84%,hsla(0,0%,98%,.13));
  }
  
  &::after {
    position: absolute;
    right: 0;
    left: 0;
    z-index: 1;
    height: 60px;
    content: '';
    pointer-events: none;
  }
  
  &.bottom-gradient::after {
    bottom: 0;    
    background: linear-gradient(to top,#fafafa,hsla(0,0%,98%,.5) 84%,hsla(0,0%,98%,.13));
  }
}
复制代码

但是我们想要达到的效果是:一旦滚动条不是最顶部,顶部就要有渐变层;一旦滚动条不是最底部,底部就要有渐变层。现在完全是写死在两头,需要通过简单的 js 脚本来判断 ul 元素的滚动条的位置:

index.js 文件 :

const listWrapper=document.querySelector(".list-wrapper");
const ul=document.querySelector("ul");

const onScroll=(e)=> {
  // 滚动条是否在顶部
  if (e.target.scrollTop > 0) {
    listWrapper.classList.add("top-gradient");
  } else {
    listWrapper.classList.remove("top-gradient");
  }
  // 滚动条是否在底部
  if (e.target.scrollHeight - e.target.scrollTop !==ul.offsetHeight) {
    listWrapper.classList.add("bottom-gradient");
  } else {
    listWrapper.classList.remove("bottom-gradient");
  }
};

ul.addEventListener("scroll", onScroll);
复制代码

最后再将原生滚动条隐藏,OK!

ul {
  ...
  scrollbar-width: none;scrollbar-width /* Firefox */
  -ms-overflow-style: none; /* IE10+ */
  
  &::-webkit-scrollbar { 
    display: none; /* Chrome */
  }
}
复制代码

顺带说一句,在 codepen 中滚动条隐藏不了,本地调试时可以,我也不晓得啥问题~

改进方案

实际上上述方案是我看《css揭秘》之后想到的,在这本书中,讲到了利用两层 background 以及 background-attachment 属性来进行渐变层的实现,但是我按书中实现之后,发现效果并不完美,甚至可以说有很大缺陷!我想了好久还是觉得用 js 方便,css 看起来是无法实现我想要的效果的!

所以上述方案就是最终改进方案,《css揭秘》中的方法我实在不敢认同,不过关于 background-attachment 属性的介绍倒是给我学到了~

在线演示

透明度渐变层代替滚动条提示 - codepen(https://codepen.io/vortesnail/pen/PozqKyM)


结语

虽然标题写了是 css3,但是还是难免涉及到了 js,我的目的是希望有同类需求的小伙伴能通过本篇文章得到帮助。欢迎各位理性讨论~如果有更好的方法,请大佬们务必不吝赐教!如果你已经看到此处,干脆点个赞再走吧~


作者:vortesnail
链接:https://juejin.cn/post/6882704719882485774
来源:掘金