Mojave Safari 14.1.2 - css animation svg disappearing during playback - html
Is someone able to explain a problem in Safari for this simple example:
codepen example
The logo-1 class element should animate into position from right to left. On mac it works in Firefox, Chrome and in IE11/win8 in the original bigger piece of code. In Safari during css animation the svg graphics disappears and appears only after animation is done. It only animates correctly if there is an extra dummy sibling to the svg element with a 3d transform applied to it. It needs to be on a lower z-index than the svg or the animation display fails. Ideally the svg element should be the only child of the logo-1 class element.
In the codepen example animation shows correctly for me in Safari only in the first main div that has the extra element under logo-1 element.
Any ideas?
Codepen code:
.logo-1 svg {
position: absolute;
top: 0;
left: 0;
}
.logo-1-sequence {
position: absolute;
top: 0;
left: 0;
display: block;
width: 113px;
height: 134px;
transform: scale3d(1, 1, 1) translate3d(0, 0, 0);
}
#keyframes kf-frame-1-logo-1-in {
0% {
transform: scale3d(0.47, 0.47, 1) translate3d(2078px, 20px, 0);
}
100% {
transform: scale3d(0.47, 0.47, 1) translate3d(1578px, 20px, 0);
}
}
.logo-1 {
position: absolute;
z-index: 2;
width: 93px;
height: 150px;
background-color: red;
animation: kf-frame-1-logo-1-in 0.5s 0.5s both linear 1;
}
.main {
background: green;
position: relative;
width: 900px;
height: 150px;
display: block;
overflow: hidden;
}
<div class="main">
<div class="logo-1">
<div class="logo-1-sequence"></div>
<svg class="logo-1-svg" xmlns="http://www.w3.org/2000/svg" width="93" height="150" viewBox="0 0 93 150">
<rect x="10" y="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5" />
</svg>
</div>
</div>
<div class="main">
<div class="logo-1">
<!-- <div class="logo-1-sequence"></div> -->
<svg class="logo-1-svg" xmlns="http://www.w3.org/2000/svg" width="93" height="150" viewBox="0 0 93 150">
<rect x="10" y="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5" />
</svg>
</div>
</div>
Related
Applying same transform values from svg to html doesn't give the same result
I want to transform SVG to HTML. Svg texts have a transform value. Applying those values to HTML elements doesn't give the same result: the SVG have way more space between them, not in the HTML. I cannot figure why. Here is a sample code: SVG => <svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve" > <rect id="background" fill="#E0FFCC" width="512" height="512" /> <text id="company" transform="matrix(1 0 0 1 124.9124 378.1289)" font-family="'Rockwell-Regular'" font-size="48px" > My comfort </text> <text id="headline" transform="matrix(1 0 0 1 163.2376 439.8711)" font-family="'Rockwell-Regular'" font-size="21px" > fuzzboxes jazzbos </text> </svg> HTML => <div style=" position: relative; background-color: #e0ffcc; width: 512px; height: 512px; " > <div style=" position: absolute; font-family: 'Rockwell-Regular'; font-size: 48px; transform-origin: top left; transform: matrix(1, 0, 0, 1, 124.9124, 378.1289); " font-size="" > My comfort </div> <div style=" position: absolute; font-family: 'Rockwell-Regular'; font-size: 21px; transform-origin: top left; transform: matrix(1, 0, 0, 1, 163.2376, 439.8711); " font-size="" > fuzzboxes jazzbos </div> </div> Result from left to right: SVG => HTML
The reason for this is that in an SVG, the X,Y position of the text is at the baseline. In other words, the bottom left of the M is at (0,0). In HTML <div>, the text starts out inside the div. So the top left of the M will be at approximately (0,0). So the equivalent baseline will be at something like (0,30). Since it starts out lower, it will end up lower after the transform matrix is applied. Here's a demo of what I mean. I've taken the transforms out initially. Note where the text is positioned by default. Then hover over the SVG (top) or div (bottom) to see the transforms applied with an animation. svg { width: 512px; } #company, #headline { transition: transform 0.5s; } svg:hover #company { transform: translate(124.9124px, 378.1289px); } svg:hover #headline { transform: translate(163.2376px, 439.8711px); } div { transition: transform 0.5s; } div:hover div:nth-child(1) { transform: translate(124.9124px, 378.1289px); } div:hover div:nth-child(2) { transform: translate(163.2376px, 439.8711px); } <svg id="Calque_1" viewBox="0 0 512 512" xml:space="preserve" > <rect id="background" fill="#E0FFCC" width="512" height="512" /> <text id="company" font-family="'Rockwell-Regular'" font-size="48px" > My comfort </text> <text id="headline" font-family="'Rockwell-Regular'" font-size="21px" > fuzzboxes jazzbos </text> </svg> <div style=" position: relative; background-color: #e0ffcc; width: 512px; height: 512px; " > <div style=" position: absolute; font-family: 'Rockwell-Regular'; font-size: 48px; transform-origin: top left; " font-size="" > My comfort </div> <div style=" position: absolute; font-family: 'Rockwell-Regular'; font-size: 21px; transform-origin: top left; " font-size="" > fuzzboxes jazzbos </div> </div> You could make the SVG behave a closer to the HTML behaviour, by setting the SVG to use dominant-baseline: hanging. svg { width: 512px; dominant-baseline: hanging; }
How to prevent an outline on SVG path when animating clip path?
I'm trying to get this animation to work in my website. For some reason the layered paths show through so a thin white outline for the path (that's animated in) is visible ruining the animation, despite the fact the paths are identical in size. I wondered if anyone has any suggestions on how to prevent this? I've made a jsFiddle and added the code below. If you change the background for the body to black it's even clearer. Any help would be appreciate. body { background: #333; padding: 2em; } svg { display: block; left: 50%; max-width: 8em; position: absolute; top: 50%; transform: translate(-50%,-50%); } #rect { animation: slideOver 5s linear infinite; } #keyframes slideOver { 0% { transform: translateX(0); } 100% { transform: translateX(100%); } }v <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 346"> <defs> <clipPath id="clip-path"> <rect id="rect" x="0" y="0" height="346" width="250"/> </clipPath> </defs> <path fill="#fff" d="M1.9 0h245.9v58H1.9zM250.1 139.9l-43.8-43.8-81.2 81.2-81.3-81.2L0 139.9l81.2 81.2L0 302.3l43.8 43.9 81.3-81.2 81.2 81.2 43.8-43.9-81.2-81.2"/> <path clip-path="url(#clip-path)" fill="#000" d="M1.9 0h245.9v58H1.9zM250.1 139.9l-43.8-43.8-81.2 81.2-81.3-81.2L0 139.9l81.2 81.2L0 302.3l43.8 43.9 81.3-81.2 81.2 81.2 43.8-43.9-81.2-81.2"/> </svg>
How to set opacity of svg from 0 - 1 when hovering a parent element?
I'd like to create a hover statement on a container, where when i hover over the Parent, it moves 40px to the right, and a yellow box sets its opacity from 0 to 1. The 40px to the right works just fine. But the box problem is killing me. .Parent:hover { position: absolute; transform: translate(40px, 0); width: 1180px; height: 199px; left: 46px; top: 50px; overflow: visible; } <div class="Parent"> <svg class="YELLOW_BOX" viewBox="0 0 1180 140"> <rect class="Yellow_box_class" rx="0" ry="0" x="0" y="0" width="1180" height="140"></rect></svg> <div class="TEXT_Class"> <span>TEXT</span> </div> </div> How do i set the opacity of "YELLOW_BOX" to 1, when hovering the parent?
It should work .parent:hover .yellow_box { opacity: 0 !important; }
Thanks for the answer. This seemed to solve my issue .Parent:hover .Yellow_box_class { opacity: 1; fill: rgba(255,237,89,1);
CSS svg hover animation/transition
im using a svg clip-path as mask for an image. Now i want an inner border inside it on hover. So i made a second clip-path for hover but the transition doesnt affect it. I want the border comming from the sides (reducing zoom/negative scaling). Here you can see what i want without working animation/transition: body { background: #ccc; } .clip-svg { position: relative; display: block; height: 400px; width: 300px; background-position: center center; background-size: auto 100%; clip-path: url(#Emblem); transition: 0.4s all ease; } .clip-svg:hover { clip-path: url(#Emblem2); } <div class="clip-svg" style="background-image: url(https://images.pexels.com/photos/864994/pexels-photo-864994.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260)"></div> <svg width="0" height="0"> <defs> <clipPath id="Emblem"> <path d="M279,240c0,96-139.4,145-139.4,145S22,336,22,240c0-58,0-203,0-203s65-11,129-11c75,0,128,11,128,11S279,136,279,240z"/> </clipPath> <clipPath id="Emblem2"> <path d="M39,51.6V240c0,72.4,80.9,116.6,101.2,126.5c11-4.5,35.7-15.4,59.8-32.3c18.5-13,33.2-26.8,43.6-41.3 c12.2-17,18.4-34.8,18.4-53V51.3C240.8,48,200.9,43,151,43C106.3,43,59.9,48.7,39,51.6z"/> <path d="M151,26C87,26,22,37,22,37s0,145,0,203c0,96,117.6,145,117.6,145S279,336,279,240c0-104,0-203,0-203S226,26,151,26z M270,240c0,19.9-6.7,39.3-19.9,57.7c-10.9,15.1-26.2,29.7-45.5,43.1c-26.2,18.3-52.8,29.8-63.1,33.8l-1.6,0.6l-1.6-0.8 c-10.4-5-37.2-18.9-61.3-41.3c-30.5-28.4-46-59.7-46-93.2V44.7l3.4-0.5C53.5,41.4,103.1,35,151,35c53.2,0,95.3,5.6,115.6,8.9 l3.4,0.5V240z"/> </clipPath> </defs> </svg> <br/> Image: https://www.pexels.com/...d-tablet-864994/ Thanks in advance
I would consider two layers each one using a clip-path and I would control the opacity: body { background: #ccc; } .clip-svg { position: relative; display: inline-block; height: 400px; width: 300px; } .clip-svg::before, .clip-svg::after { content: ""; position: absolute; top: 0; right: 0; left: 0; bottom: 0; background-position: center center; background-size: auto 100%; background-image: var(--i); transition: 0.8s all ease; } .clip-svg::before { clip-path: url(#Emblem2); } .clip-svg::after { clip-path: url(#Emblem); } .clip-svg:hover::after { opacity:0; } <div class="clip-svg" style="--i: url(https://images.pexels.com/photos/864994/pexels-photo-864994.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260)"></div> <svg width="0" height="0"> <defs> <clipPath id="Emblem"> <path d="M279,240c0,96-139.4,145-139.4,145S22,336,22,240c0-58,0-203,0-203s65-11,129-11c75,0,128,11,128,11S279,136,279,240z"/> </clipPath> <clipPath id="Emblem2"> <path d="M39,51.6V240c0,72.4,80.9,116.6,101.2,126.5c11-4.5,35.7-15.4,59.8-32.3c18.5-13,33.2-26.8,43.6-41.3 c12.2-17,18.4-34.8,18.4-53V51.3C240.8,48,200.9,43,151,43C106.3,43,59.9,48.7,39,51.6z"/> <path d="M151,26C87,26,22,37,22,37s0,145,0,203c0,96,117.6,145,117.6,145S279,336,279,240c0-104,0-203,0-203S226,26,151,26z M270,240c0,19.9-6.7,39.3-19.9,57.7c-10.9,15.1-26.2,29.7-45.5,43.1c-26.2,18.3-52.8,29.8-63.1,33.8l-1.6,0.6l-1.6-0.8 c-10.4-5-37.2-18.9-61.3-41.3c-30.5-28.4-46-59.7-46-93.2V44.7l3.4-0.5C53.5,41.4,103.1,35,151,35c53.2,0,95.3,5.6,115.6,8.9 l3.4,0.5V240z"/> </clipPath> </defs> </svg>
I don't see a way to achieve what you want using clip paths on an HTML element. You can only replace one clip path with another in CSS. You can't interpolate between two of them. However it is fairly easy to do, if you are okay with moving the image into an SVG. Then you can do whatever you want with the inner border. Note however, with this solution, the inner border is not a clip path, so it doesn't make the image transparent. I don't know if that is important to you or not. It should be possible to do that if you really need it to. body { background: #ccc; } .clip-svg .emblem2-ref { transform-origin: 150px 200px; transform: scale(1.2, 1.2); transition: 0.4s all ease; } .clip-svg:hover .emblem2-ref { transform: scale(1, 1); } #Emblem2 { fill: #ccc; } <!-- Clip path and inner border definitions. Can be included once and used by multiple SVGs --> <svg width="0" height="0"> <defs> <clipPath id="Emblem"> <path d="M279,240c0,96-139.4,145-139.4,145S22,336,22,240c0-58,0-203,0-203s65-11,129-11c75,0,128,11,128,11S279,136,279,240z"/> </clipPath> <path id="Emblem2" d="M39,51.6V240c0,72.4,80.9,116.6,101.2,126.5c11-4.5,35.7-15.4,59.8-32.3c18.5-13,33.2-26.8,43.6-41.3 c12.2-17,18.4-34.8,18.4-53V51.3C240.8,48,200.9,43,151,43C106.3,43,59.9,48.7,39,51.6z M270,240c0,19.9-6.7,39.3-19.9,57.7c-10.9,15.1-26.2,29.7-45.5,43.1c-26.2,18.3-52.8,29.8-63.1,33.8l-1.6,0.6l-1.6-0.8 c-10.4-5-37.2-18.9-61.3-41.3c-30.5-28.4-46-59.7-46-93.2V44.7l3.4-0.5C53.5,41.4,103.1,35,151,35c53.2,0,95.3,5.6,115.6,8.9 l3.4,0.5V240z"/> </defs> </svg> <!-- Will need one of these SVGs for every image you want to display --> <svg width="300" height="400" class="clip-svg"> <g clip-path="url(#Emblem)"> <image width="300" height="400" preserveAspectRatio="xMidYMid slice" xlink:href="https://images.pexels.com/photos/864994/pexels-photo-864994.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260"/> <use class="emblem2-ref" xlink:href="#Emblem2"/> </g> </svg> <br/> Image: https://www.pexels.com/...d-tablet-864994/
Animating SVG rect x property via CSS
I have a classic mobile three-bars menu button made with SVG. I would like to animate each bar on click. This is my code: $('#menu_button').click( function() { $(this).toggleClass('open'); } ); #menu_button .rectangle { left: 0; x: 0; transition: all ease 1s; } #menu_button .rectangle.first { transform: rotate(0deg); top: 0; y: 0; } #menu_button .rectangle.second { transform: rotate(0deg); transform-origin: 8px 9px; top: 6px; y: 6; } #menu_button .rectangle.third { transform: rotate(0deg); transform-origin: 11px 9px; top: 12px; y: 12; } #menu_button.open .rectangle.first { top: 23.2px; y: 23.2px; } #menu_button.open .rectangle.second { transform: rotate(405deg); } #menu_button.open .rectangle.third { transform: rotate(495deg); left: 0; x: 0; top: 8px; y: 8; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <svg width="22" height="35" id="menu_button" class="hidden-sm hidden-md hidden-lg"> <rect style="opacity:1; fill:#eb671f; fill-opacity:1;stroke:none;" class="rectangle first" width="22" height="2" x="0" y="0" /> <rect style="opacity:1; fill:#eb671f; fill-opacity:1;stroke:none;" class="rectangle second" width="22" height="2" x="0" y="6" /> <rect style="opacity:1; fill:#eb671f; fill-opacity:1;stroke:none;" class="rectangle third" width="22" height="2" x="0" y="12" /> </svg> JSFiddle for those like me who can't run the snippet: https://jsfiddle.net/9rkoLcx8/2/ The issue is with Firefox. I mean, everything is working fine on Chrome and Opera, this doesn't work on Safari (it has no animation but it's still ok as it doesn't break things up), and works half in firefox: it rotates correctly but doesn't animate the x and y of SVG rects. This is what I think: x and y are rect attributes, not CSS properties, so not only they shouldn't work on Firefox, they shouldn't work on Chrome and Opera too. That's why I added top and left, but it still doesn't work. Is there a way to make the animation of x and y work in Firefox too?