开发者

One SVG file, many SVG gradients inside

I’m making a set of buttons which use dynamic gradients. I’ve taken care of Firefox 3.6+ and WebKit by using their proprietary CSS extensions and all I need to do is support Opera, iOS and IE9 by using background-image: url("gradient.svg").

This is relatively easy, I made an SVG file, linked it and got it working. However, I’m making a set so I need at least 6 gradients. When I normally do it in images, I create a sprite for fast HTTP access. I’m not sure how to achieve this in SVG – can I use one file and access different parts of its XML by using #identifiers, like XBL does?

My current SVG:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
         "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <linearGradient id="select-gradient" x1="0" x2="0" y1="0" y2="1">
            <stop offset="0%" stop-color="rgb(231,244,248)"/>
            <stop offset="100%" stop-color="rgb(207,233,241)"/>
        </linearGradient>
        <style type="text/css">
          rect {
          fill: url(#select-gradient);
          }
      </style>
    </defs>
    <rect x="0" y="0" rx="6" ry="6" height="100%" width="100%"/>
</svg> 
开发者_如何学Python

And then I have CSS:

.button-1 {
  background-image: url("gradient-1.svg");
}

.button-2 {
  background-image: url("gradient-2.svg");
}

I want to do something like this:

.button-1 {
  background-image: url("gradient.svg#gradient1");
}

.button-2 {
  background-image: url("gradient.svg#gradient2");
}

Is it even possible? Can you help me out? I really don’t wanna push 6 XML files when I can do it with one.


If you just want gradients for button backgrounds, most of this can be acheived in css. For the remaining browsers, ie6 + can user ms filters: http://msdn.microsoft.com/en-us/library/ms532847.aspx

iOS uses webkit to render, so you can use -webkit vendor prefix. Unfortunately you will still need svg for opera, but this may make it easier (or just use a normal image sprite for opera's 1% of users)


in theory - according to SVG documentation #Params it is possible. You could use 2 params for setting up both colors, you could create multiple rects with different gradients, height set to 0 and then make only one 100% (like ?gradient2=100%)


What you could do is load your SVG file that contains all of the definitions first, and then load your other SVG files.

Using Firefox, jQuery SVG , and a minor shot of framework...

in your XHTML:

    <div id="common_svg_defs"><!--ieb--></div>
    <div id="first_thing"><!--ieb--></div>
    <div id="second_thing"><!--ieb--></div>

in your JavaScript:

    var do_stuff = function()
    {
      // load your common svg file with this goo.
      $('#common_svg_defs').svg({
        loadURL: 'path/filename.svg',
        onLoad: function(svg, error) { run_test(svg, error);} });
    }

    var run_test = function(svg, error)
    {
      if (typeof(error) !== "undefined")
      {
        if (typeof(console.log) !== "undefined")
        {
          console.log(error);
        }
      }
      else
      {
        // load your other svg files here, or just
        // set a flag letting you know it's ready.
        $('#first_thing').svg({
          loadURL: 'path/anotherfilename.svg',
          onLoad: function(svg, error) { somecallback(svg, error);} });
        $('#second_thing').svg({
          loadURL: 'path/anotherfilename.svg',
          onLoad: function(svg, error) { somecallback(svg, error);} });
      }
    }

Because the id can be found in the documents scope, the SVG are capable of finding the IRI reference.

This allows you to define things once (that would not otherwise be defined in a css) and avoid id collisions.

Cheers, Christopher Smithson

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