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>