JSFiddle example. The idea is, hovering over the big rectangle scales it in addition causing the other two smaller rectangles to scale too. Not vica versa.
HTML
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<g class="lower_element">
<rect x="19" y="19" width="35" height="15" />
<rect x="36" y="36" width="36.75" height="15" />
</g>
<g class="top">
<rect x="149" y="100" width="96.4" height="96.3"/>
</g>
</svg>
CSS
svg {
height: 220px;
width: 400px;
background: grey;
}
.lower_element {
fill: blue;
transform-origin: center;
transform-box: fill-box;
transition-duration: 0.1s;
}
.lower_element:hover {
transform: scale(1.7);
-moz-transform: scale(1.7);
-webkit-transform: scale(1.7);
-o-transform: scale(1.7);
-ms-transform: scale(1.7);
}
.top {
fill: blue;
transform-origin: center;
transform-box: fill-box;
transition-duration: 0.1s;
}
.top:hover ~ .lower-element:hover ~ .lower-element {
transform: scale(1.7);
-moz-transform: scale(1.7);
-webkit-transform: scale(1.7);
-o-transform: scale(1.7);
-ms-transform: scale(1.7);
}
At present the two smaller rectangles are scaling. Hovering on the big rectangle has no effect. Tried to use ~ for lower_element, which seems to work with div elements, like in this example here, but it doesn't do the job in SVG.
PS. The solution is saved in the 1st mentioned JSFiddle. What I noticed while playing with the original SVG, which has more than two thousand lines of g code, that it didn't work as shown in JSFiddle. The problem was, the parent "top" element was mentioned below the sibling element. I assumed it would work, but it didn't. I was making a parallel with CSS whereas anything that is mentioned below will replace anything mentioned above and thus should work. Placing the parent "top" element above the sibling elements solved the issue.
your class name of lower_element is wrong in css. also try this:
html:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<g class="top">
<rect x="149" y="100" width="96.4" height="96.3"/>
</g>
<g class="lower_element">
<rect x="19" y="19" width="35" height="15" />
<rect x="36" y="36" width="36.75" height="15" />
</g>
</svg>
css:
svg {
height: 220px;
width: 400px;
background: grey;
}
.lower_element {
fill: white;
transform-origin: center;
transition-duration: 0.1s;
}
.top {
fill: blue;
transform-origin: center;
transition-duration: 0.1s;
}
.top:hover + .lower_element {
fill: red;
}
Related
I am trying to have scale animation on an SVG text-tag. But it seems not working on WebKit based browser (Eg, Safari, Chrome iOS).
The word Test should show up, but not in Safari:
#text {
fill: #333;
animation: scaleIn 0.3s ease-in-out forwards;
}
#keyframes scaleIn {
from {
transform: translate(50px, 50px) scale(0);
}
to {
transform: translate(50px, 50px) scale(1);
}
}
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500" fill="none">
<text x="0" y="0" alignment-baseline="central" dominant-baseline="central" id="text" text-anchor="middle">
Test
</text>
</svg>
Just ran into this problem myself. I found that wrapping the text element in a group tag and then applying your id to the group tag will fix your issue. I tested it on your code and it works a treat. Good luck!
#text {
fill: #333;
animation: scaleIn 0.3s ease-in-out forwards;
}
#keyframes scaleIn {
from {
transform: translate(50px, 50px) scale(0);
}
to {
transform: translate(50px, 50px) scale(1);
}
}
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500" fill="none">
<g id="text">
<text x="0" y="0" alignment-baseline="central" dominant-baseline="central" text-anchor="middle">
Test
</text>
</g>
</svg>
In the following example I created a blinking eyes animation using CSS and an SVG: http://codepen.io/JamesTheHacker/pen/oLZVrY
It works fine in chrome, but on Firefox the eyes do not appear unless I specifically provide a width and height attribute on the <rect>.
Without the attribute the eyes are not visible. If I add the attribute the CSS height animation has no effect.
In SVG 1.1 height and width are attributes i.e. you can't set the height and width via CSS.
In SVG 2 it is proposed width and height should be CSS properties.
Back in 2016 only Chrome had implemented this part of the unfinished SVG 2 specification, since then Firefox has also implemented it so the testcase works as expected.
You have already an excellent answer indicating what the problem is
You can solve it this way
* { box-sizing: border-box; }
body { background-color: rgb(0, 184, 234); }
svg {
display: block;
margin: 90px auto;
width: 380px;
height: 130px;
}
/*
* Keyframes for blink animation
*/
#keyframes blink {
0% { transform: scaleY(1); }
40% { transform: scaleY(0); }
80% { transform: scaleY(1); }
}
.eye {
height: 20px;
width: 20px;
animation-name: blink;
animation-duration: 1s;
animation-iteration-count: infinite;
transform-origin: center 315px;
}
<svg>
<g transform="translate(-108.75 -258.41)">
<path id="specs" fill="#FFF" d="M328.911,258.412v10.29h-19.127v16.192h-19.16v16.249h19.287v-16.191h19v62.169h19.432
v-68.736h123.995v68.761h19.432v-88.709l-18.047,0.001v-0.025h-125.38H328.911z M124.069,258.454v0.001h-15.321v88.709h19.427
v-68.733h123.996l0.008,68.757h19.423v-62.401h19.032v-16.25h-19.032v-10.053h-18.047v-0.026H124.072L124.069,258.454z
M348.294,347.163v17.488h19.4v19.951h85.141v-19.976h-85.109v-17.464H348.294L348.294,347.163z M452.819,347.171v17.439h19.431
v-17.439H452.819z M128.133,347.203v17.487h19.398v19.951h85.149l-0.008-19.975h-85.117l0.001-17.464h-19.427H128.133z
M232.658,347.212v17.439h19.423v-17.439H232.658z"/>
<g id="eyes">
<rect class="eye" x="181.759" y="305.026" width="20" height="20" fill="#FFF" />
<rect class="eye" x="402.759" y="305.026" width="20" height="20" fill="#FFF" />
</g>
</g>
</svg>
I'm trying to animate svg path when mouse is over the container dom element(a), which is bigger than svg element itself(for bigger contact area). I can't rotate whole container, because svg element will contain some more paths, which should be static. Now green arrow does not accept the initial position when mouse leaves, that I would like to see happen.
https://jsbin.com/juqene/18/edit?html,css,output
HTML:
<div id="outer">
<svg xmlns="http://www.w3.org/2000/svg" width="56" height="56" viewBox="0 0 56 56">
<path id="arrow" fill="none" stroke="#21B469" stroke-miterlimit="10" d="M26.637 55.68L.583 28.346 25.333.32"/>
</svg>
</div>
CSS:
#arrow {
transform: none;
}
#outer:hover #arrow {
transform: rotate(10deg);
}
Change this
#arrow {
transform: none
}
to this
#arrow {
transform: rotate(0);
}
#inner {
width: 10px;
height: 100px;
background-color: red;
margin: 0 auto;
}
#arrow {
transform: rotate(0);
}
#outer:hover #arrow {
transform: rotate(10deg);
}
<div id="outer">
<svg xmlns="http://www.w3.org/2000/svg" width="56" height="56" viewBox="0 0 56 56">
<path id="arrow" fill="none" stroke="#21B469" stroke-miterlimit="10" d="M26.637 55.68L.583 28.346 25.333.32" />
</svg>
</div>
I have an SVG-Document with an css stylesheet
mask .show { fill: white }
mask .hide { fill: black }
#keyframes resize {
0% { transform: scaleX(.5) }
50% { transform: scaleX(1.25) }
100% { transform: scaleX(.5) }
}
mask .resize { animation: resize 10s ease infinite; transform-origin: 10px 50px }
and use masks
<mask id="oneMask">
<rect class="show" x="0" y="0" width="100%" height="100%" />
<ellipse class="hide resize" cx="10" cy="50" rx="10" ry="50" />
</mask>
this ellipse in that mask just become black, but not will be resize, what I want from it.
The CSS is working and the #keyframes to animate anything - everything but the transform: in CSS.
See here for jsFiddle
Please help me to animate and transform this with CSS,
Thank You!!!
Is it possible to achieve perspective with 3d transforms on a SVG elements?
I'm talking about something similar with how the Star Wars opening titles look like with 3d perspective. This is a jsfiddle with the desired effect achieved using CSS3 3d transforms:
<section style="transform: perspective(200px) rotateX(-30deg); transform-origin: 50% 100%; text-align: justify; width: 100px;">
<p style="backface-visibility: hidden;">TEXTTEXTTEXT</p>
</section>
Update Nov 2018:
Testing the snipet from the question in latest chrome and Firefox works. Although support for 3d transforms on svg elements isn't very wide, browsers are implementing it more and more.
Origin answer :
3D transforms aren't supported on SVG elements. There are a few workarounds though :
If the svg doesn't contain elements that shouldn't be transformed, you can use CSS 3d transforms on the SVG element itself :
svg {
width: 70%;
margin: 0 auto;
display: block;
-webkit-transform: perspective(300px) rotateX(30deg);
transform: perspective(300px) rotateX(30deg);
}
<svg viewbox="0 0 100 20">
<text x="0" y="20">TEXTEXTEX</text>
</svg>
In case of polygons, you make a 2D polygon look like a 3D polygon. In the following example, the red rectangle is 3D rotated (rotateX(40deg)) and the black rectangle is a 2D SVG polygon made to look like a 3D rotated rectangle:
div{
display:inline-block;
width:200px; height:100px;
background:red;
transform:perspective(500px) rotateX(40deg);
}
svg{
display:inline-block;
width:220px; height:auto;
}
div, svg{
display:inline-block;
margin:0 10px;
}
<div></div>
<svg viewbox="0 0.5 10 4">
<polygon points="9.9 4.1 0.1 4.1 0.7 0.6 9.3 0.6" fill=""/>
</svg>
3D transforms are supported inside <svg> elements (f.e. on <circle>) (at least to some extent, it seems like perspective is isometric only).
For example, here's animation of transform: rotate3d applied to <circle> elements (tested in Chrome only):
body, html {
background: black;
width: 100%; height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
}
svg {
width: 100%;
}
.gAExgp {
transform-origin: 50% 50% 0px;
animation-name: phEs, ipaUyp;
animation-duration: 4s, 7s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.PwswZ {
transform-origin: 50% 50% 0px;
animation-name: gcRPJT, ipaUyp;
animation-duration: 4s, 8s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
#keyframes phEs {
50% {
transform: rotate3d(0, 2, 1, 180deg);
}
100% {
transform: rotate3d(0, 2, 1, 360deg);
}
}
#keyframes gcRPJT {
50% {
transform: rotate3d(2, 0, 1, 180deg);
}
100% {
transform: rotate3d(2, 0, 1, 360deg);
}
}
#keyframes ipaUyp {
0% {
stroke: magenta;
}
33% {
stroke: cyan;
}
66% {
stroke: yellow;
}
100% {
stroke: magenta;
}
}
<!-- Logo from https://rebassjs.org -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" style="display:block;max-width:100%;margin:0;fill:none;stroke:cyan" vector-effect="non-scaling-stroke" class="sc-htoDjs hCHUAb"><circle cx="32" cy="32" r="32" fill="#000" stroke="none"></circle><circle cx="32" cy="32" r="30" stroke-width="1" vector-effect="non-scaling-stroke" opacity="0.5"></circle><g><circle cx="32" cy="32" r="24" stroke-width="2" vector-effect="non-scaling-stroke" class="sc-dnqmqq gAExgp"></circle><circle cx="32" cy="32" r="24" stroke-width="2" vector-effect="non-scaling-stroke" class="sc-iwsKbI PwswZ"></circle></g><text x="32" y="34" text-anchor="middle" font-family="system-ui, sans-serif" font-weight="bold" font-size="4" stroke="none" fill="white" style="text-transform:uppercase;letter-spacing:0.5em">Rebass</text></svg>
Also available here: https://codepen.io/anon/pen/MPeyEj