Home > Back-end >  is there a way to reference svg from page in the css?
is there a way to reference svg from page in the css?

Time:02-04

I see that you can reference the svg by id in some css/svg properties, as in:

<!-- the logo svg -->
<svg id="rect-container" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- left squares -->
    <rect fill="url(#rect-fill)"/>
</svg>

does anyone know if we can use a svg from the page, in a css bg for example? to avoid encoding it on the css. Something like this, which I already tried but did not seem to work the same way.

.myel {
  background-image: url(#rect-svg-image);
}

CodePudding user response:

Yes, you can use an SVG as a CSS background image by referencing the URL of the SVG file, just like with any other image format. The syntax would look like this:

.myel {
background-image: url(my-svg-file.svg);
}

However, referencing an SVG by its ID using url(#rect-svg-image) is not supported in CSS background images as it only works within the SVG document. To use the SVG as a background image, you need to provide a URL to the actual file, either through a relative or absolute path.

CodePudding user response:

First, there is a misconception to clear up.

fill: url(#source);

does not reference arbitrary SVG content, but a paint server, namely a gradient or pattern. Other uses of the CSS url() notation in SVG include the clip-path, mask and marker-start|mid|end properties that all also can only reference specific elements.

Currently, background-image needs an actual self-contained image resource or a CSS gradient. Referencing a SVG paint server with url() does not work.

But the CSS Images Module Level 4 also defines a element() functional notation that can reference fragments inside the page.

If you look at the text of the specification, there are still a lot of open questions listed to solve before this can become mainstream. There currently is only a Firefox implementation with vendor prefix, -moz-element(). You can point it to paint servers; that means you can (mis)use a <pattern> element. Although experimenting, I found there are some tradeoffs to make:

  • patternContentUnits="objectBoundingBox" needs all content drawn into a 1px*1px square, but makes the content scalable. Preserving the aspect ratio is not supported.
  • patternContentUnits="userSpaceOnUse" gives you preservation of the aspect ratio, but scaling is not supported.

svg {
  display: block;
  width: 0;
  height: 0;
}
div {
  width: 200px;
  height: 150px;
  border: 1px solid black;
  background-image: -moz-element(#image);
  background-size: cover;
}
<svg>
  <pattern patternContentUnits="objectBoundingBox"
           preserveAspectRatio="xMidYMid meet"
           width="100%" height="100%" id="image">
    <rect width=".5" height=".5" fill="red"/>
    <rect width=".5" height=".5" x=".5" fill="yellow"/>
    <rect width=".5" height=".5" y=".5" fill="green"/>
    <rect width=".5" height=".5" x=".5" y=".5" fill="blue"/>
    <circle r=".5" cx=".5" cy=".5" fill="white" opacity=".5"/>
  </pattern>
</svg>
<div>

  • Related