SVG styling problems with <use> - css

I'm trying to change, with CSS, the size and color of an SVG element that's being rendered with <use>. The SVG in question:
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
<path fill="#000000" fill-rule="evenodd" d="<all the actual svg path info>" clip-rule="evenodd"/>
</svg>
I do not have permission to change the contents of the SVG itself.
The way I'm using the SVG:
<svg>
<use xlink:href="#myIcon"></use>
</svg>
I've fought with this for hours, read through a pretty comprehensive article on the subject, and I still haven't had any success. I've tried applying classes to both the use element and the outer svg element, as well as referencing the path element inside. I can't seem to do anything to override the provided styles. How can I change the width, height, and fill color with this arrangement?

For the size it's easy if you correctly set the viewBox and then you adjust the width/height.
For the coloration you can rely on blending mode since the color of the SVG is black.
.icon {
display: inline-block;
background: #fff;
position: relative;
}
.icon::after {
content:"";
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
background:var(--c);
mix-blend-mode:lighten;
}
.icon>svg {
display: block;
}
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
<symbol id="myIcon">
<path fill="#000" d="M81,40.933c0-4.25-3-7.811-6.996-8.673c-0.922-5.312-3.588-10.178-7.623-13.844 c-2.459-2.239-5.326-3.913-8.408-4.981c-0.797-3.676-4.066-6.437-7.979-6.437c-3.908,0-7.184,2.764-7.979,6.442 c-3.078,1.065-5.939,2.741-8.396,4.977c-4.035,3.666-6.701,8.531-7.623,13.844C22.002,33.123,19,36.682,19,40.933 c0,2.617,1.145,4.965,2.957,6.589c0.047,0.195,0.119,0.389,0.225,0.568l26.004,43.873c0.383,0.646,1.072,1.04,1.824,1.04 c0.748,0,1.439-0.395,1.824-1.04L77.82,48.089c0.105-0.179,0.178-0.373,0.225-0.568C79.855,45.897,81,43.549,81,40.933z M49.994,11.235c2.164,0,3.928,1.762,3.928,3.93c0,2.165-1.764,3.929-3.928,3.929s-3.928-1.764-3.928-3.929 C46.066,12.997,47.83,11.235,49.994,11.235z M27.842,36.301c0.014,0,0.027,0,0.031,0c1.086,0,1.998-0.817,2.115-1.907 c0.762-7.592,5.641-13.791,12.303-16.535c1.119,3.184,4.146,5.475,7.703,5.475c3.561,0,6.588-2.293,7.707-5.48 c6.664,2.742,11.547,8.944,12.312,16.54c0.115,1.092,1.037,1.929,2.143,1.907c2.541,0.013,4.604,2.087,4.604,4.631 c0,1.684-0.914,3.148-2.266,3.958H25.508c-1.354-0.809-2.268-2.273-2.268-3.958C23.24,38.389,25.303,36.316,27.842,36.301z M50.01,86.723L27.73,49.13h44.541L50.01,86.723z" fill-rule="evenodd" clip-rule="evenodd"/>
</symbol>
</svg>
<!-- your code -->
<div class="icon" style="--c:red;">
<svg viewBox="0 0 100 125" width="100">
<use xlink:href="#myIcon"></use>
</svg>
</div>
<div class="icon" style="--c:green;">
<svg viewBox="0 0 100 125" width="150">
<use xlink:href="#myIcon"></use>
</svg>
</div>
<div class="icon" style="--c:blue;">
<svg viewBox="0 0 100 125" width="200">
<use xlink:href="#myIcon"></use>
</svg>
</div>

Save svg as a image with svg format then add the color and width or whatever you want to your img then add this to the html file as a img tag and display: none the svg code.
If you can't reach the html code then you can't do anything.

Related

Is it possible to change svg viewBox value using CSS?

