自 <体>京韩自体脂肪移植植什么地方可以做?

用CSS给SVG &use&的内容添加样式
一篇深入探究如何给SVG &use& 元素的内容添加样式的文章,并针对碰到的问题逐一解决。
SVG图形的一个最常见用例是图标系统,其中最常用的SVG sprite技术就是使用SVG &use& 元素在文档中任意位置 “实例化”图标 。
使用 &use& 元素实例化图标或任何其它的SVG元素或图像,给元素添加样式时经常会碰到一些问题。这篇文章的目的是尽可能给你介绍一些方法来解决:使用 &use& 引入的内容添加样式受限的问题。
但是在开始之前,我们先快速浏览一下SVG的主要结构和分组元素,然后慢慢进入 use 的世界中,以及shadow DOM,然后重回CSS的怀抱。我们会逐步讲解为什么给 &use& 内容添加样式会比较麻烦,以及有什么好的解决方案。
SVG结构化、分组,以及在SVG中引用(重用)元素速览
SVG中有四个主要的元素用于在文档中定义、结构化和引用SVG代码。这些元素使得重用SVG元素变得容易,同时保持代码的简洁性和可读性。因为SVG的特性,这些元素和图形编辑器中的某些命令具有相同的功能。
这四个用于SVG分组和引用的主要元素是: &g& , &defs& , &use& 和 &symbol& 。
&g& 元素(“group”的简写),用于给逻辑上相联系的图形元素分组。从图形编辑器的角度,如Adobe Illustrator, &g& 元素提供了类似于分组对象的功能。你也可以把它想象成图形编辑器中图层的概念,因为一层也是一组元素。
当你想要应用某个样式,并希望这个样式能被组中的所有元素继承,分组元素 &g& 非常好用,特别是当你想要给某组元素应用动画,同时还需要保持它们彼此的空间关系的时候。
&defs& 元素用来定义你之后要重用的元素。当你想要创建某一类在文档中要多次使用的“模板”时,使用 &defs& 定义元素。在 &defs& 元件中定义的元素不会在画布中渲染出来,除非你在文档的某个位置调用了它们。
&defs& 可以用于定义很多东西,但是最主要的使用情景之一是定义类似渐变的图案,例如,使用这些渐变作为其它SVG元素的描边填充。它可以用来定义你想要在画布上渲染的任何元素。
&symbol& 元素结合了 &defs& 和 &g& 元素的优点,将定义模板的元素组合在一起,以便之后在文档中的其他位置引用。和 &defs& 不同, &symbol& 通常不用于定义图案,但是经常用于定义例如图标这样的标志,在整个文档中都可以被引用。
&symbol& 元素相比其它两个元素有一个非常重要的优点:它接受一个 viewBox 属性,可以让它在任何视窗中自适应大小缩放渲染。
&use& 元素用于引用文档中其它位置定义的元素。你可以重用已有的元素,类似于图形编辑器中的复制粘贴功能。它可以重用单个元素,也可以重用一组用 &g& 、 &defs& 或 &symbol& 定义的元素。
要使用一个元素,你需要通过一个标识对该元素进行引用——一个ID,即 use 中的 xlink:href 属性,以及用来给该元素定位的 x 和 y 属性。你可以给 use 元素应用样式,这些样式也会级联应用到 use 元素的内容中去。
&use& 的内容是什么呢?它被克隆到哪里了?CSS级联如何处理这些内容?
在我们回答这些问题之前,因为我们目前只讲了SVG结构化和分组元素,这里还有几篇值得我们继续深入学习的文章,关于 viewBox 属性和 &symbol& 的使用:
Structuring, Grouping, and Referencing in SVG — The &g& , &use& , &defs& and &symbol& Elements
理解SVG坐标系和变换:视窗,viewBox和preserveAspectRatio
SVG &use& 及shadow DOM
当你使用 &use& 引用元素时,代码如下:
&symbol id=&my-icon& viewBox=&0 0 30 30&&
&!-- icon content / shapes here --&&/symbol&&use xlink:href=&#my-icon& x=&100& y=&300& /&
渲染在屏幕上的东西是内容定义在 &symbol& 内的图标,但是这不是真正渲染出的内容,而是 &use& 的内容,也就是 &symbol& 内容的一个副本或者克隆。
但是 &use& 元素只是一个元素,它是自闭合的。在 use 标签的开闭区间内没有任何内容,所以 &symbol& 的内容是克隆到哪里了呢?
答案是: Shadow DOM 。(不知道为什么,shadow DOM总是让我想起蝙蝠侠 (:зゝ∠) 。)
什么是shadow DOM?
shadow DOM和常规的DOM很类似,不同之处在于shadow DOM不是主文档子树的一员,shadow DOM中的结点属于文档片段,基本上等同于另一棵结点树,不能像普通结点那样添加脚本和样式。这给了作者们一种方法来封装和包裹样式及脚本,当创建模块化组件时。如果你使用过HTML5的 video 元素,或range input类型,也很好奇video控件或者范围输入组件是从哪里来的,那么你就已经接触过shadow DOM了。
在SVG &use& 元素中,引用元素的内容被复制到一个文档片段中保存,这个文档片段是由 &use& 保留着。 &use& 在这里就是一个shadow Host。
所以, &use& 的内容(克隆或复制那个它引用的元素的)都表示在一个shadow文档片段中。
也就是说,它们就在那里,但是并不可见。就像普通的DOM内容一样,但是并不是在“高等级”的DOM中,并不能在主文档中被CSS选择器和JavaScript选中,它们被复制到由 &use& 保留的文档片段中。
现在,如果你是一个设计师,你可能会想:“ok,我了解了这东西了,但是有什么方法可以检查子文档,来看看它的真正的内容呢?”答案是:有的!你可以使用Chrome的开发者工具预览shadow DOM的内容。(现在还无法在Firefox中查看shadow DOM的内容。)但是为了完成这个,你需要先在“General”面板中勾选shadow DOM检查的选项。也就是:打开 Chrome 的开发者工具,点击右上角的“Settings”按钮勾选“Show user agent shadow DOM”。
在开发者工具中勾选了shadow DOM检查这一项之后,你可以在Elements面板中看到克隆的元素,和普通的DOM元素一样。下面的图片展示了 &use& 元素引用 &symbol& 元素的内容的示例。注意到有一个“#shadow-root”,而且当点开此片段的内容时——会发现它就是 &symbol& 内容的副本。
检查一下这些代码,你可以看到shadow DOM和普通的DOM非常相似,除了在主文档中用CSS和JavaScript处理时有不同的特性之外。它们之间还存在其它差异,但是这一节不可能完全在讲shadow DOM,因为这真的是一个很大的概念,所以如果你想要阅读和了解更多关于它的内容的话,我推荐下面这几篇文章:
Intro to Shadow DOM
What the Heck is Shadow DOM?
Shadow DOM 101
Introduction to Shadow DOM (Video)
图灵社区的同学翻译的shadow DOM系列 文章 。
对我来说,考虑如何限制和shadow DOM的交互时,我把它当成普通DOM一样,除了在用CSS(和JavaScript)添加样式时需要不同地处理。但是对于SVG开发者来说就是一个问题:shadow DOM中 &use& 的内容如何存在,当需要给内容应用样式或者改变样式的时候,因为我们希望可以为它们添加样式。使用 &use& 的目的是为了可以创建某个元素的多个不同的“副本”,很多情境下,我们想要的是可以给差异化地给不同的副本添加样式。例如,考虑一个有两种样式的logo(反转颜色的主题)或多种颜色的icon,每一个都有自己的主题。这时,我们自然而然就会想到使用CSS来完成。
也就是说,我们前面提到的shadow DOM的内容在CSS看来不能像普通DOM一样添加样式。所以,我们要怎么给它的内容添加样式呢?我们不能像这样指向 &use& 的路径级联:
use path#line {
stroke: #009966;}
因为我们不能使用普通的CSS选择器来获取shadow DOM。
有一组 特殊的选择器 可以让我们打破普通DOM的界限,给它里面的结点应用样式,但是这些选择器并 没有很好的浏览器支持 ,而且相比CSS中提供的一长串用来选中普通DOM元素的选择器,它们是受限的。
此外,我们希望有一个更简单的方式来给SVG &use& 的内容添加样式,而不需要去接触shadow DOM的具体内容——只使用简单的CSS和SVG。
为了实现以及获得更多一点控制,给 &use& 的内容添加样式,我们需要从不同的角度思考,借用CSS级联和继承的优势。
因为SVG元素可以使用CSS通过三种不同的方法之一进行添加样式:外部的CSS样式(在外部的CSS文件中),内部样式块( &style& 元素包裹),以及内联样式(在元素的 style 属性中)。重点在于这些级联管理是如何将样式应用到元素之上的。
除了CSS属性,SVG元素还可以使用描述属性添加样式。描述属性是在元素上设置CSS属性的简写方式。可以认为它们是特殊的样式属性。它们的目的就是给样式级联做贡献,但是可能正走在一个我们不太期望的方向上。
在下面的代码片段中,简单地展示了一个粉色的带黄色描边的圆。 stroke , stroke-width 和 fill 都是描述属性。
&svg viewBox=&0 0 100 100&&
&circle fill=&deepPink& stroke=&yellow& stroke-width=&5& cx=&50& cy=&50& r=&10&&&/circle&&/svg&
在SVG中,所有CSS属性的子集可以通过SVG属性设置,反之亦然。这意味着,不是所有的CSS属性都可以被指定给SVG元素作为描述属性,也不是所有SVG支持的描述属性都可以在CSS中指定,虽然有很多都可以。
SVG规范列出了 可以设置为CSS属性的SVG属性 。其中一些属性可以和CSS共享(也就是已经可以作为CSS属性),如 opacity 和 transform ,有一些还不行,如 fill 、 stroke 和 stroke-width 。
在SVG 2中,这个列表将包括 x 、 y 、 width 、 height 、 cx 、 cy ,以及一些其它的描述属性,目前还不能在SVG 1.1中通过CSS来设置的。新的属性列表可以在 SVG 2规范 中找到。
如果你和我一样,那么你一定会期待描述属性可以有相比其它样式声明更高的特殊性。我的意思是,毕竟,外部的样式可以被内部的样式块覆盖,内部的样式块又可以被 style 属性设置的内联样式覆盖。那么这看起来是不是越“内层”的样式,优先级就越高。所以如果一个属性有了自己的特性,它是不是就更强大,因此它也就可以覆盖所有其它的样式声明。尽管这对我来说是非常棒的,但是它真正的工作原理却不是这样的。
事实上,描述属性算是比较低层级的“作者样式层叠表”,可以被其它 所有 的样式定义覆盖:外部的样式表,内部的样式块以及内联样式。描述属性唯一超过的就是继承样式。就是说,描述属性只可以覆盖文档中的继承样式,但是会被其它所有的样式声明覆盖 (:зゝ∠) 。
好滴~既然我们现在弄清楚了,我们回到 &use& 元素以及它的内容上吧。
我们现在知道我们不同使用CSS选择器给 &use& 中的元素设置样式。
我们知道,正如 &g& 元素,你应用给 &use& 的样式将会被它所有的后代内容继承(也就是shadow DOM中的内容)。
所以第一个改变 &use& 内元素的 fill 颜色的尝试就是给 &use& 元素本身应用此填充颜色,并让其继承和级联。
但是,这带来了两个问题:
该填充颜色将被 &use& 的所有后代内容继承,甚至包括那些你并不想给它们应用样式的内容(如果你的 &use& 中还没有任何元素,那么这就不成问题。)
如果是通过图形编辑器导出,或者是从其它设计师手中拿到的SVG,简单来说,就是你不能接触到SVG源码,那么你可能就没办法给SVG元素应用描述属性了(除非你明确指出你不希望在输出SVG的时候发生这个事情,但这是另一个话题了),这些属性的值将覆盖你给 &use& 应用的所有样式。现在,我假设如果你给 &use& 指定了样式,而且希望这些样式可以被它的后代继承,那么描述属性可能会给你带来不便。
即使你可以获取SVG的代码,你也可以摆脱描述属性,我强烈建议不要这样做,因为:
删除那些用于设置某些属性的特性 (:зゝ∠) ,将会导致这些属性被重置为初始的浏览器默认值——也就是,一般情况下,所有都是黑色填充和描边(比如我们现在讨论的是颜色)。
通过重置所有值,你可以强迫自己去给所有属性集指定样式,所以除非你想这么做,否则你不要想摆脱这些描述属性了。
描述属性设计的初衷是作为一项降级机制,用于当你的外部样式因为某些原因不能应用的时候。如果CSS因为某些东西给搞砸而不能加载的时候,你的图标至少可以有些默认的相对漂亮的样式可以降级。这点我强烈建议保留它们。
好了,现在我们有这些属性了,但是我们还想针对不同的实例应用不同的样式,比如说,不同的图标。
需要做的就是确保我们强制描述属性继承了设置于 &use& 之上的样式,或者找到一个方法来让它们覆盖这些值。为了做到这一点,我们需要利用CSS的优势。
我们从最简单的实例开始,然后慢慢进入到更复杂的情景。
CSS描述属性值的介绍
描述属性可以被其它任何的样式声明覆盖。我们可以利用这个优势,用一个外部的样式声明,强制描述属性覆盖从 use 继承的值。
通过使用CSS
inherit 关键字
,这会变得非常简单。看看下面的例子,我们绘制了一个冰淇淋的图标,只用一条路径完成,而且可以根据不同的情况改变填充颜色。这个图标是Erin Agnoli在 Noun项目 中创建的。
&symbol id=&ic&&
&path fill=&#000& d=&M81,40.933c0-4.25-3-7.811-6.996-8.673c-0.922-5.312-3.588-10.178-7.623-13.844
c-2.459-2.239-5.326-3.913-8.408-4.981c-0.797-3.676-4.066-6.437-7.979-6.437c-3.908,0-7.184,2.764-7.979,6.442
c-3.078,1.065-5.939,2.741-8.396,4.977c-4.035,3.666-6.701,8.531-7.623,13.844C22.002,33.123,19,36.682,19,40.933
c0,2.617,1.145,4.965,2.957,6.589c0.047,0.195,0.119,0.389,0.225,0.568l26.004,43.873c0.383,0.646,1.072,1.04,1.824,1.04
c0.748,0,1.439-0.395,1.824-1.04L77.82,48.089c0.105-0.179,0.178-0.373,0.225-0.568C79.855,45.897,81,43.549,81,40.933z
M49.994,11.235c2.164,0,3.928,1.762,3.928,3.93c0,2.165-1.764,3.929-3.928,3.929s-3.928-1.764-3.928-3.929
C46.066,12.997,47.83,11.235,49.994,11.235z M27.842,36.301c0.014,0,0.027,0,0.031,0c1.086,0,1.998-0.817,2.115-1.907
c0.762-7.592,5.641-13.791,12.303-16.535c1.119,3.184,4.146,5.475,7.703,5.475c3.561,0,6.588-2.293,7.707-5.48
c6.664,2.742,11.547,8.944,12.312,16.54c0.115,1.092,1.037,1.929,2.143,1.907c2.541,0.013,4.604,2.087,4.604,4.631
c0,1.684-0.914,3.148-2.266,3.958H25.508c-1.354-0.809-2.268-2.273-2.268-3.958C23.24,38.389,25.303,36.316,27.842,36.301z
M50.01,86.723L27.73,49.13h44.541L50.01,86.723z&/&
&/symbol&&/svg&
这个冰淇淋图标的内容(也就是 path )是定义在一个 &symbol& 元素中的,也就是说它们不会直接在SVG画布中渲染。
然后,我们使用 &use& 渲染出多个图标实例。
&svg class=&icon& viewBox=&0 0 100 125&&
&use class=&ic-1& xlink:href=&#ic& x=&0& y=&0& /&&/svg&&svg class=&icon& viewBox=&0 0 100 125&&
&use class=&ic-2& xlink:href=&#ic& x=&0& y=&0& /&&/svg&
我们在CSS中设置图标的宽度和高度。我使用了 viewBox 一样的尺寸,但它们也不是一定要相同的。但是,为了避免SVG内多余的空白太多,保持它们的宽高比。
width: 100
height: 125}
使用上面的代码,你可以得到下面的结果:
注意我给SVG添加了一个黑色的边框,这样大家才可以看到每个图的边界,我们定义的第一个SVG图标的内容并没有渲染。这里可以提出一点:你在 symbol 中定义的SVG文档也会在页面中渲染出来,即使它没有包括渲染图形。为了避免这一点,确保你在第一个SVG中设置了 display: none 。如果你没有隐藏包含图标定义的SVG,即使你没有明确设置任何尺寸,它也会被渲染出来——浏览器默认尺寸是 300x150px ,这是在CSS中没有替代元素时的默认尺寸,所以你会在页面上得到一块白色的区域,尽管你并不想要这块东西。
现在让我们试试改变每个图标实例的填充颜色:
use.ic-1 {
fill:}use.ic-2 {
fill: #FDC646;}
即使这样写了,图标的填充颜色还是不会有任何改变,因为继承的颜色值被 path 元素的 fill=&#000& 覆盖了。为了阻止这个东西,我们强制让 path 继承颜色值:
svg path {
瞧!我们给 &use& 元素设置的颜色现在可以逐个应用于 path 了。查看下面的demo,可以照自己喜欢的去改变颜色值,创建更多实例:
现在这种技术已经非常好用,当你想要强制 &use& 的内容继承你设置的样式时。但是在大多数情况下,这可能不是你想要的。还有很多其它添加样式的场景,所以我们接下来会介绍一些其它的方法。
使用CSS的 all 属性给 &use& 的内容添加样式
前段时间我使用一个引用自 use 的图标,我想让它里面的其中一个元素可以继承所有我给 &use& 设置的样式,像 fill 、 stroke 、 stroke-width 、 opacity 甚至 transform 。基本上,我希望可以控制所有这些CSS属性,同时保留标签中的描述属性作为降级。
如果你发现你也处在这样一个场景中,你可能会发现这用CSS做起来非常耗时间:
path#myPath {fill:stroke:stroke-width:transform:/* ... */}
看看上面的代码片段,你可以看到都是同一个模式,我们应该可以把所有这些属性结合起来,放到一个属性中,并把所有这些属性的值设置为 inherit 。
幸运的是,这就是CSS的 all 属性发光发热的时候了。我之前写过关于使用 all 属性来给SVG的 &use& 内容添加样式的 参考条目 ,但是因为我们现在的上下文环境,我们需要再看看。
使用 all 属性,我们可以这样写:
path#myPath {
这在所有支持 all 属性的浏览器中都工作得非常好(详细信息请查看属性参考条目),然而还有几个重点要记住:这条声明会真正地给元素的所有属性都设置从父元素继承值,包括那些你可能不想要的属性。所以除非你想要在CSS中给元素的所有属性都设置样式,否则你就不要使用它——这是一种极端的措施,当你想要暴露你的元素,然后在CSS中对它的样式属性进行完全的控制的时候才使用,这种情况比较少见。如果你使用这条声明,不在CSS中指定所有属性的值,它们就会直接往上然后级联,知道它们找到可以继承的值,大多数情况下就是浏览器的默认样式,从默认用户代理样式表加载而来。
注意这只会影响到那些可以在CSS中设置的属性,不包括那些SVG独有的属性。所以如果一个属性可以作为CSS属性设置,它就会被设置为 inherit ,否则就不会。
能够强制描述属性去从 &use& 继承样式是强大的,但是如果你的图标是由多个元素组成的呢,你肯定不想要让所有的这些元素都从 use 继承同一个 fill 颜色吧?那如果你想要给不同的 use 级联应用多个填充颜色怎么办呢?给 use 设置一个样式已经不足够了,我们需要一些其它的东西来帮助我们从正确的元素级联正确的颜色。
使用CSS的 currentColor 变量来给 &use& 内容添加样式
currentColor 变量
,并结合上面的技术,我们可以给一个元素指定两种不同的颜色,而不仅是一种。Fabrice Weinberg在他的CodePen blog写了一些关于这种技术的 文章 。
有关于 currentColor 更多信息,可以参阅早前的一篇译文《 使用CSS的currentColor变量扩展颜色级联 》。
这种技术的内幕其实是在 &use& 上同时使用 fill 和 color 属性,然后利用 currentColor 的变量特性,让这些颜色级联到 &use& 的内容上。我们先看一个代码实例,看看这是怎么搞的先。
假设我们要给这个小小的Codrops的logo添加两种颜色的样式——一个用于前面的水滴,一个用于后面的——logo的每一个实例都是采用两种颜色。
首先,我们从上面的代码截图开始:用 symbol 包裹我们的图标定义,然后使用三个 &use& 创建三个logo实例。
&svg style=&display:&&&symbol id=&codrops& viewBox=&0 0 23 30&&
&path class=&back& fill=&#aaa& d=&M22.63,18.261c-0.398-3.044-2.608-6.61-4.072-9.359c-1.74-3.271-3.492-5.994-5.089-8.62l0,0
c-1.599,2.623-3.75,6.117-5.487,9.385c0.391,0.718,0.495,1.011,0.889,1.816c0.143,0.294,0.535,1.111,0.696,1.43
c0.062-0.114,0.582-1.052,0.643-1.162c0.278-0.506,0.54-0.981,0.791-1.451c0.823-1.547,1.649-2.971,2.469-4.33
c0.817,1.359,1.646,2.783,2.468,4.33c0.249,0.47,0.513,0.946,0.791,1.453c1.203,2.187,2.698,4.906,2.96,6.895
c0.292,2.237-0.259,4.312-1.556,5.839c-1.171,1.376-2.824,2.179-4.663,2.263c-1.841-0.084-3.493-0.887-4.665-2.263
c-0.16-0.192-0.311-0.391-0.448-0.599c-0.543,0.221-1.127,0.346-1.735,0.365c-0.56-0.019-1.095-0.127-1.599-0.313
c1.448,3.406,4.667,5.66,8.447,5.78C19.086,29.537,23.469,24.645,22.63,18.261z&/&
&path class=&front& fill=&#ddd& d=&M6.177,11.659c0.212,0.367,0.424,0.747,0.635,1.136c0.164,0.303,0.333,0.606,0.512,0.927
c0.683,1.225,1.618,2.898,1.755,3.937c0.144,1.073-0.111,2.056-0.716,2.769c-0.543,0.641-1.315,1.014-2.186,1.067
c-0.87-0.054-1.643-0.43-2.186-1.067c-0.604-0.713-0.858-1.695-0.715-2.771c0.137-1.036,1.072-2.712,1.755-3.936
c0.18-0.32,0.349-0.623,0.513-0.927C5.752,12.404,5.964,12.026,6.177,11.659 M6.177,5.966L6.177,5.966
c-1.02,1.649-2.138,3.363-3.247,5.419c-0.932,1.728-2.344,3.967-2.598,5.88c-0.535,4.014,2.261,7.09,5.846,7.203
c3.583-0.113,6.379-3.189,5.845-7.203c-0.255-1.912-1.666-4.152-2.598-5.88C8.314,9.329,7.196,7.617,6.177,5.966L6.177,5.966z&/&&/symbol&&/svg&&svg height=&90px& width=&69px&&
&use xlink:href=&#codrops& class=&codrops-1&/&&/svg&&svg height=&90px& width=&69px&&
&use xlink:href=&#codrops& class=&codrops-2&/&&/svg&&svg height=&90px& width=&69px&&
&use xlink:href=&#codrops& class=&codrops-3&/&&/svg&
如果我们想要给 &use& 元素的每个实例设置 fill 颜色,该颜色将会两条路径都继承,最后它们就会有相同的颜色——这不是我们想要的。
所以我们不仅要指定 fill 颜色,还要让它按照默认方法级联,然后使用 currentColor 变量来确保icon前面的小水滴获取和背景不同的颜色值:该值通过 color 属性指定。
首先,我们需要在我们想要应用该颜色值的地方插入 currentColor ;进入定义图标内容的标签,在 &symbol& 中。代码如下:
&svg style=&display:&&
&symbol id=&codrops& viewBox=&0 0 23 30&&
&path class=&back& fill=&#aaa& d=&...&/&
&path class=&front& fill=&currentColor& d=&...&/&
&/symbol&&/svg&
下一步我们需要从另一个水滴中删除 fill 描述属性,并让它从 use 继承 fill 颜色,而不是使用 inherit 技术。
如果我们要使用 inherit 关键字来强制描述属性从 use 继承值,两条路径都会继承相同的值,这样 currentColor 就不会再产生任何效果。所以,在这种技术中,我们需要删除我们想要在CSS中设置的属性,只保留那个我们想要使用 currentColor 设置的值。
&svg style=&display:&&
&symbol id=&codrops& viewBox=&0 0 23 30&&
&path class=&back& d=&...&/&
&path class=&front& fill=&currentColor& d=&...&/&
&/symbol&&/svg&
现在,在 &use& 上使用 fill 和 color 属性,给水滴添加样式:
.codrops-1 {
fill: #4BC0A5;
color: #A4DFD1;}.codrops-2 {
fill: #0099CC;
color: #7FCBE5;}.codrops-3 {
fill: #5F5EC0;
color: #AEAFDD;}
每个 &use& 元素有自己的 fill 和 color 值。对单个水滴来说, fill 颜色级联并被没有 fill 属性的第一条路径(后面的水滴)继承, color 属性的值被作为第二条路径(前面的水滴)的 fill 属性的值。
所以当前颜色值被引用到 &use& 元素里边,使用 currentColor 。漂亮整洁,对吗?
这是上面代码的demo:
这种双色变量技术对于简单的双色标志非常好用。在Fabrice的文章中,他创建了三个不同的sass logo,通过改变文本的颜色和背景颜色。
currentColor 关键字目前只在CSS变量中支持。但是,如果我们有更多的变量,是不是就可以分配和释放更多的值到 &use& 内容中呢?对的!Amelia Bellamy-Royds在 CodePen blog的文章 中介绍了这个概念,大概一年多之前。我们来看看它是如何工作的。
将来:使用CSS自定义属性给 &use& 内容添加样式,即CSS变量
使用 CSS自定义属性(即CSS变量) ,你可以给 &use& 的内容添加样式,而不需要强制浏览器覆盖任何描述属性的值。
如 MDN中定义 的,CSS变量可以是作者、或用户,定义的,web页面中包含整个文档中指定的值的实体。它们被设置了使用自定义属性,并通过一个指定的功能符号 var() 访问。和CSS预处理器(如sass)的变量非常相似,但是更灵活,可以 做预处理器变量不能做的事情 。(CSS变量很快将被添加到Codrops CSS参考条目中,敬请期待。)
变量,即CSS变量或预处理器变量,都可以有很多使用示例,但是主题(颜色)是最常见的用例之一。在这一节中我们将讲解在给SVG添加样式时如何使用它。
我们先从一张 symbol 中定义并通过 use 实例化的图像开始,并且只为这张图像应用这种技术;只要你想,这个示例中给 &use& 内容应用样式的概念,也可以被应用到很多 &use& 元素中。
现在,假设我们有如下这个可爱时髦的机器人插画, Freepik设计 ~
机器人的代码包括了这些组成颜色。
&svg style=&display: none&&&symbol id=&robot& viewBox=&0 0 340 536&&&path d=&...& fill=&#fff& /&&path d=&...& fill=&#D1312C& /&&path d=&...& fill=&#1E8F90& /&&path d=&...& fill=&#1E8F90& /&&path d=&...& fill=&#fff& /&&path d=&...& fill=&#6A4933& /&&path d=&...& fill=&#1E8F90&
/&&path d=&...& fill=&#6A4933& /&&path d=&...& fill=&#fff& /&&path d=&...& fill=&#6A4933& /&&path d=&...& fill=&#F2B42B& /&&path d=&...& fill=&#fff& /&
&!-- rest of the shapes --&&/symbol&&/svg&
现在,我们不打算使用CSS变量作为每条路径的 fill 属性的值;我们将使用CSS fill 属性作为其填充颜色值,并保留原位置的 fill 属性。这个属性将作为降级使用,在不支持CSS变量的浏览器中,这样这个图像在那些不支持变量的浏览器中,仍然能保留初始样式。
添加了变量之后,上面的代码变成如下:
&svg style=&display: none&&&symbol id=&robot& viewBox=&0 0 340 536&&&path d=&...& fill=&#fff& /&&path d=&...& fill=&#D1312C& /&&path d=&...& fill=&#1E8F90& style=&fill: var(--primary-color)& /&&path d=&...& fill=&#1E8F90& style=&fill: var(--primary-color)& /&&path d=&...& fill=&#fff& /&&path d=&...& fill=&#6A4933& style=&fill: var(--tertiary-color)& /&&path d=&...& fill=&#1E8F90& style=&fill: var(--primary-color)& /&&path d=&...& fill=&#6A4933& style=&fill: var(--tertiary-color)& /&&path d=&...& fill=&#fff& /&&path d=&...& fill=&#6A4933& style=&fill: var(--tertiary-color)& /&&path d=&...& fill=&#F2B42B& style=&fill: var(--secondary-color)& /&&path d=&...& fill=&#fff& /&&!-- rest of the shapes --&&/symbol&&/svg&
因为内联 style 标签会覆盖描述属性,支持CSS变量的浏览器会使用这些变量作为图形的填充颜色。不支持CSS变量的浏览器将使用 fill 属性值。
下一步,我们需要在CSS中定义变量的值。首先,插画需要使用 use 实例化:
&svg width=&340& height=&536&&
&use xlink:href=&#robot& id=&robot-1& /&&/svg&
然后,变量将会定义在 use 上,这样它们会被级联到内容上。你给变量选的颜色将会构成你的插画内容的颜色主题。所以,对于上面的机器人,构成图形有三种主要的颜色,我把它们命名为primary、secondary和tertiary。
#robot-1 {
--primary-color: #0099CC;
--secondary-color: #FFDF34;
--tertiary-color: #333;}
有这些变量,你仍然可以使用 fill 和 color 属性,但是你可能不需要或者根本不想要。所以,有了以上通过变量定义的颜色,我们的机器人如下:
你可以根据自己需要创建很多图像的副本,每个都定义一组不同的颜色,然后使用不同的颜色主题。当你想要给同一个logo根据上下文,以不同的方式为其添加样式时,或者任何其它相似的用例。
现在,我们提到那些不支持CSS变量的浏览器会降级到描述属性的初始样式,而不支持变量的浏览器将会使用 fill 属性来覆盖属性。ok!但如果浏览器不支持CSS变量,而且作者还没有为它们提供指定的变量值,或者他们提供的值是无效的,会发生什么呢?
对于我们这里的时髦可爱的机器人,我们定义了三个变量,只有图像中的一小部分元素没有获取任何变量,因为它们使用默认的颜色,任何颜色的主题都是非常漂亮的。所以,如果你在支持CSS变量的浏览器(目前只有Firefox)中展示上面的代码,然后从CSS中删除变量声明,你将会得到:
如果如果没有设置变量值或者变量值无效,浏览器会使用默认颜色,通常是黑色的填充和描边。
避免的方法是为浏览器支持提供另一种降级颜色。事实上,CSS变量的语法就可以做到这一点:在 var() 函数内部不要只提供变量值一条声明,你可以用逗号分隔提供两条声明:变量名和一个降级颜色值——在这里就是指我们在描述属性中使用的值。
所以,回到上面的机器人代码,如下:
&svg style=&display: none&&&symbol id=&robot& viewBox=&0 0 340 536&&&path d=&...& fill=&#fff& /&&path d=&...& fill=&#D1312C& /&&path d=&...& fill=&#1E8F90& style=&fill: var(--primary-color, #1E8F90)& /&&path d=&...& fill=&#1E8F90& style=&fill: var(--primary-color, #1E8F90)& /&&path d=&...& fill=&#fff& /&&path d=&...& fill=&#6A4933& style=&fill: var(--tertiary-color, #6A4933)& /&&path d=&...& fill=&#1E8F90& style=&fill: var(--primary-color, #1E8F90)& /&&path d=&...& fill=&#6A4933& style=&fill: var(--tertiary-color, #6A4933)& /&&path d=&...& fill=&#fff& /&&path d=&...& fill=&#6A4933& style=&fill: var(--tertiary-color, #6A4933)& /&&path d=&...& fill=&#F2B42B& style=&fill: var(--secondary-color, #F2B42B)& /&&path d=&...& fill=&#fff& /& &!-- rest of the shapes --&&/symbol&&/svg&
就是它了。对任何无法加载或没有定义值的变量,浏览器将会降级使用标签中定义的初始颜色。非常棒!
使用这种技术,你现在可以在页面上任何你想要的地方,使用 &use& 引用机器人。在CSS中为每一个新实例定义一组变量值,这样每个实例都会有一组不同的颜色主题。
你可以看看上面的demo,创建很多机器人副本,然后指定不同的变量值,只要确保你使用的是Firefox浏览器,因为在写这篇文章的当前()只有它支持CSS变量:
如果你是在Firefox中查看demo,你会看到我们用CSS变量定义的蓝色+黄色版本的机器人。记得在Chrome中查看其降级机制(绿色版本),然后在Firefox中尝试删除变量声明,看看降级如何。
呼~写了这么长。
利用CSS样式的优势,给 &use& 的内容添加样式——虽然在shadow DOM中可以不要这么复杂。用CSS变量(仅一个 currentColor 或自定义属性)我们可以进入到shadow DOM中,定制我们的图形,并提供非常好的降级机制。
就我个人而言,我非常喜欢捣鼓CSS变量+SVG的组合。我喜欢他们组合在一起时非常地强大,特别是考虑到它们强大的降级机制。它们目前只在Firefox中支持,正如我们提到的,但是如果你想要看它们得到更多的支持,你可以在 MS Edge User Voice forums 上为它们投票。
在将来我们可能会有其它的方法来给 use 内容添加样式,因为已经有很多这方面的讨论,关于使用CSS变量作为SVG的参数;所以这篇文章,虽然很长,而且可能没有涵盖到所有这方面的内容。如果你有什么其它的想法,请在评论中留言。
处理重用SVG元素的内容已经成为最热门的SVG话题之一,很多人都觉得很难处理,因为克隆的代码在对应的位置如何自然展示。涉及的和相关的话题非常多,但是这是其它文章要讨论的了。
希望你喜欢这篇文章,并能对你有所帮助,感谢阅读!
本文根据 @SaraSoueidan 的《
Styling SVG &use& Content with CSS
》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处: http://tympanus.net/codrops//styling-svg-use-content-css 。
在校学生,本科计算机专业。逗比一枚,热爱前端热爱生活,喜欢CSS喜欢JavaScript喜欢SVG,爱玩PS玩AI玩啊逗比的软件。努力向上,厚积薄发。
最新教程周点击榜
微信扫一扫}

我要回帖

更多关于 京韩自体脂肪移植 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信