CSS: change opacity of svg path on hover - css

I would like to change opacity of an inline SVG path from CSS. Here is the code :
canvas { background-color:#777;}
svg { position:absolute; top: 0px;left:0px;}
#circle:hover {opacity: 0.9;}
#square:hover {opacity: 0.9;}
<canvas width="300px" height="300px"></canvas>
<svg height="300" width="300" pointer-events="none" >
<circle id="circle" cx="100" cy="100" r="40" stroke="black" stroke-width="3" fill="red" pointer-events="all" opacity="0.3"/>
<path id="square" d="M150 150 H 250 V 250 H 150 L 150 150" opacity="0.3"/>
</svg>
As you'll notice, it works with the circle, but not with the path. My questions are:
Why isn't it working with the path?
What should I do to apply the hover opacity to the path?

The path inherits pointer-events="none" from its parent.
The circle doesn't because it overrides that parent pointer-events value.
If you want something to respond to mouse events, don't have it set it as pointer-events none.

Remove pointer-events="none" then it will work fine.
Pointing none The element does not react to pointer events. Hence it doesn't work.
See details
canvas { background-color:#777;}
svg { position:absolute; top: 0px;left:0px;}
#circle:hover {opacity: 0.9;}
#square:hover {opacity: 0.9;}
<canvas width="300px" height="300px"></canvas>
<svg height="300" width="300" >
<circle id="circle" cx="100" cy="100" r="40" stroke="black" stroke-width="3" fill="red" pointer-events="all" opacity="0.3"/>
<path id="square" d="M150 150 H 250 V 250 H 150 L 150 150" opacity="0.3"/>
</svg>

Related

How to change svg path width on hover

I have an issue I can't find an helpful answer. I have a svg arrow, the arrow has to grow when the user hovers over with the mouse. The problem is that only the line has to change size not the arrow head. I just want the line to grow horizontally.
This is the svg code
<svg width="51" height="8" viewBox="0 0 51 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M50.3536 4.35355C50.5488 4.15829 50.5488 3.84171 50.3536 3.64645L47.1716 0.464466C46.9763 0.269204 46.6597 0.269204 46.4645 0.464466C46.2692 0.659728 46.2692 0.976311 46.4645 1.17157L49.2929 4L46.4645 6.82843C46.2692 7.02369 46.2692 7.34027 46.4645 7.53553C46.6597 7.7308 46.9763 7.7308 47.1716 7.53553L50.3536 4.35355ZM0 4.5H50V3.5H0V4.5Z" fill="black"/>
</svg>
And this is the code the I have working right now
svg {
width: 50px;
overflow: visible;
transition: width 0.5s ease;
}
svg:hover {
width: 100px;
}
I also have a Codepen link
https://codepen.io/godhandkiller/pen/xxRZeYv
The problem here is that I'm manipulating the whole SVG but I only need to change the like size.
A possible solution: you can use a line path with a marker-end. The marker is the tip of the arrow. For the animation I'm using SMIL animations changing the d attribute of the path from M1,4L25,4 to M1,4L50,4. The animate element has a begin attribute making the animation to begin when you mouse over the overlaying rectangle: begin="theRect.mouseover". Another animate element animates the path on mouse out: begin="theRect.mouseout"
svg {
border: 1px solid red;
transition: width 0.5s ease;
}
<svg id="theSVG" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 51 8" stroke="#000" stroke-linecap="round">
<defs>
<marker id="m" overflow="visible" markerUnits="userSpaceOnUse">
<path d="M-3,-3L0,0 -3,3" />
</marker>
</defs>
<path d="M1,4L25,4" marker-end="url(#m)">
<animate attributeName="d" to="M1,4L50,4" dur="1s" begin="theRect.mouseover" repeatCount="1" fill="freeze" />
<animate attributeName="d" to="M1,4L25,4" dur="1s" begin="theRect.mouseout" repeatCount="1" fill="freeze" />
</path>
<rect width="100%" height="100%" stroke="none" pointer-events="all" id="theRect" />
</svg>

svg rotate 90deg but disappear

I have a svg which is an arrow facing right. However, i am unable to make the arrow downward by adding transform: rotate(). When I change css svg path, the entire arrow is gone. How do I solve it?
Before:
After:
In my html and css,
svg path {
transform: rotate(90);
}
<svg class="arrow-right" xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 25 25">
<g id="ico___black" data-name="ico_>_black" transform="translate(19525 16160)">
<path id="パス_60" data-name="パス 60" d="M1061.961,192.633l5.465,5.465,5.465-5.465"
transform="translate(-19707.389 -15080.434) rotate(-90)" fill="none" stroke="#2b2525"
stroke-width="2" />
<rect id="長方形_124" data-name="長方形 124" width="25" height="25" transform="translate(-19525 -16160)"
fill="none" />
</g>
</svg>
you can apply the transform on the svg instead of the path.
svg {
transform: rotate(90);
}

Animating feComposite SVG filter elements

I have two svg shapes, one on top of the other, and I've applied the feComposite filter on both so that the top shape knocks out part of the bottom shape. The code is as follows and works fine.
<svg width="100" height="100">
<defs>
<filter id="myfilter">
<feImage xlink:href="#layer1" result="lay1"/>
<feImage xlink:href="#layer2" result="lay2"/>
<feComposite operator="out" in="lay1" in2="lay2"/>
</filter>
</defs>
<g filter="url(#myfilter)">
<circle id="layer1" cx="50" cy="50" r="40" stroke-
width="0" fill="green" />
<circle id="layer2" class="small" cx="20" cy="60" r="20" stroke-
width="0" fill="red" />
</g>
</svg>
Now I want to animate the top shape, but when I tried to apply the animation, both shapes animates and I can't figure out why because I've only targeted the second shape with class="small". Here is the css code for the animation.
#keyframes rock {
0% {
transform: rotate(45deg);
}
50% {
transform: rotate(0deg);
}
100% {
transform: rotate(-45deg);
}
}
.small {
animation-name: rock;
animation-duration: 5s;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
I am puzzled by this behavior and hope someone can shed some light to this problem. Is it not possible to animate the svg elements individually when filters are applied to them as a group? But that doesn't seem to make sense because the svg elements can be targeted individually.
Here is a link to codepen: https://codepen.io/lanlanonearth/pen/bGbRyVo
Please try this: You put both circles in the <defs> and you <use xlink:href="#layer1". Next you apply the filter to the <use> element.
<svg width="100" height="100">
<defs>
<circle id="layer1" cx="50" cy="50" r="40" stroke-width="0" fill="green" />
<circle id="layer2" class="small" cx="20" cy="60" r="20" stroke-width="0" fill="red" />
<filter id="myfilter">
<feImage xlink:href="#layer1" result="lay1"/>
<feImage xlink:href="#layer2" result="lay2"/>
<feComposite operator="out" in="lay1" in2="lay2"/>
</filter>
</defs>
<use xlink:href="#layer1" filter="url(#myfilter)"></use>
</svg>
Check it on codepen

svg grouped elements jointly hover

Is it possible for hover on an svg element cause other elements with the same class to hover too without jQuery? Or do I have to next the two into an outer group?
I have inside an inline svg the following groups:
<g class="class1">
<path....>
<path....>
</g>
<g class="class1">
<path....>
<path....>
</g>
I then have in my CSS:
class1 {
...
}
class1:hover {
...
}
I guess you can't do it directly, but you can achieve it by adding an id to the parent element, no classes needed, like that:
#circles:hover circle{
fill: Wheat;
}
<svg id="circles" width="100" height="260" >
<circle cx="50" cy="50" r="40" stroke="Tomato" stroke-width="4" fill="Tomato" />
<circle cx="50" cy="140" r="40" stroke="Tomato" stroke-width="4" fill="Aquamarine"/>
</svg>

It is possible to give <path> tag a class for css purposes?

I'd like to have two paths in my svg with classes so i can toggle opacity when I hover the svg with my mouse.
The answere to this question is easy to find, but anyway: yes it is. See the Global Attributes in https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path
.shape {
opacity: .5;
}
<svg width="300px" height="300px" viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
<path class="shape" d="M 100 100 L 300 100 L 200 300 z" fill="orange" stroke="black" stroke-width="5" />
</svg>
Yes, you would use the stroke-opacity option.

Resources