I want to change the svg value of the viewBox using CSS when the window width is 660px.
viewBox="0 0 230 87" => viewBox="0 0 100 87".Is it possible to change svg viewBox value using CSS ?
You can only change presentation attributes through CSS. viewBox is not one of these.
What you can do however is to use <symbol> elements to define "views" over the scene.
Indeed, <symbol> does have a viewBox attribute, so you can use this element to point to the whole scene, and then use one <use> element per such "view" and control via CSS when this <use> is displayed:
svg {
border: 1px solid;
border-color: yellow;
}
#media (max-width:500px) {
svg { border-color: green; }
#small-use { display: block; }
#big-use { display: none; }
}
#media (min-width:501px) {
#small-use { display: none; }
#big-use { display: block; }
}
<svg>
<!-- we wrap the whole scene in one symbol -->
<symbol id="scene">
<rect fill="blue" x="0" y="0" width="500" height="500"/>
<rect fill="red" x="0" y="0" width="50" height="50" />
</symbol>
<!-- following symbols will define our "views" -->
<symbol id="small-view" viewBox="0 0 60 60">
<use href="#scene"/>
</symbol>
<symbol id="big-view" viewBox="0 0 500 500">
<use href="#scene"/>
</symbol>
<!-- append all the views, CSS will determine which to display -->
<use href="#small-view" id="small-use"/>
<use href="#big-view" id="big-use"/>
</svg>
<p>Change the window's size to trigger the "change of viewBox"</p>
If you want to change SVG width, you can set width property on svg tag
<svg width="40" height="40" viewBox="0 0 40 40">...</svg>
or, you can add CSS style on it.
<svg viewBox="0 0 40 40" style="width:80px; height: 80px">...</svg>
If you edit viewBox, your SVG shape might be destroyed.

Any way to use SVG Sprite from CSS?

HTML:
<svg>
<use xlink:href="/assets/images/icons-sprite.svg#icon-name"></use>
</svg>
SVG sprite:
<svg width="0" height="0" class="hidden">
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="icon-name">
<path ... fill="currentColor"></path>
</symbol>
</svg>
Is there any way to use SVG sprite from CSS
Like this
<div class=“icon”></div>
.icon {
background-image: “/assets/images/icons-sprite.svg#icon-name”
height: 30px
}
I’m using the technique for including SVGs described here whereby you create a doc that looks something like this…
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="arrow-left" viewBox="0 0 10 16">
<path d="M9.4 1.4L8 0 0 8l8 8 1.4-1.4L2.8 8z"/>
</symbol>
<symbol id="arrow-right" viewBox="0 0 10 16">
<path d="M0 14.6L1.4 16l8-8-8-8L0 1.4 6.6 8z"/>
</symbol>
</svg>
Include it in the top of your HTML and then insert the SVG icons in your markup like this…
<svg class="arrow-right">
<use xlink:href="#arrow-right" />
</svg>
It’s easy and works great. However, I’m trying to use the same icons in my CSS pseudo classes :before and :after using an empty content attribute and the SVG in the background. Something like this…
.title:after {
float: right;
width: 16px;
height: 10px;
content: "";
background: url('#arrow-right');
}

How can i add backgroung image in the following svg?

From this website
https://smooth.ie/blogs/news/svg-wavey-transitions-between-sections
i generated the following svg
<div style="height: 100%; overflow: hidden;" class='parent' ><svg viewBox="0 0 500 150" preserveAspectRatio="none" style="height: 100%; width: 100%;"><path d="M213.19,0.00 C152.69,70.06 270.03,70.06 202.98,150.00 L500.00,150.00 L500.00,0.00 Z" style="stroke: none; fill: #08f;"></path></svg></div>
the problem is that when i try to add background image for example here on the parent class
.parent {
background-image: url('../../../assets/images/calendar.png');
}
then the image is hidden behind the blue color of the svg.How can i 'insert' this image to be on the blue svg color image ?
As name says - it's "background-image" so it always is on the background of selected element.
I suggest that you should make an <img> tag in parent element and style it so that .parent would have attribute position: relative and img should have position: absolute.
Also remember to set top and left/right position for <img>.
it's Answered here https://stackoverflow.com/a/3798797/9017484
You can do it by making the background into a pattern:
<defs>
<pattern id="img1" patternUnits="userSpaceOnUse" width="100" height="100">
<image href="wall.jpg" x="0" y="0" width="100" height="100" />
</pattern>
</defs>
your code should be something like this:
<div style="height: 100%; overflow: hidden;" class='parent' >
<svg viewBox="0 0 500 150" preserveAspectRatio="none" style="height: 100%; width: 100%;">
<defs>
<pattern id="img1" patternUnits="userSpaceOnUse" width="100" height="100">
<image href="ImageFile.jpg" x="0" y="0" width="100" height="100" />
</pattern>
</defs>
<path d="M213.19,0.00 C152.69,70.06 270.03,70.06 202.98,150.00 L500.00,150.00 L500.00,0.00 Z" style="stroke: none; fill: url(#img1);"></path>
</svg>
</div>
change the opacity level so the color is lower opacity. something like this perhaps.
background {
backgroundColor:blue,
opacity: 0.5;
}

