svg drop-shadow on Internet Explorer 11 [duplicate] - css

Is it possible to set drop shadow for an svg element using css3 , something like
box-shadow: -5px -5px 5px #888;
-webkit-box-shadow: -5px -5px 5px #888;
I saw some remarks on creating shadow using filter effects. Is there an example of using css alone. Below is a working code where the cusor style is correctly applied, but no shadow effect. Please help me to get the shadow effect with least bit of code.
svg .shadow {
cursor:crosshair;
-moz-box-shadow: -5px -5px 5px #888;
-webkit-box-shadow: -5px -5px 5px #888;
box-shadow: -5px -5px 5px #888;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" viewBox="0 0 120 70">
<rect class="shadow" x="10" y="10" width="100" height="50" fill="#c66" />
</svg>

Use the new CSS filter property.
Supported by webkit browsers, Firefox 34+ and Edge.
You can use this polyfill that will support FF < 34, IE6+.
You would use it like so:
/* Use -webkit- only if supporting: Chrome < 54, iOS < 9.3, Android < 4.4.4 */
.shadow {
-webkit-filter: drop-shadow( 3px 3px 2px rgba(0, 0, 0, .7));
filter: drop-shadow( 3px 3px 2px rgba(0, 0, 0, .7));
/* Similar syntax to box-shadow */
}
<img src="https://upload.wikimedia.org/wikipedia/commons/c/ce/Star_wars2.svg" alt="" class="shadow" width="200">
<!-- Or -->
<svg class="shadow" ...>
<rect x="10" y="10" width="200" height="100" fill="#bada55" />
</svg>
<!-- Or -->
<svg>
<g fill="none" stroke="#decade" stroke-width="2" transform="scale(2)">
<circle class="shadow" cx="20" cy="20" r="19"/>
<path class="shadow" d="M 20,1 V 39"/>
<path class="shadow" d="M 20,1 V 20" transform="rotate(135, 20, 20)"/>
<path class="shadow" d="M 20,1 V 20" transform="rotate(225, 20, 20)"/>
</g>
</svg>
This approach differs from the css box-shadow effect in that it accounts for opacity and does not apply the drop shadow effect to the box but rather to the outline of the svg element itself.
NOTE: This approach used to work when the class was placed on the <svg> element alone. You can now use this on an inline svg element such as <rect>.
Read more about css filters on html5rocks.

Here's an example of applying dropshadow to some svg using the 'filter' property. If you want to control the opacity of the dropshadow have a look at this example. The slope attribute controls how much opacity to give to the dropshadow.
Relevant bits from the example:
<filter id="dropshadow" height="130%">
<feGaussianBlur in="SourceAlpha" stdDeviation="3"/> <!-- stdDeviation is how much to blur -->
<feOffset dx="2" dy="2" result="offsetblur"/> <!-- how much to offset -->
<feComponentTransfer>
<feFuncA type="linear" slope="0.5"/> <!-- slope is the opacity of the shadow -->
</feComponentTransfer>
<feMerge>
<feMergeNode/> <!-- this contains the offset blurred image -->
<feMergeNode in="SourceGraphic"/> <!-- this contains the element that the filter is applied to -->
</feMerge>
</filter>
<circle r="10" style="filter:url(#dropshadow)"/>
Box-shadow is defined to work on CSS boxes (read: rectangles), while svg is a bit more expressive than just rectangles. Read the SVG Primer to learn a bit more about what you can do with SVG filters.

You can easily add a drop-shadow effect to an svg-element using the drop-shadow() CSS function and rgba color values. By using rgba color values you can change the opacity of your shadow.
img.light-shadow{
filter: drop-shadow(0px 3px 3px rgba(0, 0, 0, 0.4));
}
img.dark-shadow{
filter: drop-shadow(0px 3px 3px rgba(0, 0, 0, 1));
}
<img class="light-shadow" src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.svg" />
<img class="dark-shadow" src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.svg" />

Easiest way I've found is with feDropShadow.
<filter id="shadow" x="0" y="0" width="200%" height="200%">
<feDropShadow dx="3" dy="3" stdDeviation="1" flood-color="#ff0000" flood-opacity="1" />
</filter>
On the element:
<path d="..." filter="url(#shadow)"/>

Black text with white shadow
Another way, I used for white shadow (on text): create a clone for shadow:
Note: This require xmlns:xlink="http://www.w3.org/1999/xlink" at SVG declaration.
Real text value is located in <defs> section, with position and style, but without a fill definition.
The text is cloned two times: first for shadow and second for the text itself.
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="70"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="Blur"><feGaussianBlur stdDeviation="0.8" /></filter>
<text style="font-family:sans,helvetica;font-weight:bold;font-size:12pt"
id="Text"><tspan x="12" y="19">
Black text with white shadow
</tspan></text>
</defs>
<rect style="fill:#8AB" width="640" height="70" />
<use style="fill:white;" filter="url(#Blur)" xlink:href="#Text"
transform="translate(1.8,.9)"/>
<use style="fill:black;" xlink:href="#Text"/>
</svg>
More distant shadow with biggest value as blur deviation:
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="70"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="Blur"><feGaussianBlur stdDeviation="3" /></filter>
<text style="font-family:sans,helvetica;font-weight:bold;font-size:12pt"
id="Text"><tspan x="12" y="19">
Black text with white shadow
</tspan></text>
</defs>
<rect style="fill:#8AB" width="640" height="70" />
<use style="fill:white;" filter="url(#Blur)" xlink:href="#Text"
transform="translate(7,5)"/>
<use style="fill:black;" xlink:href="#Text"/>
</svg>
You can use this same approach with regular SVG objects.
With same requirement: No fill definition at <defs> section!
<svg xmlns="http://www.w3.org/2000/svg" width="364" height="172"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="Blur"><feGaussianBlur stdDeviation="0.8" /></filter>
<g transform="matrix(.7,0,0,.7,-117.450795,-335.320895)" id="Img">
<g transform="matrix(12.997776,0,0,-12.997776,389.30313,662.04015)">
<path d="m 0,0 -1.107,0 c -0.039,0 -0.067,0.044 -0.067,0.086 0,0.015 0.589,1.914 0.589,1.914 0.021,0.071 0.023,0.073 0.031,0.073 l 0.001,0 c 0.009,0 0.01,-0.002 0.031,-0.073 0,0 0.589,-1.899 0.589,-1.914 C 0.067,0.044 0.037,0 0,0 M 1.493,4.345 C 1.482,4.383 1.448,4.411 1.408,4.414 l -4.065,0 C -2.698,4.41 -2.731,4.383 -2.742,4.346 c 0,0 -2.247,-7.418 -2.247,-7.432 0,-0.037 0.029,-0.067 0.067,-0.067 l 2.687,0 c 0.021,0.008 0.037,0.028 0.042,0.051 l 0.313,1 c 0.01,0.025 0.033,0.042 0.061,0.043 l 2.479,0.002 c 0.027,-0.002 0.051,-0.021 0.061,-0.045 l 0.32,-1 c 0.005,-0.023 0.021,-0.044 0.042,-0.052 0,0 2.642,10e-4 2.644,10e-4 0.037,0 0.068,0.028 0.068,0.065 0,0.013 -2.302,7.433 -2.302,7.433" />
</g>
<g transform="matrix(12.997776,0,0,-12.997776,508.27177,644.93113)">
<path d="m 0,0 -1.651,-0.001 c 0,0 -0.044,0.013 -0.044,0.063 l -10e-4,0.833 c 0,0.05 0.044,0.063 0.044,0.063 l 1.514,0 C 0.038,0.958 0.394,0.87 0.394,0.463 0.394,0.056 0,0 0,0 m 7.916,0.645 3.741,0 0,2.453 -4.81,0 C 6.397,3.098 5.764,2.866 5.401,2.597 5.038,2.328 4.513,1.715 4.513,0.87 c 0,-0.845 0.513,-1.502 0.513,-1.502 0.263,-0.326 0.925,-1.005 0.925,-1.005 0.015,-0.016 0.024,-0.037 0.024,-0.061 0,-0.051 -0.041,-0.092 -0.092,-0.092 l -3.705,0 c -0.451,0.002 -0.482,0.181 -0.482,0.207 0,0.046 0.056,0.075 0.056,0.075 0.169,0.081 0.514,0.35 0.514,0.35 0.732,0.57 0.82,1.352 0.82,1.771 0,0.42 -0.063,1.163 -0.814,1.814 C 1.521,3.078 0.57,3.096 0.57,3.096 l -5.287,0 c 0,0 0,-7.52 0,-7.522 0,-0.024 0.022,-0.043 0.046,-0.043 l 2.943,0 0,2.11 c 0,0.037 0.057,0 0.057,0 l 1.533,-1.54 c 0.545,-0.551 1.446,-0.57 1.446,-0.57 l 5.796,0.001 c 0.989,0 1.539,0.538 1.69,0.688 0.15,0.151 0.651,0.714 0.651,1.647 0,0.932 -0.426,1.409 -0.608,1.628 C 8.675,-0.309 8.029,0.375 7.894,0.517 7.878,0.53 7.868,0.55 7.868,0.572 c 0,0.033 0.019,0.064 0.048,0.073" />
</g>
<g transform="matrix(12.997776,0,0,-12.997776,306.99861,703.01559)">
<path d="m 0,0 c 0.02,0 0.034,0.014 0.04,0.036 0,0 2.277,7.479 2.277,7.486 0,0.02 -0.012,0.042 -0.031,0.044 0,0 -2.805,0 -2.807,0 -0.014,0 -0.023,-0.011 -0.026,-0.026 0,-0.001 -0.581,-1.945 -0.581,-1.946 -0.004,-0.016 -0.012,-0.026 -0.026,-0.026 -0.014,0 -0.026,0.014 -0.028,0.026 L -1.79,7.541 c -0.002,0.013 -0.012,0.025 -0.026,0.025 -10e-4,0 -3.1,0.001 -3.1,0.001 -0.009,-0.002 -0.017,-0.01 -0.02,-0.018 0,0 -0.545,-1.954 -0.545,-1.954 -0.003,-0.017 -0.012,-0.027 -0.027,-0.027 -0.013,0 -0.024,0.01 -0.026,0.023 l -0.578,1.952 c -0.001,0.012 -0.011,0.022 -0.023,0.024 l -2.992,0 c -0.024,0 -0.044,-0.02 -0.044,-0.045 0,-0.004 10e-4,-0.012 10e-4,-0.012 0,0 2.31,-7.471 2.311,-7.474 C -6.853,0.014 -6.839,0 -6.819,0 c 0.003,0 2.485,-0.001 2.485,-0.001 0.015,0.002 0.03,0.019 0.034,0.037 10e-4,0 0.865,2.781 0.865,2.781 0.005,0.017 0.012,0.027 0.026,0.027 0.015,0 0.023,-0.012 0.027,-0.026 L -2.539,0.024 C -2.534,0.01 -2.521,0 -2.505,0 -2.503,0 0,0 0,0" />
</g>
<g transform="matrix(12.997776,0,0,-12.997776,278.90126,499.03369)">
<path d="m 0,0 c -0.451,0 -1.083,-0.232 -1.446,-0.501 -0.363,-0.269 -0.888,-0.882 -0.888,-1.727 0,-0.845 0.513,-1.502 0.513,-1.502 0.263,-0.326 0.925,-1.01 0.925,-1.01 0.015,-0.016 0.024,-0.037 0.024,-0.06 0,-0.051 -0.041,-0.093 -0.092,-0.093 -0.008,0 -6.046,0 -6.046,0 l 0,-2.674 7.267,0 c 0.988,0 1.539,0.538 1.69,0.689 0.15,0.15 0.65,0.713 0.65,1.646 0,0.932 -0.425,1.414 -0.607,1.633 -0.162,0.196 -0.808,0.876 -0.943,1.017 -0.016,0.014 -0.026,0.034 -0.026,0.056 0,0.033 0.019,0.063 0.048,0.073 l 3.5,0 0,-5.114 2.691,0 0,5.101 3.267,0 0,2.466 L 0,0 Z" />
</g>
<g transform="matrix(12.997776,0,0,-12.997776,583.96822,539.30215)">
<path d="m 0,0 -1.651,-0.001 c 0,0 -0.044,0.013 -0.044,0.063 l -10e-4,0.833 c 0,0.05 0.044,0.063 0.044,0.063 l 1.514,0 C 0.038,0.958 0.394,0.87 0.394,0.463 0.394,0.056 0,0 0,0 m 2.178,-1.79 c -0.45,0.002 -0.482,0.181 -0.482,0.207 0,0.046 0.056,0.075 0.056,0.075 0.169,0.081 0.514,0.35 0.514,0.35 0.732,0.57 0.82,1.352 0.82,1.771 0,0.42 -0.063,1.163 -0.814,1.814 C 1.521,3.078 0.57,3.098 0.57,3.098 l -5.287,0 c 0,0 0,-7.522 0,-7.524 0,-0.024 0.022,-0.043 0.046,-0.043 0.005,0 2.943,0 2.943,0 l 0,2.109 c 0,0.038 0.057,0 0.057,0 l 1.533,-1.539 c 0.545,-0.551 1.446,-0.57 1.446,-0.57 l 4.525,0 0,2.679 -3.655,0 z" />
</g>
<g transform="matrix(12.997776,0,0,-12.997776,466.86346,556.40203)">
<path d="m 0,0 -1.107,0 c -0.041,0 -0.067,0.044 -0.067,0.086 0,0.016 0.589,1.914 0.589,1.914 0.021,0.071 0.027,0.073 0.031,0.073 l 0.001,0 c 0.004,0 0.01,-0.002 0.031,-0.073 0,0 0.589,-1.898 0.589,-1.914 C 0.067,0.044 0.04,0 0,0 M 1.49,4.347 C 1.479,4.385 1.446,4.412 1.405,4.414 l -4.065,0 C -2.7,4.412 -2.734,4.385 -2.745,4.348 c 0,0 -2.245,-7.42 -2.245,-7.434 0,-0.037 0.03,-0.067 0.067,-0.067 l 2.687,0 c 0.022,0.007 0.038,0.028 0.043,0.051 l 0.313,1.001 c 0.01,0.024 0.033,0.041 0.061,0.042 l 2.478,0 C 0.687,-2.061 0.71,-2.078 0.721,-2.102 l 0.32,-1 c 0.005,-0.023 0.021,-0.044 0.042,-0.052 0,0 2.642,10e-4 2.644,10e-4 0.037,0 0.067,0.028 0.067,0.066 0,0.012 -2.304,7.434 -2.304,7.434" />
</g>
</g>
</defs>
<rect style="fill:#8AB" width="364" height="172" />
<use style="fill:white;" filter="url(#Blur)" xlink:href="#Img"
transform="translate(1.8,.9)"/>
<use style="fill:black;" xlink:href="#Img"/>
</svg>

If your SVG element is <text>, you can use the CSS property text-shadow without any problem. Syntax is text-shadow: color x-offset-px y-offset-px blur-px.

Probably an evolution, it appears that inline css filters works nicely on elements, in a certain way.
Declaring a drop-shadow css filter, in an svg element, in both a class or inline does NOT works, as specified earlier.
But, at least in Firefox, with the following wizardry:
Appending the filter declaration inline, with javascript, after DOM load.
// Does not works, with regular dynamic css styling:
shadow0.oninput = () => {
rect1.style.filter = "filter:drop-shadow(0 0 " + shadow0.value + "rem black);"
}
// Okay! Inline styling, appending.
shadow1.oninput = () => {
rect1.style += " ;filter:drop-shadow(0 0 " + shadow1.value + "rem black);"
rect2.style += " ;filter:drop-shadow(0 0 " + shadow1.value + "rem black);"
}
<h2>Firefox only</h2>
<h4>
Does not works!
<input id="shadow0" type="number" min="0" max="100" step="0.1">
| Okay!
<input id="shadow1" type="number" min="0" max="100" step="0.1">
<svg viewBox="0 0 120 70">
<rect id="rect1" x="10" y="10" width="100" height="50" fill="#c66" />
<!-- Inline style declaration does NOT works at svg level, no shadow at loading: -->
<rect id="rect2" x="40" y="30" width="10" height="10" fill="#aaa" style="filter:drop-shadow(0 0 20rem black)" />
</svg>

I'm not aware of a CSS-only solution.
As you mentioned, filters are the canonical approach to creating drop shadow effects in SVG. The SVG specification includes an example of this.

Related

How to fit svg width/height to be the same as path width/height

I have this svg that renders an arrow
<div style="position: absolute; z-index: 0;">
<svg
width="373"
height="280"
overflow="auto"
style="position: absolute; left: 630.922px; top: -305px; pointer-events: none;"
>
<path
d="M 20 260 C 20 260, 334.74671750091653 33.15551891825835, 334.74671750091653 33.15551891825835"
stroke="CornflowerBlue"
stroke-dasharray="0 0"
stroke-width="5"
fill="transparent"
pointer-events="visibleStroke"
></path>
<g
fill="CornflowerBlue"
pointer-events="auto"
transform="translate(319.89194405571646,25.37183689162216) rotate(-35.78107386189255) scale(30)"
opacity="1"
>
<animate
dur="0.4"
attributeName="opacity"
from="0"
to="1"
begin="indefinite"
repeatCount="0"
fill="freeze"
></animate>
<path d="M 0 0 L 1 0.5 L 0 1 L 0.25 0.5 z"></path>
</g>
</svg>
</div>
This results in
As you can clearly see from the photo (it's an inspect element of the svg element though), the diagonal arrow has blue background even after the arrow's head ends. The same thing counts for the width as well, the blue background is wider than the actual arrow width. Is it possible to fit the svg width/height to be the same on as the path's? The paths looks like this:
If possible, how can I achieve this?
Draw your arrows outside the SVG by either changing the path data or by adding a viewBox to the SVG element with a x/y/width/height that shifts the arrows outside the SVG's boundaries. And then add overflow: visible to your SVG element.
In this example I have a viewBox 500 in width and 300 in height. I made a line from the left bottom corner to the top right corner. I turned the arrow into a <marker>. To hide the start and the end of the line I added a stroke-dasharray there the first segment in 0, a space of 1, a segment of 98 and a space of 1 (0 1 98 1). The path length is set to 100.
<svg viewBox="0 0 500 300" width="500">
<defs>
<marker id="arrow" viewBox="0 0 1 1" refX="1" refY=".5"
markerWidth="6" markerHeight="6"
orient="auto-start-reverse">
<path d="M 0 0 L 1 0.5 L 0 1 L 0.25 0.5 z" fill="CornflowerBlue" />
</marker>
</defs>
<rect width="500" height="300" fill="#eee"/>
<line x1="0" y1="300" x2="500" y2="0" stroke-dasharray="0 1 98 1"
pathLength="100" stroke="CornflowerBlue" stroke-width="5" marker-end="url(#arrow)" />
</svg>

How to modify the size of a <g> (SVG element)?

I can not seem to succeed at modifying the size of my element that is rendered inside a recharts graph as X axis. I want it to be 20px height and width. I couldn't even succeed by making modifications in the console css to the element. Could anyone help me out?
Here's the element:
<svg
style={{ cursor: 'pointer', }} width="20px" height="20px"
>
<g transform={`translate(10,10)`} fill="green" stroke="green">
<path
fill="current"
fillRule="evenodd"
d="M8,0 C3.58862306,0 0,3.58862306 0,8 C0,12.4113769 3.58862306,16 8,16 C12.4113769,16 16,12.4113769 16,8 C16,3.58862306 12.4113769,0 8,0 Z M12.0546875,6.3046875 L7.72131347,10.6379394 C7.59130859,10.7679443 7.42065431,10.833374 7.25,10.833374 C7.07934569,10.833374 6.90869141,10.7679443 6.77868653,10.6379394 L4.61206056,8.47131347 C4.35131837,8.21069338 4.35131837,7.78930663 4.61206056,7.52868653 C4.87268066,7.26794434 5.29394531,7.26794434 5.5546875,7.52868653 L7.25,9.22399903 L11.1120606,5.36206056 C11.3726807,5.10131837 11.7939453,5.10131837 12.0546875,5.36206056 C12.3153076,5.62268066 12.3153076,6.04394531 12.0546875,6.3046875 Z"
transform="translate(.5)"
/>
</g>
</svg>
As #enxaneta recommended, a negative viewBox offset like viewBox="-0.5 -0.5 17 17" is a straight forward solution.
Alternatively, you could scale your <g> (or your path) like so:
.svg{
display:inline-block;
width:10em;
border: 1px solid #ccc
}
<svg class="svg" viewBox="0 0 16 16">
<g transform="scale(0.94117647)" transform-origin="8 8" stroke-width="1" fill="green" stroke="green">
<path d="M8,0 C3.58862306,0 0,3.58862306 0,8 C0,12.4113769 3.58862306,16 8,16 C12.4113769,16 16,12.4113769 16,8 C16,3.58862306 12.4113769,0 8,0 Z M12.0546875,6.3046875 L7.72131347,10.6379394 C7.59130859,10.7679443 7.42065431,10.833374 7.25,10.833374 C7.07934569,10.833374 6.90869141,10.7679443 6.77868653,10.6379394 L4.61206056,8.47131347 C4.35131837,8.21069338 4.35131837,7.78930663 4.61206056,7.52868653 C4.87268066,7.26794434 5.29394531,7.26794434 5.5546875,7.52868653 L7.25,9.22399903 L11.1120606,5.36206056 C11.3726807,5.10131837 11.7939453,5.10131837 12.0546875,5.36206056 C12.3153076,5.62268066 12.3153076,6.04394531 12.0546875,6.3046875 Z" ></path>
</g>
</svg>
Edit: correct scaling value
As #Carsten Massmann has pointed out it should be:
The scaling factor 0.94117647 is the result of
16/17 (original svg width / svg width + stroke-width)
transform-origin="8 8" ensures we're scaling from the center of our viewBox.
Another workaround might be to set overflow to visible to avoid any cropping:
.svg{
display:inline-block;
width:10em;
border: 1px solid #ccc
}
<svg overflow="visible" class="svg" viewBox="0 0 16 16">
<path stroke-width="1" fill="green" stroke="green" d="M8,0 C3.58862306,0 0,3.58862306 0,8 C0,12.4113769 3.58862306,16 8,16 C12.4113769,16 16,12.4113769 16,8 C16,3.58862306 12.4113769,0 8,0 Z M12.0546875,6.3046875 L7.72131347,10.6379394 C7.59130859,10.7679443 7.42065431,10.833374 7.25,10.833374 C7.07934569,10.833374 6.90869141,10.7679443 6.77868653,10.6379394 L4.61206056,8.47131347 C4.35131837,8.21069338 4.35131837,7.78930663 4.61206056,7.52868653 C4.87268066,7.26794434 5.29394531,7.26794434 5.5546875,7.52868653 L7.25,9.22399903 L11.1120606,5.36206056 C11.3726807,5.10131837 11.7939453,5.10131837 12.0546875,5.36206056 C12.3153076,5.62268066 12.3153076,6.04394531 12.0546875,6.3046875 Z" ></path>
</svg>
Caveats: your icon will be displayed larger than your original design and might cause layout inconsistencies when used with other elements that fit the 16x16 boundaries.
If it will be useful to you, I found svg similar to yours and I demonstrated how you can add styles
svg {
background: #479840;
border-radius: 50%;
}
path {
filter: invert(99%) sepia(99%) saturate(2%) hue-rotate( 205deg)
brightness(110%) contrast(100%);
}
<svg height="44" viewbox="0 0 24 24" width="44" xmlns="http://www.w3.org/2000/svg">
<path d="m10 15.586-3.293-3.293-1.414 1.414L10 18.414l9.707-9.707-1.414-1.414z"></path></svg>

How can I add a specific box shadow to my svg?

So I know there is a question similar to this: How to add box-shadow to a svg path circle shape but I am having trouble understanding how they transitioned the box shadow characteristics to the svg drop shadow characteristics. (Especially as SVG Drop shadows don't have the concept of a spread radius.)
I am trying to get this exact box shadow: box-shadow: 0px 10px 25px 0px rgba(18, 103, 17, 0.15);
And I currently have:
<svg width="250" height="250">
<defs>
<filter id="drop-shadow">
<feGaussianBlur in="SourceAlpha" stdDeviation="25" />
<feOffset dx="0" dy="10" result="offsetblur" />
<feOffset dx="-10" dy="0" result="offsetblur" />
<feFlood flood-color="rgba(18, 103, 17, 0.15)" flood-opacity="1" />
<feComposite in2="offsetblur" operator="in" />
<feMerge>
<feMergeNode />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<circle cx="112.53" cy="112.53" r="87" fill="none" stroke="#74C947" stroke-width="25.53" style="filter: url(#drop-shadow);"></circle>
</svg>
Also if I can just use box-shadow css on the svg circle I'm happy to do so, but that doesn't seem to be an option (it only allows drop shadows).
Add a class to the svg and define the shadow in the class.
<svg class='svg-shadow'>...</svg>
.svg-shadow {
box-shadow: 10px 5px 5px #000;
}
In the specification for box shadow it says...
...the image that would be generated by applying to the shadow a Gaussian blur with a standard deviation equal to half the blur radius
So if you want to create a drop shadow in SVG you need to divide the box shadow blur radius (in your case 25px) by two and therefore you want stdDeviation="12.5"
Note that you can simplify your code.
SVG actually has a feDropShadow element so you could just use that
<svg width="250" height="250">
<defs>
<filter id="drop-shadow">
<feDropShadow stdDeviation="12.5" dx="10" dy="-10" flood-color="rgba(18, 103, 17, 0.15)" />
</filter>
</defs>
<circle cx="112.53" cy="112.53" r="87" fill="none" stroke="#74C947" stroke-width="25.53" style="filter: url(#drop-shadow);"></circle>
</svg>
but there's an even easier way using the canned drop-shadow filter i.e.
<svg width="250" height="250">
<circle cx="112.53" cy="112.53" r="87" fill="none" stroke="#74C947" stroke-width="25.53" style="filter: drop-shadow(10px -10px 12.5px rgba(18, 103, 17, 0.15))"></circle>
</svg>

How to invert alpha channel of svg

I have an SVG image like this. I would like to invert it, such that everything that is black becomes transparent, and everything that is transparent becomes black. So the result would be a black square with a transparent, square shaped 'hole' in the middle. How can I achieve this?
Code for the svg:
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 99.999997 99.999997"
height="100"
width="100">
<g
transform="translate(0,-952.36223)"
>
<path
d="M 50.000001,954.80939 65.450848,986.11624 100,991.13652 74.999998,1015.5055 80.901699,1049.915 50,1033.6691 19.098298,1049.915 25.000001,1015.5055 -1.2134336e-6,991.13652 34.549151,986.11624 Z"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:22.67716599;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</svg>
Use the path as a mask like below:
body {
background:pink;
}
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 99.999997 99.999997">
<defs>
<mask id="hole">
<rect width="100%" height="100%" fill="white"/>
<path transform="translate(0,-952.36223)"
d="M 50.000001,954.80939 65.450848,986.11624 100,991.13652 74.999998,1015.5055 80.901699,1049.915 50,1033.6691 19.098298,1049.915 25.000001,1015.5055 -1.2134336e-6,991.13652 34.549151,986.11624 Z"
fill="black" />
</mask>
</defs>
<rect fill="black" width="100%" height="100%" mask="url(#hole)" />
</svg>
The original answer showed an approach using the feFuncA primitive - GetSelf pointed out below that it wasn't working due to browser bugs).
Another approach that works is to invert the alpha channel using a feColorMatrix filter. Updated code below. Note this still won't work on fully transparent colored shapes in Chrome since it seems to discard any color channel values for shapes with opacity below 0.005.
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 99.999997 99.999997"
height="100"
width="100">
<defs>
<filter id="invert-alpha">
<feColorMatrix type="matrix" values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 -1 1"/>
</filter>
</defs>
<g
transform="translate(0,-952.36223)" filter="url(#invert-alpha)"
>
<path
d="M 50.000001,954.80939 65.450848,986.11624 100,991.13652 74.999998,1015.5055 80.901699,1049.915 50,1033.6691 19.098298,1049.915 25.000001,1015.5055 -1.2134336e-6,991.13652 34.549151,986.11624 Z"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:22.67716599;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</svg>

SVG path with border

How can I create a path with a fill and outline similar to
So far I have found a couple of ways but none that is particularly clean.
One way would be to use paint-order but this does not work in mobile and IE.
Another way duplicate the path... but this would create needless amounts of data.
Is there a different way to use CSS to simply create an outline or border for an SVG path?
<svg height="50" width="300">
<path d="M5 20 1215 20" />
</svg>
path {
fill: red;
stroke: #646464;
stroke-width:10px;
stroke-linejoin: round;
}
Here is a codepen
You have to draw the path as an outline as so:
<svg xmlns="http://www.w3.org/2000/svg" width="220" height="220" viewBox="0 0 220 220">
<path fill="#ddd" stroke="#3f4141" d="M0 0h220v220H0z"/>
<path fill="#fff" stroke="#00b400" stroke-width="4"
d="M 159.8 30.3
h -110
v 120
h-20
l 30 40
30 -40
h-20
v-100
h90"/>
</svg>
Sketched in Inkscape, optimised in SVGOMG then tweaked by hand.
EDIT
I have a working solution using markers that works as follows:
Create the line (any line) as a symbol
Create a faux - stroke by layering two instances of the line on top of each other, with different line widths
Add arrow with pre-defined stroke as marker
Hairline stroke shows through sometimes at start of line ... solve this using another marker that masks using the background color.
this technique would only work over a plain background.
<svg style="display: inline-block; margin-left: 2em;" width="220" height="220" viewBox="0 0 220 220" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<style>
.arrow-stroke {
stroke: #00b400;
stroke-width: 28;
/* marker-end etc should be supported but unsure of browser support */
}
.arrow-fill {
stroke: white;
stroke-width: 20
}
</style>
<marker id="arrow" markerWidth="45" markerHeight="70" refX="5" refY="35" orient="auto" markerUnits="userSpaceOnUse">
<path fill="#fff" stroke="#00b400" stroke-width="4" d="M 2 25 v-20 l 40,30 -40,30 v-20"/>
</marker>
<!-- Used to hide hairline that shows through, fill color must match background color -->
<marker id="startMask" markerWidth="2" markerHeight="30" refX="1" refY="15" orient="auto" markerUnits="userSpaceOnUse">
<path fill="#ddd" d="M0 0 v30 h2 v-30 z" />
</marker>
<symbol id="line">
<path d="M 159.8 30.3 h -110 v 120"/>
</symbol>
<symbol id="line2">
<path d="M 140 60 l 20 30"/>
</symbol>
<symbol id="line3">
<path d="M 100 80 q 0 40 20 70"/>
</symbol>
</defs>
<path id="grey-box" fill="#ddd" stroke="#3f4141" d="M0 0h220v220H0z"/>
<g fill="none">
<use xlink:href="#line" class="arrow-stroke" />
<use xlink:href="#line" class="arrow-fill" marker-end="url(#arrow)" marker-start="url(#startMask)" />
<use xlink:href="#line2" class="arrow-stroke" />
<use xlink:href="#line2" class="arrow-fill" marker-end="url(#arrow)" marker-start="url(#startMask)" />
<use xlink:href="#line3" class="arrow-stroke" />
<use xlink:href="#line3" class="arrow-fill" marker-end="url(#arrow)" marker-start="url(#startMask)" />
</g>
</svg>
Hope this helps

Resources