特别声明:如果您喜欢小站的内容,可以点击申请会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!或添加QQ:874472854(^_^)
Icon图标在Web应用或Web页面中起着至关重要的作用。它除了起到一定装饰作用之外,还可以在不添加任何文本信息的情况之下向用户传达正确的含义。在当今的Web开发中,有许多不同的方式将图标运用于Web应用或Web页面上。同样,在社区中也有很多介绍Icon图标系统构建的方法,比如早期的雪碧图,字体图标以及SVG Sprites等。但是今天我想从不同的角度来和大家聊聊,如何基于React框架下构建属于自己的SVG图标系统。感兴趣的同学,欢迎继续往下阅读。
特别声明:如果你是基于Vue框架开发,你可以移步阅读《如何在Vue项目中使用SVG Icon》一文,当然,文章中提到的相关技术同样也适应于Vue体系以及其他的开发体系。
为什么选择使用SVG Icons
早在几年前,我在《Web中的图标》一文中就和大家一起探讨过图标在Web开发中的几种使用方式以及他们之间的利弊。其实随着CSS的@font-face
特性的到来,使用字体图标比使用雪碧图更受欢迎。但最近几年,随着客户端对SVG的支持越来越友好,不管是设计师还是开发者越来越觉得SVG图标要比字体图标还要更友好。在社区中有关于这方面的讨论也比较多,比如 @Chris Coyier的《Inline SVG vs Icon Fonts》和@Mallik Cheripally的《Inline SVG or Icon Fonts: Which One to Use》文章就做过详细的对比。
就算是到今天为止,这样的话题也没有停止过。不过我自己觉得,使用SVG Icon有以下几点优势:
- 可读性:SVG可以直接内联使用,开发者可以在SVG代码中直接添加
title
以及ARIA相关的特性,这极大地提高了可访问性(A11Y),特别是在仅用图标向用户传递信息的情况下。相比之下,字体图标在这方面就处于劣势(当然可以借画其他手段来实现A11Y的能力) - 清晰度:众所周知,SVG是矢量图,它不会因为不同的分辨率造成不清晰;而字体图标在一些显示器上不那么清晰。虽然使用CSS的
font-smoothing
让字体图标避免这种情况,但是“不完全将字体平滑化”,font-smoothing
属性是很难覆盖到 - 加载失败:可能很多同学都越到过,使用字体图标的时候,Web页面渲染的时候,字体图标会以一个带有
x
符号的方框替代的情况,这主要是因为跨域(CORS
)问题或Opera mini
造成字体文件加载失败引起的,这也是使用字体图标很蛋疼的地方。而在SVG中是不会出现这个现象 - 扩展性:对于字体图标,如果希望给图标某部分改变样式或加载动效,那么是不可能实现的;但SVG图标可以轻易做到。这主要是因为SVG是
XML
标记语言,可以像操作DOM一样操作SVG的元素,这样一来,就可以晚于给SVG图标的某部分改变样式(比如填充颜色),甚至添加动效
当然,SVG还有其他的优势。这也是SVG Icon被运用于Web开发中的主要原因之一。另外,如果你在Web开发当中,经常会用到图标的话,那么我们构建一个图标系统就变得尤其重要;还有一点,如果你以前就有一个字体图标系统,希望将它们换成SVG图标系统,那么接下来的内容就对你非常有用。
SVG使用姿势
SVG(或者说SVG图标)运用于Web有很多种方式,不过众多方式中更推荐于内联方式,特别是SVG图标的使用场景。
在当下Web开发一般都是基于一些JavaScript框架进行开发,比如说React,Vue等。这些前端开发框架允许我们将UI抽出来,构建成一个可复用的UI组件。这也意味着,我们可以创建一个通用的图标组件,并使用type
属性来指定SVG图标,然后以内联方式呈现在Web页面中。比如:
<Icon type="book" />
如何是在React框架下还可以直接将SVG文件当React组件使用:
import { ReactComponent as ReactLogo } from './logo.svg';
<ReactLogo className="App-logo" />
当然,具体的使用有很多种方式,正如《SVG在React中的运用》和《如何在Vue项目中使用SVG Icon》中所介绍的,我们可以直接将.svg
文件转换成Web组件使用。
特另声明,只要你是基于类似于Webpack来构建的项目,有很多方式将SVG转换成Web组件(不同的加载器,使用方式略有细微的差异)。
接下来,我们以几种不同的方式来看看怎么一步一步构建属于自己的SVG图标系统。注意,下面的内容都是基于React体进行开发的。
SVG Sprites
在《SVG在React中的运用》中我们介绍的几种将SVG自动转换为React组件的使用方式,虽然方式不同,但最终呈现在Web中的效果是一样的。文章中提到的几种方式都有着一个共性:
SVG内联到HTML!
他们有着一个最大的优势:直接将SVG文件转换为React组件,但也有着一个最明显的缺点,比如说,我在同一个页面不同的地方使用了同一个SVG图标组件,这个时候会有相同的代码插入到DOM中:
import {ReactComponent as Home} from 'home.svg'
const App = () => (
<>
<header>
<Home />
</header>
<!-- ... -->
<footer>
<Home />
</footer>
</>
)
export default App
这个时候,渲染出来的Web页面,你会发现在<header>
和<footer>
引入了两段相同的SVG代码,类似像下面这样:
<div id="root">
<header>
<svg t="1598444628462" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1160" width="200" height="200">
<path d="M950.153231 461.510311l-122.16073-111.794026-1.27984-1.087864 0-136.87889c0-10.110736-8.190976-18.365704-18.365704-18.365704l-82.549681 0c-10.110736 0-18.365704 8.190976-18.365704 18.365704l0 35.835521-5.11936-4.351456-150.829146-134.255218c-0.63992-0.575928-1.343832-1.023872-1.983752-1.471816-11.070616-8.766904-24.060992-13.43832-37.563305-13.43832-14.07824 0-27.51656 4.991376-38.971129 14.526184-0.127984 0.191976-0.31996 0.383952-0.511936 0.447944l-398.670166 352.595926c-10.55868 9.086864-12.926384 26.428696-5.247344 38.907137 7.67904 12.414448 22.525184 15.230096 33.083865 6.207224l398.350206-352.40395c0.063992 0 0.191976-0.127984 0.255968-0.191976C503.68104 151.149106 507.712536 149.613298 512 149.613298s8.31896 1.535808 11.710536 4.415448c0.191976 0.1279
如需转载,烦请注明出处:https://www.w3cplus.com/svg/create-svg-icons-system-width-react.html
如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!