overlay svg responsive according to the img

I have to put an icon overlay to the image. Image is 100% in width & height. Icon is the mark on the image. Icons position is changing according to the image responsive. I need to stick the same position of the icon all time. When image is responsive the icon also needs to be change its width left and top.
<div class="outer">
<svg class="mark-icon"><svg>
<img src="Map.jpg" class="map-bg"/>
</div>
.outer{
position:relative;
}
.map-bg{
width:100vw;
height:100vh;
object-fit:cover;
}
.mark-icon{
width:50px;
height:50px;
position:absolute;
left:50px;
top:30px;
}
Sample
https://jsfiddle.net/rkv3sd0q/
Try adding a map image using the svg <image> tag
Add a red pointer icon with <circle>
When both elements are inside the SVG, their position relative to each other will remain constant.
And will not change on any resize of the browser window.
body{
margin:0px;
padding: 0px;
}
.outer-pane {
width:100vw;
height:100vh;
}
.pointer {
fill:red;
cursor:pointer;
}
<div class="outer-pane">
<svg viewBox="0 0 1000 739" preserveAspectRatio="xMin YMin meet" >
<image class="mainProject" xlink:href="https://www.mapsofworld.com/style_2019/images/world-map.png?v:1" width="1000" height="739" />
<circle class="pointer" cx="320" cy="124" r="25" fill="red" />
</svg>
</div>
Update
Map with multiple markers
To do this, add the marker path once using the <symbol> tag
<symbol id="marker" width="18" height="28" viewbox="0 0 9.831 14.782">
<path fill="#00AEEF" d="M9.831 4.916c0 2.714-3.538 8.487-4.913 9.867C3.437 13.307 0 7.631 0 4.916S2.201 0 4.916 0s4.915 2.201 4.915 4.916z"/>
<circle cx="4.912" cy="4.916" r="2.932" fill="#E7EDEF"/>
</symbol>
And add markers to the map many times with the <use> tag
<use xlink:href="#marker" fill="#00AEEF" x="350" y="80" />
<use xlink:href="#marker" fill="red" x="670" y="360" />
body{
margin:0px;
padding: 0px;
}
.outer-pane{
width:100vw;
height:100vh;
}
.pointer {
fill:red;
cursor:pointer;
}
symbol path {
fill:inherit;
}
<div class="outer-pane">
<svg viewBox="0 0 1000 739" preserveAspectRatio="xMin YMin meet" >
<symbol id="marker" width="18" height="28" viewbox="0 0 9.831 14.782">
<path fill="#00AEEF" d="M9.831 4.916c0 2.714-3.538 8.487-4.913 9.867C3.437 13.307 0 7.631 0 4.916S2.201 0 4.916 0s4.915 2.201 4.915 4.916z"/>
<circle cx="4.912" cy="4.916" r="2.932" fill="#E7EDEF"/>
</symbol>
<image class="mainProject" xlink:href="https://www.mapsofworld.com/style_2019/images/world-map.png?v:1" width="1000" height="739" />
<use xlink:href="#marker" fill="#00AEEF" x="350" y="80" />
<use xlink:href="#marker" fill="red" x="670" y="360" />
<use xlink:href="#marker" fill="violet" x="770" y="360" />
<use xlink:href="#marker" fill="purple" x="170" y="210" />
<use xlink:href="#marker" fill="crimson" x="190" y="310" />
</svg>
</div>
What I understood is, Icon must be responsive and it's height and width should decrease with decrease on width of the screen, also It should be on left upper corner of the image.
If that is the case then you have to use #media query on each break point to change the icon size and position for left, top, width and height properties
Also, if you keep object-fit: cover;, then there is possibility that image is not of the same height and width of screen. So there might be possibility that icon is not where should be.
If there is anything else, please put up a example in codepen and update the question again.
You can place your icon dynamically by using, unit as vw and vh, as your image is set as well with that, it will be responsive the same way:
.mark-icon{
position:absolute;
left:5vw;
top:5vh;
}
DEMO:
body{margin:0;}
.outer{
position:relative;
}
.map-bg{
width:100vw;
height:100vh;
object-fit:cover;
}
.mark-icon{
width:50px;
height:50px;
position:absolute;
left:5vw;
top:5vh;
}
<div class="outer">
<svg height="100" width="100" class="mark-icon">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
Sorry, your browser does not support inline SVG.
</svg>
<img src="https://images.freeimages.com/images/large-previews/7e9/ladybird-1367182.jpg" class="map-bg">
</div>

