SVG片段标识符(Fragment Identifiers)如何工作——w3cdream|前端学习-开发

'I'm W3cdream,创造',前·所·未·有
SVG片段标识符(Fragment Identifiers)如何工作

发布作者:萧强   发布时间:2016-01-31   阅读次数:13708

我之前谈到了一点关于SVG<use>的内容——使用它来创建图标系统。<use>的美妙之处在于你可以定义一次SVG,然后在其它地方可以对其多次引用。这种特性使得我们可以创建图标系统,解决“多张图仅需要发一次请求,因为这super高效”这个我们过去用CSS sprite和图标字体解决的问题。

但是<use>意味着内联SVG。当你想要使用一个比较大的SVG文件中的一部分时,如使用SVG作为<img>或background-image引入。这就用到片段标识符啦。

准备好SVG

一个方法是像“CSS”sprite一样将SVG的内容排列好(这大概可以叫做SVG sprite)。

准备好SVG

我们这样排的原因是通过移动viewBox,然后让这张图的部分内容显示出来就够了,和CSS sprite一样。

在这个小demo中,我们使用的三个图标都是32X32的大小。所以这个文件是32X96。我们可以这样子玩耍viewBox

  • 显示整个文件的viewBox参数:0,0,32,96;
  • 显示第一个icon的viewBox参数:0,0,32,32;
  • 显示第二个icon的viewBox参数:0,32,32,32;
  • 显示第三个icon的viewBox参数:0,64,32,32;
  • 这四个参数分别代表:left,top,width,height。注意第二个参数top,每次增加32。这样就可以显示出一个图片的不同部分啦。

    把这些viewBox参数添加到SVG文件中

    你可以把这些特定的viewBox参数值放到SVG文件中的<view>元素内,这个元素是特别为此设计的:

    <view id="icon-clock-view" viewBox="0 0 32 32" />
    <view id="icon-heart-view" viewBox="0 32 32 32" />
    <view id="icon-arrow-right-view" viewBox="0 64 32 32" />

    现在我们可以在其它地方引用这些图标啦。

    <view>元素可以像上面这样独立开来,也可以包裹其它的元素,然后里面的viewBox就会显示id指向的内容,如下:

    <!-- 这个viewBox会显示片段标识符为`match-me`的内容 -->
    <view id="match-me" viewBox="0 64 32 32">
      <rect ...>
    </view>

    规范中的demo

    针对HTML的语法

    给通过<img>引入的SVG应用这个特殊的viewBox值,你可以这样写:

    <!-- 第一个icon -->
    <img src="http://www.w3cdream.com/sprite.svg#svgView(viewBox(0, 0, 32, 32))" alt="">
    或者,如果你已经设置好了<view>元素,你可以这样通过名称引用:

    <!-- 第二个icon -->
    <img src="http://www.w3cdream.com/sprite.svg#icon-heart-view" alt="">

    针对CSS的语法

    你可以在CSS中的引用图片路径中声明一个特殊的viewBox:

    .icon-clock {
      background: url("http://www.w3cdream.com/sprite.svg#svgView(viewBox(0, 0, 32, 32))") no-repeat;
    }
    或引用一个<view>元素,如果你有先设置好的话:

    .icon-clock {
      background: url(sprite.svg#icon-clock-view) no-repeat;
    }
    虽然...,如果你通过这种方式在CSS中使用SVG,然后克服了各种设置SVG的困难。你可能只是想要使用CSS sprite技术,吧SVG文件当成背景图像,然后移动背景图像的位置:

    .icon-heart {
      background: url("sprite.svg") no-repeat;
      background-size: 32px 96px;
      background-position: 0 -32px;
    }

    我只是想把图标一个一个堆叠成栈

    如果图标的viewBox都是相同的,你基本上就只需要设置在需要的时候hide/show,这也非常容易。

    在同一个空间中设计它们(或使用一个构建工具来完成,都可以),保证图标都是相同的尺寸。这里,我给每个图标都设置了一个单独的id。

    SVG

    设置hide/show的技巧,可以在CSS中:1、图片全部隐藏;2、只显示片段标识符匹配的图标。只用CSS可以就完成,因为有:target选择器

    整理好的SVG:

    <defs>
      <style>
        g {
          display: none;
        }
        g:target {
          display: inline;
        }
      </style>
    </defs>
    
    <g id="icon-clock">
      <path d="M20.6,23.3L14,16.7V7.9h4v7.2l5.4,5.4L20.6,23.3z M16-0.1c-8.8,0-16,7.2-16,16s7.2,16,16,16s16-7.2,16-16S24.8-0.1,16-0.1z
             M16,27.9c-6.6,0-12-5.4-12-12s5.4-12,12-12s12,5.4,12,12S22.6,27.9,16,27.9z"/>
    </g>
    <g id="icon-heart">
      <path d="M32,11.2c0,2.7-1.2,5.1-3,6.8l0,0L19,28c-1,1-2,2-3,2s-2-1-3-2L3,18c-1.9-1.7-3-4.1-3-6.8C0,6.1,4.1,2,9.2,2
            c2.7,0,5.1,1.2,6.8,3c1.7-1.9,4.1-3,6.8-3C27.9,1.9,32,6.1,32,11.2z"/>
    </g>
    <g id="icon-arrow-right">
      <path d="M32,15.9l-16-16v10H0v12h16v10L32,15.9z"/>
    </g>

    浏览器支持

    Can I Use网站追踪了片段标识符的[支持情况]((http://caniuse.com/#feat=svg-fragment)。可惜它不是能否工作这么简单,因为它要看浏览器,可能在HTML中可以,但是CSS不可以,或者还有更怪异的情况。

    我没有做过非常详细的浏览器支持情况的整理,但是这里有个简略的版本:

  • Firefox中工作没有问题。
  • IE 11也没问题。IE 9和IE 10在background-position有点怪怪的,但其它的都没问题。
  • 当前版本的Chrome/Safari/Opera(38/8/25)处理HTML的<img>都没问题,但是CSS有问题,包括background-position。原Blink内核的Opera也是一样,非常有趣。
  • iOS8.1唯一可以处理的只有引用<view>的<img>。
  • Android 4.4可以处理的只有background-position(这个是完全没有真正使用片段标识符的)。Android 5匹配当前的Chrome/Safari/Opera都没问题。
  • 扩展参考

  • Spec
  • SVG Stacks by Simuari, which points to a demo by Erik Maelström and a demo by Bear Travis.
  • Demo by Jorge Aznar
  • Better SVG Sprites With Fragment Identifiers by Peter Gasston
  • SVG Sprite Sheets by Bear Travis
  • 如需转载,烦请注明出处:http://www.w3cplus.com/svg/svg-fragment-identifiers-work.html


    常用昵称:萧强,全端布道者

    姓名:“刘晓强”,W3CDream创始人,目前就职于易点付。专注于web爱博体育预测和移动端方面知识的研究,熟练掌握photoshop和AI,喜爱Flat UI设计和Metro UI风格,熟练掌握CSS3+HTML5技术、LESS CSS和Sass CSS,还有jQuery框架方面及一些爱博体育预测框架bootstrap响应式设计等。新浪微博
    上一篇:SVG图标非常方便,但降级并不容易
    下一篇:已经没有下一篇内容了
    友荐云推荐

    HTML5学习指南

    热点文章

    新闻资讯

    标签云

    友情赞助