I'm trying to to switch a Vue/Vuetify app from using the webfont for Material Design Icons to use SVG icons instead.
When using the webfont, an example of a heading that contains an icon is
<template>
<h1>
<v-icon>mdi-format-list-bulleted</v-icon>
My Heading
</h1>
</template>
The height of the icon automatically matches the heading because the <i> element that is generated for the icon has CSS properties
font-size: inherit;
color: inherit;
After switching to SVG icons, an example of a heading that contains an icon is
<template>
<h1>
<v-icon>{{ iconPath }}</v-icon>
My Heading
</h1>
</template>
<script>
import { mdiFormatListBulleted } from '#mdi/js'
export default {
data: () => ({
iconPath: mdiFormatListBulleted
})
}
</script>
This generates the following markup instead:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img"
aria-hidden="true" class="v-icon__svg">
<!-- path element omitted -->
</svg>
the CSS class has the following properties
.v-icon__svg {
height: 24px;
width: 24px;
fill: currentColor;
}
The fixed icon height of 24px means that the SVG icon doesn't match the heading's height.
Although the <v-icon> component provides a number of props that I can use to change the icon's size, e.g. size, large, small, these will fix the size to a specific value, rather than inheriting the size from the parent element.
Is there a way for an SVG to inherit it's size from it's parent element? More specifically, I want the SVG height and width to be the same as the parent element's height.
Demo
I've created a demo of what happens when you use SVG icons. It takes about 30 seconds for it to load, and you may need to disable 3rd party cookies for it to work.
If you set the height of the SVG to one of the relative units it will match the font-size of the context. You can combine this with vertical-align if necessary.
h1,h2 {
color: navy;
}
.height-ch {
height: 1ch;
fill: currentColor;
}
.height-em {
height: 1em;
fill: currentColor;
}
.height-rem {
height: 1rem;
fill: currentColor;
}
<h1>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img"
aria-hidden="true" class="height-em">
<path d="M 0 0 L 24 0 L 24 24 L 0 24 Z" />
</svg>
Heading em
</h1>
<h2>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img"
aria-hidden="true" class="height-em">
<path d="M 0 0 L 24 0 L 24 24 L 0 24 Z" />
</svg>
Heading em
</h2>
<h2>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img"
aria-hidden="true" class="height-ch">
<path d="M 0 0 L 24 0 L 24 24 L 0 24 Z" />
</svg>
Heading ch
</h2>
<h2>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img"
aria-hidden="true" class="height-rem">
<path d="M 0 0 L 24 0 L 24 24 L 0 24 Z" />
</svg>
Heading rem
</h2>
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');
}
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.
So, the question is - how to set the svg icon to fit the container size? For not it unfortunately crops without any resize... I cannot figure out how to make my file-svg scale! This is question is not about inline svg manipulation!
div {
width: 50px;
height: 50px;
}
img {
width:100%;
height:100%;
}
<div>
<img src="https://svgshare.com/i/7Bw.svg" viewBox="0 0 10 10" preserveAspectRatio="none">
</div>
You need to define viewBox inside the SVG to able to scale it later:
img {
width:100%;
height:100%;
}
<div style="width:50px;height:50px;">
<img src="https://svgshare.com/i/7EX.svg">
</div>
<div style="width:100px;height:100px;">
<img src="https://svgshare.com/i/7EX.svg">
</div>
Here is the SVG code:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 98 98">
<circle class='ui-icon__svg ui-icon__border' cx='50' cy='50' r='48' />
<path class='ui-icon__svg' d='M31.5 42.5V36l45-.1.1 22.6H70m0 6.7H25l-.1-22.7H70v22.7zM36 43.1l.1 22-.1-22zm22.9 0l.1 22-.1-22zm-16.3-6.6l.1 6.1-.1-6.1zm22.9 0l.1 6.1-.1-6.1z' />
</svg>
I’m using a SVG sprite like this in the body:
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="bars" width="1792" height="1792" viewBox="0 0 1792 1792">
<path d="M1664 1344v128q0 26-19 45t-45 19h-1408q-26 0-45-19t-19-45v-128q0-26 19-45t45-19h1408q26 0 45 19t19 45zm0-512v128q0 26-19 45t-45 19h-1408q-26 0-45-19t-19-45v-128q0-26 19-45t45-19h1408q26 0 45 19t19 45zm0-512v128q0 26-19 45t-45 19h-1408q-26 0-45-19t-19-45v-128q0-26 19-45t45-19h1408q26 0 45 19t19 45z"/>
</symbol>
</svg>
If I need the symbol, I call it like this:
<svg class="icon left bars" style="fill: #000;">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#bars"></use>
</svg>
Now I need this SVG in a CSS ::after. I know that you can use a SVG as background image in the ::after but it won’t work with use:
.element::after {
background: url('data:image/svg+xml;utf8,<svg class="icon left bars" style="fill: #000;"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#bars"></use></svg>') no-repeat;
//background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='61' height='41' fill='#000' stroke='none'><path d='M0,0 6,10 L12,0 L0,0 Z'></path></svg>") no-repeat;
content: "";
display: block;
height: 16px;
width: 16px;
}
Demo: JSFiddle
Is there anyone who got this working?
.element::before {background-image:url("data:image/svg+xml;charset=UTF-8,<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%' viewBox='0 0 75.33 68.119'>\ <polygon fill-rule='evenodd' clip-rule='evenodd' fill='red' points='8.125,11.865 75.33,0 73.794,37.574 70.938,68.119 0,64.603 '/>\ </svg>"); content:""; display:inline-block; width:75.33px; height:68.119px;}
<div class="element"></div>
However it only works on non-IE browsers, a shame as you could turn it into a mixin in less/sass so you dont bloat your working css.
I got it from
https://codepen.io/AmeliaBR/details/xijuv
And also worth a read https://manu.ninja/inline-svg-how-i-learned-to-stop-worrying-and-love-gzip/
EDIT working in IE 11
See this answer CSS: Using raw svg in the URL parameter of a background-image in IE