How do I get filters to work on nested SVGs? - css

I'm trying to get a hover effect for some svgs. The code I'm working on is basically icons contained in an svg so they're all positioned on top of a background (it looks like a map - I want individual icons on the map to highlight on hover).
The problem is filters don't seem to have any effect on nested svg elements. I've tried putting the filter directly in the nested element and it doesn't change anything.
Here's a simple example of the code that I would like to work.
.icon:hover{
filter: sepia(100%);
}
<html>
<body>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg x="10" class="icon">
<rect x="10" y="10" height="100" width="100" style="fill: #0000ff"/>
</svg>
<svg x="200">
<rect x="10" y="10" height="100" width="100" style="fill: #0000ff"/>
</svg>
</svg>
</body>
</html>

You can use svg filters. The sepiatone filter is from https://gist.github.com/jorgeatgu/5b338cc1a4e0df901348
svg{border:1px solid}
.icon:hover{
filter: url(#sepiatone);
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter id="sepiatone">
<feColorMatrix type="matrix" values=".343 .669 .119 0 0 .249 .626 .130 0 0 .172 .334 .111 0 0 .000 .000 .000 1 0"/>
</filter>
</defs>
<svg x="10" class="icon">
<rect x="10" y="10" height="100" width="100" style="fill: #0000ff"/>
</svg>
<svg x="200">
<rect x="10" y="10" height="100" width="100" style="fill: #0000ff"/>
</svg>
</svg>

Related

Svg lines on edges mask only in mobile

How can i remove lines on a svg masck. It only shows in mobile. See it live on bakar.store
I've tried everything and don't understand why it shows only on mobile.
i've change the svg, the css and always shows lines in image
`
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 196.9 88.3" >
<defs>
<mask id="mask" x="0" y="0" width="100%" height="100%" >
<rect x="0" y="0" width="100%" height="100%" />
<path shape-rendering="geometricPrecision" d="M70.3,74.9c-1.9,4.3-4.8,7.2-12.9,7.2H7.1V7.8h20c5,0,8.4,1.6,10.8,3.8c3.3,3,4.2,6,4.2,18.7
c0,9.7-0.7,11.9-4.8,14.7c2.6,9.7,28.1,8.6,32,15.6C72.8,66.9,71.9,71.3,70.3,74.9z M28,32.7H15.2v8.8H28c3.6,0,5.6-1.4,5.6-4.2
C33.6,34.4,31.8,32.7,28,32.7z M27.6,48.5H15.2v9.1h12.7c4.9,0,6.5-1.6,6.5-4.7C34.4,49.9,31.8,48.5,27.6,48.5z"/>
<path shape-rendering="geometricPrecision" d="M66.9,53.4V40H53.6l0,9.4h-5l0-29c0-5.5,1.2-8,3.4-10.1c1.9-1.9,4.5-3.6,8.5-3.6c2.7,0,6.7,1.4,8.9,4.3
c1.8,2.3,2.7,3.8,2.7,9.5v33H66.9z M66.9,30.5c0-4.6-2.7-7.7-6.6-7.7c-4.3,0-6.8,3.6-6.8,7.7v5h13.4V30.5z"/>
<path shape-rendering="geometricPrecision" d="M95.2,76.4c-4.5-3.6-7.4-9.5-8.1-17.1h-0.3v22.7h-8.1V7.8h8.1v23h0.3c1-6,2.6-11.9,8.5-17.2
c4.9-4.3,39.7-5.5,47.8-5.8v24.5h-41.9c-9.4,0-14.7,5.1-14.7,12.8c0,7.6,6,12.5,14.5,12.5h11.3v24.5
C103.7,82.1,100.6,80.7,95.2,76.4z"/>
<path shape-rendering="geometricPrecision" d="M180.8,47.6c4.9,2.1,6.1,6.2,6.1,12v24.5h-8.1v-23c0-4.6-0.4-5.8-2.7-8.2c-1.4-1.7-3.6-2.5-7.5-2.5h-9.4v33.7
h-8.1V9.8h20.3c5,0,8.4,1.6,10.8,3.8c3.3,3,4.8,6,4.8,16.5C187.1,41.9,186.6,44.5,180.8,47.6z M172,34.8h-12.7v8.7H172
c4.5,0,6.5-1.3,6.5-4.1C178.5,36.4,177.3,34.8,172,34.8z"/>
<path shape-rendering="geometricPrecision" d="M137.8,82.6V69.3h-13.4v13.4h-5v-33c0-5.5,1.2-8,3.4-10.1c1.9-1.9,4.5-3.6,8.5-3.6c2.7,0,6.3,1.4,8.5,4.3
c1.8,2.3,3.1,3.8,3.1,9.5v33H137.8z M137.8,59.8c0-4.6-2.7-7.7-6.6-7.7c-4.3,0-6.8,3.6-6.8,7.7v5h13.4V59.8z"/>
</mask>
</defs>
<rect x="0" y="0" width="100%" height="100%" />
</svg>
`

Responsive SVG Mask

I have looked at several other answers on Stack:
Responsive SVG Clip Path or Mask Image
Responsive SVG image mask
But none seem to work for me. I have an SVG mask based on a path. I want it to expand to fill all available space (or contract) whilst keeping the aspect ratio of the path.
svg {
width: 100%;
height: 100%;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 237.859 264.582" preserveAspectRatio="xMinYMin meet">
<defs>
<pattern id="triangle-image" patternUnits="userSpaceOnUse" width="3918" height="3918">
<image xlink:href="images/aspirational-photos/christian-buehner-JQFHdpOKz2k-unsplash.jpg" x="0" y="0" width="100%" height="100%" />
</pattern>
<pattern id="triangle-pattern" width="100%" height="100%" patternUnits="userSpaceOnUse">
<path id="triangle-path" d="M237.844,32.946c-0.001-9.981-4.42-19.279-12.121-25.512c-7.82-6.331-17.85-8.78-27.518-6.721
c-3.373,0.717-6.639,1.979-9.707,3.751l-129.11,74.56l-42.942,24.8C6.147,109.771-0.001,120.42,0,132.312
c0,11.892,6.149,22.541,16.449,28.487l84.623,48.833l87.457,50.486c7.179,4.143,15.193,5.435,23.174,3.736
c15.41-3.279,26.166-16.532,26.156-32.222L237.844,32.946z"
fill="#fff" fill-rule="evenodd" width="100%" height="100%" />
</pattern>
<mask id="triangle-mask" width="100%">
<rect x="0" y="0" width="100%" height="100%" fill="url(#triangle-pattern)" />
</mask>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="url(#triangle-image)" mask="url(#triangle-mask)"/>
</svg>
The SVG seems to obey the path values no matter what I do. Is there a way to make it expand or contract like an image would?
I've simplified your code in the sense that I'm applying the mask to the image instead of using patterns. Also the mask is the path. I'm not using width="100%" since the width af an svg element will take all the space available i.e 100%.
I would like to understand why you need it height="100%"
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 240 265">
<defs>
<mask id="triangle-mask">
<path d="M237.844,32.946c-0.001-9.981-4.42-19.279-12.121-25.512c-7.82-6.331-17.85-8.78-27.518-6.721
c-3.373,0.717-6.639,1.979-9.707,3.751l-129.11,74.56l-42.942,24.8C6.147,109.771-0.001,120.42,0,132.312
c0,11.892,6.149,22.541,16.449,28.487l84.623,48.833l87.457,50.486c7.179,4.143,15.193,5.435,23.174,3.736
c15.41-3.279,26.166-16.532,26.156-32.222L237.844,32.946z"
fill="#fff" />
</mask>
</defs>
<image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/beagle400.jpg" mask="url(#triangle-mask)"/>
</svg>
Alternatively if you need all those patterns please remove width="100%"for the mask in your code.

SVG change cursor from `cursor:wait` into e.g. `cursor:help` after hovering n seconds (loading time for tooltip) without scripting?

There has been a question about changing the cursor using before on this site, but it asked for a solution using Javascript, and it wasn't specific about when to trigger the action to change the cursor.
My question is about SVG and CSS/SMIL without the use of other scripting languages such as Javascript.
When hovering over a certain object, how to change the cursor from cursor:wait into e.g. cursor:help? The change should be triggered after an exact amount of seconds of being hovered over the object.
The use-case is clearly presented in a minimal snippet below.
MWE SNIPPET
#MOUSE_OVER_THESE{
cursor:wait;
}
<svg id="SVG"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="250"
height="175"
viewBox="0 0 250 175">
<text font-size="10" x="10" y="20">
<tspan
x="10" dy="0">Hover over the objects below. Can the cursor</tspan><tspan
x="10" dy="12">change from "cursor:wait" into e.g. "cursor:help"</tspan><tspan
x="10" dy="12.5">after about 1 second, (which will be right</tspan><tspan
x="10" dy="12.5">about when the tooltip appears on certain</tspan><tspan
x="10" dy="12.5">browsers) without using any scripting language?</tspan></text>
<g id="MOUSE_OVER_THESE">
<rect x="50" y="100" width="60" height="50" fill="red">
<title>This is a tooltip.</title>
</rect>
<rect x="150" y="100" width="60" height="50" fill="blue">
<title>This is another tooltip.</title>
</rect>
</g>
</svg>
I can not afford to use scripting languages such as Javascript, so I am wondering if there is a more native SVG with CSS/SMIL approach.
Here is a trick using transition and a hidden element.
UPDATE
The mouse need to be moved slightly in order to see the cursor change
.hide {
transition:1s visibility 1s;
cursor:wait;
}
.hide:hover {
visibility:hidden;
}
#MOUSE_OVER_THESE {
cursor:help;
}
#MOUSE_OVER_THESE:hover + .hide {
display:none;
}
<svg id="SVG"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="250"
height="175"
viewBox="0 0 250 175">
<text font-size="10" x="10" y="20">
<tspan
x="10" dy="0">Hover over the objects below. Can the cursor</tspan><tspan
x="10" dy="12">change from "cursor:wait" into e.g. "cursor:help"</tspan><tspan
x="10" dy="12.5">after about 1 second, (which will be right</tspan><tspan
x="10" dy="12.5">about when the tooltip appears on certain</tspan><tspan
x="10" dy="12.5">browsers) without using any scripting language?</tspan></text>
<g id="MOUSE_OVER_THESE">
<rect x="50" y="100" width="60" height="50" fill="red">
<title>This is a tooltip.</title>
</rect>
<rect x="150" y="100" width="60" height="50" fill="blue">
<title>This is another tooltip.</title>
</rect>
</g>
<rect class="hide" x="50" y="100" width="160" height="50" fill="transparent"></rect>
</svg>

Applying coloured opacity to SVG image

I have an SVG that contains a <g> element, within this is a <path>, within here I specify a fill of #image0
Later in the same SVG I have my <def>, within here is my <pattern> and then the <image> tag that corresponds to the fill of #image0
The value of the href of the <image> is a base64 encoded image.
I would like to apply a coloured, semi transparent overlay on top of the image. e.g. a #F5A9A9 50% opacity overlay.
I have tried adding style="opacity: 0.5" to the <image> tag -- this applies the opacity but obviously no colour. I suspect the answer is along the lines of background-color: rgba(245,169,169, 0.5) but I am unsure where to position this,
<g class="g-item">
<path class="st0" d="M1839.1,1394.2c0,0,22.7,6.7,30,18c0,0,111.3,7.1,122.6-130.5V801.1l-827.8,260l0,226 c4.9,107,118.7,125,118.7,125c3.6-17.3,27-19.5,27-19.5L1839.1,1394.2z" data-id="0" style="fill: url("#image0");"></path>
</g>
<defs class="g-def">
<pattern id="image0" width="1" height="1" y="0" x="0" patternContentUnits="objectBoundingBox" viewBox="0 0 1 1" preserveAspectRatio="xMidYMid slice">
<image preserveAspectRatio="xMidYMid meet" width="1" height="1" x="0" y="0" xlink:href="data:image/png;base64,iVBORw0KGgoAA.....AElFTkSuQmCC" data-naturalWidth="960" data-naturalHeight="960"></image>
</pattern>
</defs>
I would like to apply a coloured, semi transparent overlay on top of the image. e.g. a #F5A9A9 50% opacity overlay.
Well, you can do just that: paint a semi-transparent rectangle on top of the image:
<defs class="g-def">
<pattern id="image0" width="1" height="1" y="0" x="0"
patternContentUnits="objectBoundingBox"
viewBox="0 0 1 1" preserveAspectRatio="xMidYMid slice">
<image preserveAspectRatio="xMidYMid meet"
width="1" height="1" x="0" y="0"
xlink:href="data:image/png;base64,iVBORw0KGgoAA.....AElFTkSuQmCC"
data-naturalWidth="960" data-naturalHeight="960"></image>
<rect width="1" height="1" fill="#F5A9A9" opacity="0.5"></rect>
</pattern>
</defs>

Show hidden rect with text on hover of another poly

I need to use pure svg for a project. I know how to get this effect simply with divs but I dont know how to make it work with svg, I dont know what im doing wrong.
I want to show a hidden black rect with white text when you hover on another polygon (and the polygon is 0.1 of opacity normal and changes to 0.8 of opacity on the same hover) Something like a tooltip with opacity and with a nice smooth transition, but pure SVG.
.showme {
opacity: 0.3;
}
.showme:hover {
opacity: 0.8;
}
.desc {
visibility: hidden;
}
.showme:hover + .desc {
visibility: visible;
}
<svg width="200" height="200" viewBox="0 0 1000 300"
xmlns="http://www.w3.org/2000/svg" version="1.1" >
<rect x="1" y="1" width="998" height="298" fill="blue" class="showme"/>
</svg>
<svg width="200" height="200" viewBox="0 0 1000 300"
xmlns="http://www.w3.org/2000/svg" version="1.1" class="desc" >
<rect x="1" y="1" width="998" height="298" fill="black" />
<text x="250" y="150" font-family="Verdana" font-size="55" fill="white">Hello world!</text>
</svg>
Please help :/
Thanks.
Keeping your svg, you can do with like this, but you'll need some slight changes:
<svg width="200" height="200" viewBox="0 0 1000 300"
xmlns="http://www.w3.org/2000/svg" version="1.1" >
<rect onmouseover='document.getElementById("desc").style.visibility = "visible"' onmouseout='document.getElementById("desc").style.visibility = "hidden"' x="1" y="1" width="998" height="298" fill="blue" class="showme"/>
</svg>
<svg width="200" height="200" viewBox="0 0 1000 300"
xmlns="http://www.w3.org/2000/svg" version="1.1" id="desc" >
<rect x="1" y="1" width="998" height="298" fill="black" />
<text x="250" y="150" font-family="Verdana" font-size="55" fill="white">Hello world!</text>
</svg>
https://jsfiddle.net/q6kkhvz7/2/

Resources