Specify an SVG as a background image and ALSO style the SVG in CSS?

Solution 1:

No, this is not possible. The SVG has to be prepared in one document (which may be a data URI or an externally referenced file) and then used as a background in another file.

Solution 2:

You can use SVG and CSS masks to recreate this effect, then use normal CSS to style the inside of the SVG, even background-image

-webkit-mask:   url(filename.svg) 50% 50% / 100px 50px no-repeat;
    -o-mask:    url(filename.svg) 50% 50% / 100px 50px no-repeat;
    -ms-mask:   url(filename.svg) 50% 50% / 100px 50px no-repeat;

background-color: red;
background-image: url(animated.gif);

/* Filename, Position / Size, Repeat */
/* Modernizr.cssmask is the test needed to pass - snippet below */

You can use this to create drop shadows by appending an element to the DOM and styling that, with a lower z-index and setting an opacity.

Hope that helps!

Edit: Links

  • Modernizr Test - http://pastebin.com/w4eVbEKr
  • Some more information - https://www.webkit.org/blog/181/css-masks/

Solution 3:

It's actually possible for those who can use preprocessors in production, by "inlining" background SVG, and bit of SASS mixins, which "slice" whole svg gibberish, to get access to parts you want to manipulate via SASS variables.

In your original scenario you have an element
<div class="element1"></div>,

so you need a mixin/function which will inline SVG for you. Let's say you want to control of the fill, so:

@mixin inline-svg($color, $svg-content) {
  $start: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><style>path { fill:#{$color}; }</style>';
  $end:   '</svg>';

  background-image: url('data:image/svg+xml;utf8, #{$start}#{$svg-content}#{$end}');
}

where $svg-content variable is your <svg> stuff excluding <style> element (which you want to access from inside of the mixin) and wrapping svg tag,, ie: $svg-content = "<path .... />"

This just need to be included with values passed inside:
@include inline-svg(salmon, $svg-content);

To sum whole thing up, this is an example SASS code:

$svg-content = "<path .... />"

@mixin inline-svg($color, $svg-content) {
    $start: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><style>path { fill:#{$color}; }</style>';
    $end:   '</svg>';

    background-image: url('data:image/svg+xml;utf8, #{$start}#{$svg-content}#{$end}');
}  

.element1 {
    @include inline-svg(rgba(0,0,0,0.6), $svg-content);
}

I think possibilities here are quite big (there are also limitations here to that approach). I actually pass a SASS map to my mixin with css styles defined as key, value pair, to inject whole bunch of css styles to the <style> part of svg.

So it's technically possible, but require more compexity, but once you get this done, you'll get benefits of reusing this mixin throughout your project(s), which is cool .