热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

“易滑移”的SVG符号:如何制作它们(以及为什么)

ThewidespreadadoptionofSVGinmodernwebpageshasreallyrampedin2016thankstoits,filesize,scalab
SVG symbols

The widespread adoption of SVG in modern web pages has really ramped in 2016 thanks to its, file size, scalability and CSS.

凭借其文件大小,可伸缩性和CSS,SVG在现代网页中的广泛采用在2016年确实有所增加。

It can be used for icon systems (take a look at Build Your Own SVG Icons), although icon fonts, in some cases, can be preferable (some info here: The Great Icon Debate: Fonts Vs SVG).

它可以用于图标系统(请参阅“ 构建自己的SVG图标” ),尽管在某些情况下图标字体可能更可取(此处的一些信息: 伟大的图标辩论:字体与SVG )。

But SVG can also be used for logos or graphic elements (at least not overly complex ones) and its natural flexibility makes it a perfect solution for responsive sites (take a look at Sara Soueidan’s Making SVGs Responsive with CSS).

但是SVG也可以用于徽标或图形元素(至少不能过于复杂),其自然的灵活性使其成为响应站点的完美解决方案(请参阅Sara Soueidan的“ 使CSS响应 SVG ” )。

The use of SVG makes it possible to target and change the size and color of an entire element through CSS, but, unless your SVG code is embedded in your HTML page, you can’t modify a single portion of it in this way.

使用SVG可以通过CSS定位和更改整个元素的大小和颜色,但是,除非您的SVG代码嵌入到HTML页面中,否则您不能以这种方式修改其中的一部分

问题 ( The Problem)

Let’s look at a simpler example. Here we have an image that we need to display in a range of colors.

让我们来看一个简单的例子。 在这里,我们需要以多种颜色显示图像。

Same SVG shape. Different colors.

Of course, traditionally we would simply create three standalone images – each with a different flavor. But what if we wanted to use a single SVG file and style it at render time?

当然,传统上,我们只会创建三个独立的图像-每个图像具有不同的风格 。 但是,如果我们想使用单个SVG文件并在渲染时设置样式怎么办?

Furthermore, is there a way we make our image a ‘SVG symbol’ to take advantage of browser caching?

此外,有没有一种方法可以使我们的图像成为“ SVG符号 ”,以利用浏览器缓存?

I’m going to refer to this a “Reskinnable SVG symbol” – the “bones” of your SVG image remain the same but it’s easy to change the surface appearance.

我将其称为“可重新着色的 SVG符号” – SVG图像的“骨骼”保持不变,但很容易更改表面外观。

The perfect solution would be accessing symbol elements through a CSS selector and add some rules to them (the same method that we would have used with embedded SVG).

完美的解决方案是通过CSS选择器访问符号元素,并向它们添加一些规则(与嵌入式SVG所使用的方法相同)。

In the following sample, I’ve added a class (top, right, bottom and left) to each triangle, arranged the image as a symbol and tried to modify it thru CSS, in this way:

在以下示例中,我为每个三角形添加了一个类( top , right , bottomleft ),将图像布置为符号,并尝试通过CSS进行修改,方法是:

