inline svg想写介绍以及使用

2020-05-13 10:05:23

参考地址 inline svg的使用

inline svg是目前前端图标解决方案的最优解(当然不仅限于图标),而且使用方式也及其简单,只要将svg图标代码当成普通的html元素来使用即可,如:


<!-- 绘制右箭头 -->

<svg viewBox="0 0 1024 1024" height="1em" width="1em" fill="currentColor">

  <path d="M665.6 512L419.84 768l-61.44-64 184.32-192L358.4 320l61.44-64 184.32 192 61.44 64z" />

</svg>


<!-- 绘制边框 -->

<svg viewBox="0 0 20 2" preserveAspectRatio="none" width="100%" height="2px">

  <path d="M0 1L20 1" stroke="rgba(0, 0, 0, .5)" stoke-width="2px"></path>

</svg>

1

2

3

4

5

6

7

8

9

将上面的代码插入html文档即可以很简单地绘制出一些图标。


一般来说,使用inline svg作为图标使用时,想要保留svg的纵横比,可以只指定width属性,但是一般为了清晰都同时指定height属性。但如果是像上面绘制边框这种不需要保留纵横比的情形,可将preserveAspectRatio设置为none。


优势与使用方式

从上面的例子可以看到,将svg直接作为普通html元素插入文档中,其本质和渲染出一个div、span等元素无异,天生具有渲染快、不会造成额外的http请求等优势,除此之外还有以下优势之处:


样式控制更加方便

一般来说,我们为inline svg顶层的<svg>元素会设置以下几个属性:


height=“1em” width=“1em” 可以方便地通过设置父元素的font-size属性控制尺寸

fill=“currentColor” 可以方便地根据父元素或自身的color属性控制颜色

但是我们也可以为其内部的子元素单独设置样式,如:


svg path {

  fill: rgb(0, 153, 255);

}

1

2

3

在inline svg中仅有一个<path>元素时,上面的特性可能用处不大,但是如果某些svg是由多个元素构成时,可以将样式分别应用的特性就尤为宝贵了,很容易地就可以解决在字体图标中不可有多色图标的问题:


<style>

svg path {

  fill: rgb(0, 153, 255);

}

svg path.right {

  fill: rgb(30, 185, 133);

}

</style>


<svg viewBox="0 0 1024 1024" width="1em" height="1em" fill="currentColor">

  <path d="M256 51.2v256H153.6V512h51.2v51.2h-51.2v307.2H512v51.2H102.4V307.2H0v-256z"></path>

  <path d="M256 512h51.2v51.2H256zM358.4 512h51.2v51.2h-51.2z"></path>

  <path d="M460.8 102.4H1024V256H460.8zM460.8 460.8H1024v153.6H460.8V460.8zM460.8 819.2H1024v153.6H460.8V819.2z"></path>

</svg>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

动画控制细化

既然能够样式控制能够细化,那动画设置自然也能够具体到各元素,所以这一项严格意义上和上一项是一样的,但是动画算是样式中比较独立的一部分,所以此处单独拎出来阐述。


这里要说明一下,使用字体图标是可以应用动画的,不过那个动画是整体动画:


<!-- 字体图标整体动画 -->

<style>

/* 定义icon font */

.icon {

  font-family: 'iconfont' !important;

  /* ... */

}

.icon-smile:before {

  content: '\e938';

}


/* 定义动画 */

@keyframes loadingIcon {

  from {

    transform: rotate(0);

  }


  to {

    transform: rotate(360deg);

  }

}

.icon {

  animation: loadingIcon 2s infinite;

}

</style>

<i class="icon icon-smile"></i>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

上面的动画会将icon-smile图标整体做旋转,如果我们只是想对其中的部分应用动画就不行了。


而在inline svg中,只需为想要设置动画的部分元素设置class,然后在CSS中定义动画即可,如要查看针对svg某些部分应用动画,可查看此例。


如需对svg中各部分分别应用样式,则在设计svg时最好不要将各部分都编于一组,可以将应用相同样式的部分进行分别编组,其他不需要设置样式的部分编为一组,这样我们在应用样式时,只需为对应的<g>标签设置class属性即可。


一般在拿到svg文件后,推荐使用svgo优化svg代码,节省体积,但是如果我们需要针对性设置样式时则需要谨慎使用,因为优化代码会进行路径合并等操作,可能我们想要设置的子元素已经不是独立的了。


不必加载非必要资源

对于字体图标来说,首页就需要加载全部的字体文件;对于svg sprites来说,一般需要往<body>首位插入隐藏的一堆symbol或defs代码合集(可通过对index.html预插入或者通过js代码插入)。上述两种方式都相当于全量加载,对于用户来说可能根本“看不全”这些图标或代码。而通过inline svg的方式则不会,因为它是直接渲染在页面上,不涉及资源加载操作,不会造成浪费。


对单页面应用来说,配合如webpack的splitChunks配置可缩短首屏加载时间;对多页面应用来说优势更加明显,不必为每个页面都处理svg相关资源的引入。


inline svg的复用及组件化

上面提到inline svg的优势,但是也很容易看出其劣势:复杂,一个<p>可以很明显地表示一段文字,但是一个<svg>想要描述出一个图标就有些复杂了,想要表达内容愈丰富,插入文档中的代码段就愈复杂,虽然svg本身改动的频率不高,如有改动也是整体替换,但是它破坏了整个文件的可维护性。而且还存在多处引用同一个inline svg片段的情况,因为它基本上是由一些无规律的指令和数组组成的,故针对其进行全局搜索都不现实。所以同一个inline svg必须能够进行复用,而组件就是为了解决复用而生的,而且将inline svg封装成组件也相当简单,下面以Vue和React为例展示一下inline svg的组件实现:


