发布时间:2025-06-13
浏览次数:0
前言
在图标话题的探讨中,我们之前已有相关讨论。今天,前端早读课的文章由百度员工顾轶灵进行分享,并且此内容得到了@百度Geek说的官方授权,允许进行分享。
顾轶灵,百度商业平台研发部的资深研发工程师,他的主要职责是推动商业产品前端基础建设的进展。目前,他正专注于设计领域与前端研发之间的协作规范和效率提升,同时也在努力将相关流程和技术实际应用到工作中。
正文从这开始~~
在产品设计中,适当地运用图标能够让产品显得更加生动且易于理解。在开发前端项目时,图标处理与引入是两个至关重要的步骤。在 Web 产品的开发过程中,引入图标的过程大致可以分为以下几个阶段:起初是通过独立图片的方式引入图标、随后转向运用 CSS 技术、再后来是采用字体图标(font icons)的形式、接着是使用 SVG 格式(SVG/SVG)、最后是在前端视图层框架中对图标组件进行封装。本文将简要回顾图标设计流程的发展历程,并探讨在百度设计语言体系构建过程中我们所进行的一系列探索。
一、使用独立图片
在过去的较长一段时间里,前端开发主要依赖插入图片的方式来实现图标功能。那时,CSS 尚未普及,因此,开发者们普遍采用这样的方法。
标签引入图标图片是唯一的可能。
src="mail.jpg" alt="email">
自CSS支持背景图功能以来,大众开始采用“-image”后缀来导入众多小图片,然而,这一做法并未实质性地解决每个图标仍需独立图片的问题。
这种方式在拥有众多图标的网页上会触发大量HTTP请求,进而消耗浏览器并行处理请求数量,造成页面整体加载速度缓慢,用户体验极差。特别是对于那些鼠标悬停后切换图标的设计,首次切换时往往需要等待图标加载。(然而,令人遗憾的是,时至今日,仍有网站沿用这种做法。)
二、CSS
随后,在本世纪初的前几年,研究者们发现了一种创新方法:他们引入了图片融合技术(图像处理技术),巧妙地将大量图标图片拼接在一起,并在样式设计中利用特定的符号(如破折号)来根据不同位置展示对应的图标。例如:
.toolbtn {
background: url(icons.png);
display: inline-block;
height: 20px;
width: 20px;
}
#btn1 {
background-position: -20px 0px;
}
#btn2 {
background-position: -40px 0px;
}
尽管这种方法与为每个小图标分别创建图片文件相比,仅需触发一次HTTP请求,从而对系统性能更为有利,然而,它仍存在以下问题:
拼接而成的图像维护起来极其复杂,必须进行细致的手动调整。尽管市面上存在一些能够自动制作“雪碧图”的软件,然而,由于这类工具存在局限性,其生成机制难以确保能够灵活应对各种不同的应用场景。
该图片来源于网址https://www..com/2012/04/css--/。
当项目中的图标数量较多时,图片需在全部下载完毕之后才会显现,这或许会导致在较长时间内所有图标均无法呈现。加之维护费用高昂,按需加载图标变得相当困难,因此,网站上的所有图标往往会被整合到一个统一的“雪碧图”中。
图标色调已经固定,不能依据内容的语境和前后文灵活地改变图标的色调。
图片尺寸是固定的,进行缩放后很难保证图标的显示效果。
在这个时代,设计师与工程师的协作模式通常是这样的:设计师完成设计后,会将图标文件交付给工程师。工程师则需要借助图片编辑软件或雪碧图生成器等工具,对拼接后的图片进行维护。然而,这种方式的效率和可维护性都相当令人担忧。
字体图标的崛起
由于图标在一定程度上相当于象形文字,因此随着 CSS 开始支持使用 @font-face 引入网络字体,人们便迅速想到可以利用这一功能来加载和展示图标。自2012年起,这家提供众多免费图标的网站取得了显著成就,尤其是其后续的商业化版本5,甚至成功为平台筹集了一百万美金。与此同时,各类字体图标平台如雨后春笋般涌现。阿里的.cn平台自多年前起便已成为国内最受欢迎的图标托管、共享与管理平台。时至今日,字体图标依然是最受欢迎的web图标解决方案之一。
字体图标的制作原理相当直观,它主要是通过占用特定的字符编码(一般位于私人使用区域,如U+E000至U+F8FF、U+F0000至U+FFFFD以及U+至U+范围内)来绘制图标字形,并同步创建一系列预定义的图标名称,即class name。这些资源可以通过网络字体技术进行加载,而图标则可以通过对应的class name进行引用。由于不同浏览器在处理web字体时对字体格式的兼容性各不相同,因此常常需要制作多种格式的字体,以便浏览器可以根据需要进行选择性的加载。
/* iconfont.cn 生成的样式文件大致如下:*/
@font-face {
font-family: "iconfont";
src: url('iconfont.eot'); /* IE9 */
src: url('iconfont.eot#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('iconfont.woff2') format('woff2'),
url('iconfont.woff') format('woff'),
url('iconfont.ttf') format('truetype'), Chrome、Firefox、Opera、Safari、Android系统以及iOS 4.2及以上版本。
url('iconfont.svg#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family: "iconfont" !important;
}
.icon-flag:before {
content: "\e233";
}
在 HTML 中使用:
class="icon-flag">
字体图标在维护上存在一定难度,然而,与“雪碧图”相比,它展现出诸多显著的优势:
但我们可以看出,这个方案对使用者的工程能力已经有所要求。尽管当前许多行业内的前端团队已经具备了基本的工程化技能,并开始运用Grunt、Gulp等工具,基于Node和npm来构建各自的工程化策略,然而,单独对每个图标进行编码以及生成相应的CSS代码,工作量就已经相当可观,更不用说制作多种格式的字体文件,这对于一般工程师来说几乎是一项无法着手完成的任务。这恰恰是.cn受到众多用户青睐的关键所在。用户对第三方平台的过度依赖,以及自行搭建所需的高昂成本,都导致了图标维护方面仍存在不少难题。
此外,尽管字体图标在一定程度上缓解了“雪碧图”带来的用户体验难题,但同时也引入了新的挑战:,
字体文件的加载过程较为耗时,在此期间,图标无法正常展示,导致内容出现频繁闪烁。尤其在部分浏览器中,若图标位于私有使用区域,在默认字体设置下,可能会以方块字符的形式呈现。
这幅图片来源于该网址:https://.blog/,发布于2016年2月22日,采用了SVG格式。
这一点与“雪碧图”存在诸多相似之处。尽管我们能够借助data URI将资源直接嵌入,实际上在相当长的一段时间里,我们确实采用过将图片或字体通过data URI进行编码并嵌入HTML的方法来减少加载时的延迟,然而这种编码方式会导致内容体积增加大约三分之一,实际上只是一种权衡与折衷。字体图标生成涉及众多格式,若将其内嵌于HTML页面,网页性能无疑会受到严重影响。
针对视力受损并依赖读屏软件的用户而言,因为字体图标实质上是由字符构成的,不管字体是否已经成功加载,读屏软件都无法准确读取其信息。在默认设置中,甚至可能错误地读出“”等不恰当的内容。试想,若一个网站广泛采用字体图标却未对每个图标添加相应的 aria- 语义标签,这无疑会给读屏软件用户带来极大的困扰。
SVG 图标
SVG 拥有固有的可扩展性(即 SVG 中的“S”特性),这使得它非常适合用于制作图标。此外,SVG 作为文本格式,众多矢量图形编辑软件均能将其导出,设计师因此能直接将文件交付给工程师,无需再创建字体文件,从而显著减轻了在维护方面的难题。然而,若将 SVG 当作普通图片来处理,通过
仅通过引入CSS中的图像方式,或者说是通过使用CSS-image技术,这些优势虽然存在,但单凭这些还不足以动摇图标字体的稳固地位。
内联 SVG
SVG的真正优势在于,一旦将其嵌入到HTML内容中,它的文档结构便能够被页面上的和CSS所访问与操控。这一特性为网络图标的发展开辟了全新的领域:,
相比于通过图片资源加载或者图标字体,只有一个劣势:
尽管内联SVG具备众多优点,然而目前阶段,在开发过程中运用它们并不像字体图标那样简便快捷(只需引入CSS,前端便可以随意使用),而是需要针对工程项目进行一定程度的干预。2016年,我们全面推行了内联SVG的方案,其技术架构采用Ruby后端渲染,并通过服务端脚本中的函数来调用图标字体。
<%= octicon(:symbol => "plus") %>
输出:
SVG
鉴于 SVG 允许使用一个特定的元素来提取内嵌 SVG 中的特定部分,从而将其独立出来进行展示,因此,受到 CSS 设计理念的启发,人们创造了一种 SVG 的解决方案。此方案中,只需将整个 SVG 的资源内联即可。
使用时:
同时,存在众多依托于Grunt、Gulp等工具的构建策略,它们能够高效地生成SVG文件。
这种方式主要的问题在于:
前端组件框架的时代
我们终于步入了当前的时代,这个时代的特点是网页渲染逻辑已转移到前端,前端开发领域主要由组件化框架引领。在React、Vue等众多框架的应用中,我们已养成习惯,将视图逻辑分解并借助组件进行复用。通过设计图标组件,我们自然而然地对底层方案进行了封装,并向前端提供了更为简单直观的 API 以便使用图标。需注意的是,这一做法并未从根本上改变 web 图标渲染的方法,其底层依然依赖前文所述的多种方案。即便在不采用这些视图层框架的项目中,我们依然需要依赖上述低层级的实现来进行开发。
当然,从多角度进行综合考量,采用封装的内联SVG应当是当前最为理想的选择。上文提到的后端方案与当前的前端技术方案相匹配,本质上就是依托于内联SVG的图标组件。在npm上sketch导出svg图标,目前众多基于不同组件框架开发的图标组件,其中包括某些知名框架,都已内置了SVG、React/Vue组件等更为先进的解决方案。
既然内联SVG已较好地解决了体验上的问题,因此我们现在可以更专注于提升研发效率、保持一致性和优化开发体验。根据百度内部过往的实践经验,我们遇到了以下几个问题:
理想情况下,我们希望达成如下目标:
在目前推进百度设计语言系统的过程中,我们与工程效能团队携手合作,共同制定了一套完整的方案。
图标平台整体流程图标管理平台
该平台相当于一个基础的图标内容管理系统,能够实现图标库的建立与维护,而图标设计师则是负责在系统中进行图标的添加与管理工作。在数据更新完毕后,用户可以选择将当前的图标输出至API进行发布。该API提供图标库中图标的SVG源代码及相关信息,流程中涉及的主要使用者包括设计团队专用的插件和前端编译/发布系统。我们支持在图标库发布阶段设定需通知的编译服务,因此,若需要,不同用户还可自行定义编译发布的流程。
插件
我们向设计团队推出了联通图标管理平台的插件sketch导出svg图标,设计师可在该插件内迅速查找并选用所需的图标。借助我们的插件将在线标注稿导出后,标注稿上便会自动显示图标在图标平台上的独有标识码,这正是我们制作图标组件时使用的标识码,前端工程师可据此直接从图标组件库中导入相应的图标组件。
优化/编译/发布服务
这个服务在图标库 API 触发更新时主要做了三件事:
图标包模板
编译服务对包模板()仅有的约定是:
模板制作者需供给图标组件的详细实现方法,同时提供将图标信息转化为前端代码的构建工具脚本。在无特殊要求的情况下,直接采用我们提供的基于React、Vue等框架的组件模板,即可轻松实现高品质的前端图标组件。
编译服务执行完毕后,前端工程师仅需掌握以下信息:首先,所用的图标源自哪个npm软件包;其次,该图标的名称是什么。这样,他们便能迅速在前端项目中添加所需图标。此外,这一流程确保了设计师的设计稿与前端实现的统一性,同时,还能通过图标平台进行集中化的更新管理。
总结
我们前端工程师在Web产品中引入图标方面进行了诸多尝试,并开发出诸多辅助工具以优化协作流程。面对当前组件化开发的主流趋势,我们经过对多种方案的优劣分析,确立了一套适合当前情况的“最佳实践”。这套实践方案降低了流程中的沟通成本和人工操作错误率,确保了设计和实现的同步性。最后,希望本文的内容能给大家带来收获,谢谢。
本文作者信息如下:@顾轶灵,详细信息请参阅原文链接:https://mp..qq.com/s/Hw。
为你推荐
欢迎自荐投稿,前端早读课等你来。
如有侵权请联系删除!
Copyright © 2023 江苏优软数字科技有限公司 All Rights Reserved.正版sublime text、Codejock、IntelliJ IDEA、sketch、Mestrenova、DNAstar服务提供商
13262879759
微信二维码