.top { fill: #356BA5; }
.right { fill: #357FD9; }
/* and so on... */

Unfortunately, at the moment this only works with Firefox, as the following Codepen demonstrates. The second image appears in tones of blue only on Firefox (I’ve embedded the symbol code in the pen for convenience, but we have the same results with external SVG files).

不幸的是,目前这仅适用于Firefox,如以下Codepen所示。 第二个图像仅在Firefox上显示为蓝色(为方便起见,我在笔中嵌入了符号代码,但是对于外部SVG文件,我们得到的结果相同)。

See the Pen svg element editing (demo 1) by Massimo Cassandro (@massimo-cassandro) on CodePen.

请参见CodePen上 Massimo Cassandro( @ massimo-cassandro ) 编写的Pen svg元素(示例1) 。

See the Pen SVG CSS styling (demo 1) by Massimo Cassandro (@massimo-cassandro on CodePen.

见笔SVG CSS样式(演示1)由马西莫卡桑德罗( @马西莫-卡桑德罗上CodePen 。

In large projects, where we may have many elements like that, maintenance issues are an important factor, so I’m always searching for a way to better organize project assets.

在大型项目中,我们可能会有很多类似的内容,维护问题是一个重要因素,因此我一直在寻找一种更好地组织项目资产的方法。

My goal was a pure CSS solution: the previous sample can be rewritten using a single-triangle-SVG to be rotated, moved and colored using CSS.

我的目标是纯CSS解决方案:可以使用单三角形SVG重写先前的示例,然后使用CSS对其进行旋转,移动和着色。

But I didn’t like this solution: it seems to me that it simply moves the problem, without solving it. How many real-world logos have components that all have the same shape?

但是我不喜欢这种解决方案:在我看来,它只是在解决问题而不解决问题。 现实世界中有多少个徽标具有相同形状的组件?

Sara Soueidan explains the problem much better then I do and offers us a clever solution using CSS variables. Unfortunately CSS variables are still an experimental technology and Microsoft browsers don’t support them.

Sara Soueidan比我更好地解释了这个问题,并使用CSS变量为我们提供了一个巧妙的解决方案 。 不幸的是CSS变量仍然是实验技术, Microsoft浏览器不支持它们 。

解决方案 ( The Solution)

As it often happens, the solution is so head-slappingly simple that it will make you feel stupid for not having thought about it before.

通常情况下,解决方案是如此简单,以至于您之前从未考虑过,这会让您感到愚蠢。

I came across it looking at the new Medium logo some months ago (it seems Medium has since changed their logo code – you’ll have to take my word).

几个月前,我看到它看着新的Medium徽标(此后,Medium似乎已经更改了其徽标代码-您必须相信我的话)。

qJVnVmr

You can see that Medium logo consists of four ‘shapes’, each filled with a different flat color. The B&W version is identical to the green one (except for the colour, of course).

您会看到中型徽标由四个“形状”组成,每个形状都填充有不同的纯色。 黑白版本与绿色版本相同(当然,除了颜色)。

The solution for having a single file for both versions was to simply build a symbol for each shape, each of them within the same viewBox.

对于两个版本都使用一个文件的解决方案是简单地为每个形状构建一个符号,每个符号都在同一个viewBox中

Let’s apply it to our example and create a symbol for each shape in our image. They all share the same viewBox of the whole image (0 0 54 54), so they place themselves in the right position without any additional instruction. Just take care to avoid fill, stroke, style etc. attributes in the symbol code).

让我们将其应用于示例,并为图像中的每个形状创建一个符号。 它们都共享整个图像的同一viewBox ( 0 0 54 54 ),因此它们无需任何其他说明即可将自己放置在正确的位置。 请注意避免在符号代码中使用fill , stroke , style等属性。














So now we can assemble them into a single SVG container:

现在,我们可以将它们组装到单个SVG容器中:






Each use element can be styled however you like, and, most importantly, it is compatible with all modern browsers:

每个use元素都可以随意设置样式,最重要的是,它与所有现代浏览器兼容:

See the Pen SVG CSS styling (demo 2) by Massimo Cassandro (@massimo-cassandro on CodePen.

见笔SVG CSS样式(演示2)由马西莫卡桑德罗( @马西莫-卡桑德罗上CodePen 。

That’s all.

就这样。

We just have to arrange our SVG files in this way. We can, of course, do it manually, but if you have to manage many graphic elements or you need to quickly edit and reuse them in more projects, you need a smarter and faster workflow. I’ve found my solution using Adobe Illustrator and a bit of Gulp.

我们只需要以这种方式排列我们的SVG文件。 当然,我们可以手动执行此操作,但是如果您必须管理许多图形元素,或者需要快速编辑并在更多项目中重复使用它们,则需要更智能,更快速的工作流程。 我已经使用Adobe Illustrator和一些Gulp找到了解决方案。

SVG Symbols构建工作流程 ( SVG Symbols building workflow)

The basics of this technique are the same I’ve just covered in my Build Your Own SVG Icons and Create an Icon Font Using Illustrator & IcoMoon articles, so take a look at them for the first steps.

该技术的基础与我在使用Illustrator和IcoMoon文章构建您自己的SVG图标和创建图标字体中所介绍的相同 ,因此请首先了解它们。

Say we have two elements, just like in the image below. Each of them is arranged in a specific artboard:

假设我们有两个元素,如下图所示。 它们每个都布置在特定的画板上:

Illustrator artboard

We gave them some color for convenience, although we know that the fill color (as well as, if there are any, the stroke one, the stroke size and so on) will be edited through CSS.

为了方便起见,我们给了它们一些颜色,尽管我们知道填充颜色(以及笔触一个,笔划大小等)(如果有的话)将通过CSS进行编辑。

Since each symbol must have its artboard, we now have to split each image in as many artboards as each colored part.

由于每个符号都必须有其画板,因此我们现在必须将每个图像分成与每个彩色部分一样多的画板。

This can be made very quickly in Illustrator, cutting each element, selecting the target artboard and choosing the Paste in place command.

这可以在Illustrator中很快完成,剪切每个元素,选择目标画板,然后选择“ 粘贴到位”命令。

Illustrator artboard

Note that each artboard has a specific name: it will be used for symbols IDs.

请注意,每个画板都有一个特定的名称:它将用于符号ID。

Now we can export our artboards to SVG using the brand new File → Exports → Export for screens command.

现在,我们可以使用全新的File→Exports→Export for screens命令将画板导出到SVG。

This is a really useful new tool of the latest Illustrator versions: it allows you to save each artboard or user-defined asset in many formats with a single command.

这是最新Illustrator版本中非常有用的新工具:它使您可以通过一个命令以多种格式保存每个画板或用户定义的资源。

Choose “Artboards” from the export panel, set “SVG” as output format and select the destination folder:

从导出面板中选择“画板”,将“ SVG”设置为输出格式,然后选择目标文件夹:

Symbols exporting

Each artboards will be exported as a single SVG file:

每个画板将作为单个SVG文件导出:

SVG files

Now we need to put together all files as SVG symbols and to delete some SVG attributes we don’t need: a little gulp script will help us to do so very quickly.

现在,我们需要将所有文件作为SVG符号放在一起,并删除一些不需要的SVG属性:一个小gulp脚本将帮助我们非常快速地做到这一点。

时间到了 ( Time for Gulp)

The next section is slightly more technical, but – if you’re up for it – it will give you a fast, clean way to produce versatile SVGs like this.

下一部分将稍微讲一点技术,但是-如果您愿意-它将为您提供一种快速,干净的方法来生产这种通用的SVG。

I’ve already written about Gulp on SitePoint, and you can also find a lot of resources on the web about Gulp installing and all related arguments, so I’ll assume you’ve already installed it and that you know what we’re talking about.

我已经在SitePoint上写过有关Gulp的文章 ,并且您也可以在Web上找到很多有关Gulp安装和所有相关参数的资源,因此,我假设您已经安装了Gulp,并且您知道我们在说什么关于。

Anyway, if you don’t like Gulp, you can also do all the following steps manually. I’ve done this many times before starting using Gulp: it is definitely a good way to learn and it’s more than enough in small projects or where a constant editing and maintenance work is not requested.

无论如何,如果您不喜欢Gulp,也可以手动执行以下所有步骤。 在开始使用Gulp之前,我已经做了很多次:这绝对是学习的一种好方法,并且在小型项目中或不需要进行持续的编辑和维护工作的情况下,这已经足够了。

So, we have some SVG files, each of them is arranged just like the example below (the d attribute has been shortened for convenience):

因此,我们有一些SVG文件,每个文件的排列方式都与下面的示例一样(为方便起见,缩短了d属性):




Our goal is to arrange all images as SVG symbols in a unique file while stripping away all the unwanted attributes:

我们的目标是将所有图像作为SVG符号排列在一个唯一的文件中,同时去除所有不必要的属性:


...
...

Beside Gulp, our job needs some other extensions:

除了Gulp,我们的工作还需要一些其他扩展:

  • First of all, gulp-svgstore and gulp-svgmin to combine and minify our svg files

    首先, gulp-svgstore和gulp-svgmin合并并缩小我们的svg文件

  • gulp-rename to adjust id names and to give our destination files a specific name. This module is particulary needed if you want to use the previous Illustrator SVG export command, we’ll cover it later.

    gulp重命名可调整id名称并为目标文件指定特定名称。 如果要使用以前的Illustrator SVG导出命令,则特别需要此模块,我们将在以后介绍。

Now we can arrange our Gulpfile (the code is also available as a public Gist):

现在我们可以安排我们的Gulpfile(该代码也可以作为公共Gist使用 ):

var gulp = require('gulp')
,rename = require('gulp-rename')
,svgstore = require('gulp-svgstore')
,svgmin = require('gulp-svgmin')
;
gulp.task('default', function() {
gulp.src(['svg_files/*.svg'])
.pipe(rename(function (path) {
path.basename = path.basename.replace(/__icon_prefix__/, '');
return path;
}))
.pipe(svgmin(function (file) {
return {
// https://github.com/svg/svgo/tree/master/plugins
plugins: [
{ cleanupIDs: { remove: true, minify: true } }
, { removeDoctype: true }
, { removeComments: true }
, { removeStyleElement: true }
, { removeDimensions: true }
, { cleanupNumericValues: { floatPrecision: 2 } }
, { removeAttrs: { attrs: ['(fill|stroke|class|style)', 'svg:(width|height)'] } }
]
//,js2svg: { pretty: true } // uncomment for readability
};
}))
.pipe(svgstore())
.pipe( rename('my-icons.svg') )
.pipe(gulp.dest('./'));
});

After the modules are loaded, we indicate the files we want to parse (svg_files/*.svg).

加载模块后,我们指示要解析的文件( svg_files/*.svg )。

SVGstore uses the name of each file to set the symbol id attributes (i.e. a file named umbrella.svg will become a symbol with id="umbrella"). If you are using the new Illustrator Export for screens panel, you can avoid the first rename command, since your files will be named exactly as the artboards they come.

SVGstore使用每个文件的名称来设置符号id属性(即,名为umbrella.svg .svg的文件将成为id="umbrella"的符号)。 如果您正在使用新的Illustrator 导出到屏幕面板,则可以避免使用第一个重命名命令,因为文件的名称将与它们附带的画板完全相同。

But older versions of Illustrator create file names by concatenating the Illustrator file name with the artboard name, so we’ll need to rename files removing the Illustrator file name prefix:

但是旧版本的Illustrator通过将Illustrator文件名与画板名称连接在一起来创建文件名,因此我们需要重命名文件,以删除Illustrator文件名前缀:

path.basename = path.basename.replace(/__icon_prefix__/, '')

Now we can clean our files. gulp-svgmin is the Gulp version of SVGO a “Nodejs-based tool for optimizing SVG vector graphics files” (Jake Archibald released an online version of SVGO that is really useful if you want to arrange your files manually).

现在我们可以清理文件了。 一饮而尽,svgmin是的咕嘟咕嘟版本SVGO一个“优化SVG矢量图形文件的NodeJS为基础的工具”(杰克·阿奇博尔德发布了SVGO的在线版本 ,如果你想手动排列文件真的有用)。

SVGO has a lot of configurable options (you can browse through all of them in the project page), but we are in need of just a few (you can, of course, customize the script according to your needs):

SVGO有很多可配置的选项(您可以在项目页面中浏览所有选项),但是我们只需要少数几个(当然,您可以根据需要自定义脚本):

  • cleanupIDs: removes all ids from your files

    cleanupIDs :从文件中删除所有ID

  • removeDoctype, removeComments and removeStyleElement: strip all doctypes comments and elements

    removeDoctype , removeCommentsremoveStyleElement :剥离所有doctypes注释和元素

  • removeDimensions removes all width and heights attributes if viewbox is present

    如果存在removeDimensions删除所有widthheights属性

  • cleanupNumericValues rounds numeric values to a sensible level of precision

    cleanupNumericValues数值四舍五入到合理的精度水平

  • removeAttrs removes all specified attributes

    removeAttrs删除所有指定的属性

Next, the files are passed to svgstore to be combined in a unique file, which is then renamed and saved.

接下来,将文件传递到svgstore ,以合并为唯一文件,然后将其重命名并保存。

After using it a few times, you should be able to arrange it in a few minutes for each project, and it will give you the ability to quickly rebuild your SVG symbols file any time you need to.

几次使用后,您应该可以在几分钟内为每个项目进行安排,它使您能够随时根据需要快速重建SVG符号文件。

This is an example of the result (even in this pen, I embedded the svg file for convenience, but you can safely link it as an external file):

这是结果的一个示例(即使在这支笔中,为了方便起见,我也嵌入了svg文件,但是您可以安全地将其链接为外部文件):

See the Pen svg css styling (demo 3) by Massimo Cassandro (@massimo-cassandro) on CodePen.

请参阅CodePen上 Massimo Cassandro( @ massimo-cassandro ) 撰写的Pen svg css样式(演示3) 。

有什么警告吗? ( Are there any caveats?)

Since this method is based on styling use elements, we have problems when they are removed by a polyfill, as we see in svg4everybody.

由于此方法基于样式use元素,因此在通过polyfill删除它们时会遇到问题,如svg4everybody中所示 。

In browsers that doesn’t support external symbols link (all IE), svg4everybody replaces all use elements with the content of the matching symbols. So all css rules that apply to use don’t take effect.

在不支持外部符号链接(所有IE)的浏览器中, svg4everybody会将所有use元素替换为匹配符号的内容。 因此适用于所有CSS规则, use不生效。

This can be solved adapting your CSS selectors to inner symbols element (path, circle, etc.), but it can be a little tricky.

可以通过使CSS选择器适应内部符号元素( path , circle等)来解决此问题,但这可能有些棘手。

额外奖励 ( Extra bonus)

There are infinite variants of this workflow: you can deal with strokes, text, etc.

此工作流程有多种变体:您可以处理笔画,文本等。

Another interesting feature to be explored is the use of Illustrator Symbols: they are exported as SVG symbols, and this opens up a lot of possibilities.

需要探索的另一个有趣功能是Illustrator符号的使用:它们以SVG符号的形式导出,这带来了很多可能性。

Illustrator Symbos in Bracket

Thanks for reading.

谢谢阅读。

翻译自: https://www.sitepoint.com/reskinnable-svg-symbols-how-to-make-them-and-why/




推荐阅读
  • 使用圣杯布局模式实现网站首页的内容布局
    本文介绍了使用圣杯布局模式实现网站首页的内容布局的方法,包括HTML部分代码和实例。同时还提供了公司新闻、最新产品、关于我们、联系我们等页面的布局示例。商品展示区包括了车里子和农家生态土鸡蛋等产品的价格信息。 ... [详细]
  • Iamusingafixedheightimagetofilladivwithgradientcolorusingsomethinglike:background:t ... [详细]
  • IveseenquestionsaboutIDEshere--WhichisthebestIDEforScaladevelopment?andWhatisthe ... [详细]
  • 在Kubernetes上部署JupyterHub的步骤和实验依赖
    本文介绍了在Kubernetes上部署JupyterHub的步骤和实验所需的依赖,包括安装Docker和K8s,使用kubeadm进行安装,以及更新下载的镜像等。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • 本文介绍了一种解析GRE报文长度的方法,通过分析GRE报文头中的标志位来计算报文长度。具体实现步骤包括获取GRE报文头指针、提取标志位、计算报文长度等。该方法可以帮助用户准确地获取GRE报文的长度信息。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
author-avatar
李玲玉1990020292
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有