React实现

// any-inline-svg-component.tsx

import React from 'react';


interface SVGIconProps {

  width?: string;

  height?: string;

  fill?: string;

  style?: React.CSSProperties;

  className?: string;

  onClick?: (event: React.MouseEvent<SVGSVGElement>) => any;

}


export default (props: SVGIconProps) => {

  return (

    <svg viewBox="0 0 1024 1024" {...props}>

      {/* 内部实现 */}

    </svg>

  );

}


// 使用inline svg组件

import AnySvgIcon from './any-inline-svg-component'

<AnySvgIcon width="16px" height="16px" />

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

Vue实现

// any-inline-svg-component.vue

<template>

  <svg viewBox="0 0 1024 1024" :width="width" :height="height" :fill="fill">

    <!-- 内部实现 -->

  </svg>

</template>

<script>

import { Vue, Prop, Component } from 'vue-property-decorator'


@Component

export default class AnySvgIcon extends Vue {

  @Prop({ default: '1em' }) public width!: string

  @Prop({ default: '1em' }) public height!: string

  @Prop({ default: 'currentColor' }) public fill!: string

  // 其他属性

}

</script>


// 使用inline svg组件

<template>

  <AnySvgIcon />

</template>

<script>

import { Vue, Component } from 'vue-property-decorator'

import AnySvgIcon from './any-inline-svg-component.vue'


@Component({

  components: {

    AnySvgIcon,

  },

})

class App extends Vue {

  // bala...

}

</script>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

请注意安装typescript和vue-property-decorator等依赖。


如果工程内使用svg较少,可手动将这些svg文件内容处理成相应的组件。但当工程内使用svg很多的话,可参考ant design icons的处理方式,将svg文件批量处理成相应的组件。


更多

上面的例子中,我们都写死了viewBox为0 0 1024 1024,这个属性是可以改变的,它只是定义了一个坐标系统,不代表占据页面的空间大小(由width、height指定),而且和设计svg文件时使用的画布大小有关,大家只要坚持一种设计风格即可,有关svg的设计,可参考字体图标的使用与设计。


inline svg是一个很强大的工具,不仅仅能用作图标,搭配上CSS和其特有的属性可以很简单地实现很多效果,大家多多探索。


参考

GitHub octicons迁移至SVG

inline svg和字体图标的对比

字体图标的使用与设计



  • 2019-10-14 21:18:57

    Comparable 的 使用

    要做这个呢,我们也是用到了Arrays.sort 这个排序的方法!但不同的是,我们之前用的是int数组,现在我们用的是这个UserBean数组。如果你想对这个UserBean数组进行排序,你要多做一件事,就是让这个 UserBean类去 实现Comparable 的接口,并重写 里面  comparaTo 的方法。注意,这个接口是可以提供泛型的 ———————————————— 版权声明:本文为CSDN博主「sdn_bt496」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明

  • 2019-10-15 05:53:20

    xUtils 里的DbUtils使用心得

    使用xUtils做Android数据库开发非常简便和得心应手,而且它本身还支持很多查询功能,比如一对多,select count和自定义sql查询等,并且支持事务(默认关闭) 下面是官方sample给的代码和我的一些使用心得 首先是两个实体类,对应两张表,这两张表中有一对多的关系

  • 2019-10-15 09:18:48

    腾讯 Android 面试笔试总结

    Activity中的几种启动模式 Android消息机制 IntentService 事件分发 Android性能优化、内存优化 内存优化 View的绘制 Eventbus原理 Rxjava的操作符有哪些,说说他们的作用 线程锁 锁方法和类对象啥的有啥区别 AsyncTask原理 说说MVP和MVVM的特点 Android中用到的观察者模式有哪些地方 说说google新出的Lifecycle框架 okhttp原理 Retrofit原理 RecyclerView源码、缓存分析 Binder机制 Android Jetpack Kotlin Activity中的几种启动模式

  • 2019-10-15 09:20:49

    SpringBoot注解梳理

    @SpringBootApplication:包含了@ComponentScan、@Configuration和@EnableAutoConfiguration注解。其中@ComponentScan让spring Boot扫描到Configuration类并把它加入到程序上下文。 @Configuration 等同于spring的XML配置文件;使用Java代码可以检查类型安全。 @EnableAutoConfiguration 自动配置。 @ComponentScan 组件扫描,可自动发现和装配一些Bean。 @Component可配合CommandLineRunner使用,在程序启动后执行一些基础任务。 @RestController注解是@Controller和@ResponseBody的合集,表示这是个控制器bean,并且是将函数的返回值直 接填入HTTP响应体中,是REST风格的控制器。 @Autowired自动导入。 @PathVariable获取参数。 @JsonBackReference解决嵌套外链问题。 @RepositoryRestResourcepublic配合spring-boot-starter-data-rest使用。

  • 2019-10-15 09:52:00

    动图解释递归,按值传递和按引用传递的区别,线性查找和二分查找,二叉查找树

    对于大部分人,数据结构一直是一个短板,当然我也是,不是学不会,而是容易忘,就拿最简单的排序来说吧,当时学习的时候明明已经弄得很清楚了,过了一段时间不用又忘记了,还要重新再看一遍,不知道有多少小伙伴和我有一样的烦恼。今天让我们用用动图的方式学习一下数据结构中的递归和二分查找吧,这种讲解方式非常生动,而且非常容易记住和理解。