Fill Colour on <use> Element For a <symbol> Isn't Changing Colour

I'm trying to change the fill colour on an SVG symbol when it is inside a <use> element. Because there are going to be multiple instances of the symbol on the page, I can't do this is the <symbol> element, because the different instances of <use> will be different colours.
I've can't seem to get it work though. In the example below I would like to the bottom instance to be a blue twitter icon.
In the CSS I've done #bottom-twitter svg path {fill:blue;} which doesn't work. And I can't seem to get anything to work.
Any help would be amazing.
#box1 {
height: 5rem;
width: 5rem;
}
/* NOT WORKING */
#bottom-twitter svg path {
fill:blue;
}
<svg id="twitter" style="display: none;">
<defs>
<symbol id="twitter-symbol" viewBox="0 0 19.19 15.95">
<path id="twitter-path" d="M19.19,1.92a8.76,8.76,0,0,1-2.28.64A3.9,3.9,0,0,0,18.63.32a6.87,6.87,0,0,1-2.52,1A3.87,3.87,0,0,0,13.23,0,4,4,0,0,0,9.32,4,3.41,3.41,0,0,0,9.44,5,11,11,0,0,1,1.32.72a4.29,4.29,0,0,0-.52,2A4,4,0,0,0,2.56,6.12,3.61,3.61,0,0,1,.76,5.6v0a4,4,0,0,0,3.16,4,4.35,4.35,0,0,1-1,.16,4.9,4.9,0,0,1-.76-.08,4,4,0,0,0,3.68,2.8A7.79,7.79,0,0,1,.92,14.19a6.78,6.78,0,0,1-.92,0A10.83,10.83,0,0,0,6,16c7.24,0,11.19-6.16,11.19-11.47V4a6.83,6.83,0,0,0,2-2">
</path>
</symbol>
</defs>
</svg>
<div class="box" id="box1">
<svg id="top-twitter" viewBox="0 0 19.19 15.95">
<use xlink:href="#twitter-symbol"/>
</svg>
<svg id="bottom-twitter" viewBox="0 0 19.19 15.95">
<use xlink:href="#twitter-symbol"/>
</svg>
</div>
The problem is the fill="#000" in the svg path. Remove that or just change it to be the color you want.
#box1 {
height: 5rem;
width: 5rem;
}
/* NOT WORKING */
#bottom-twitter {
fill: blue;
}
<svg id="twitter" style="display: none;">
<defs>
<symbol id="twitter-symbol" viewBox="0 0 19.19 15.95">
<path id="twitter-path" d="M19.19,1.92a8.76,8.76,0,0,1-2.28.64A3.9,3.9,0,0,0,18.63.32a6.87,6.87,0,0,1-2.52,1A3.87,3.87,0,0,0,13.23,0,4,4,0,0,0,9.32,4,3.41,3.41,0,0,0,9.44,5,11,11,0,0,1,1.32.72a4.29,4.29,0,0,0-.52,2A4,4,0,0,0,2.56,6.12,3.61,3.61,0,0,1,.76,5.6v0a4,4,0,0,0,3.16,4,4.35,4.35,0,0,1-1,.16,4.9,4.9,0,0,1-.76-.08,4,4,0,0,0,3.68,2.8A7.79,7.79,0,0,1,.92,14.19a6.78,6.78,0,0,1-.92,0A10.83,10.83,0,0,0,6,16c7.24,0,11.19-6.16,11.19-11.47V4a6.83,6.83,0,0,0,2-2" >
</path>
</symbol>
</defs>
</svg>
<div class="box" id="box1">
<svg id="top-twitter" viewBox="0 0 19.19 15.95">
<use xlink:href="#twitter-symbol"/>
</svg>
<svg id="bottom-twitter" viewBox="0 0 19.19 15.95">
<use xlink:href="#twitter-symbol"/>
</svg>
</div>

Resources