Bug in CSS3 rotateY transition on Safari? - css

I am showing a modal popup using CSS3 transitions (largely borrowed from Effeckt.css). It works well in all modern browsers except Safari. In Safari, the movement is OK, but the background-color snaps in unevenly.
This is the code, the problem is visible in Safari on OSX: http://jsfiddle.net/eJsZx/4/
A screenshot of the problem before it resolves itself. You can see that half the div is correctly colored white, half is still transparent.
This is the relevant part of the CSS (.effeckt-show and .md-effect-8 are applied when the button is clicked, to show the modal):
.effeckt-modal {
visibility: hidden;
-webkit-backface-visibility: hidden;
-ms-backface-visibility: hidden;
-o-backface-visibility: hidden;
backface-visibility: hidden;
background: white;
}
.md-effect-8 {
-webkit-perspective: 1300px;
-ms-perspective: 1300px;
-o-perspective: 1300px;
perspective: 1300px;
-webkit-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.md-effect-8 .effeckt-modal {
-webkit-transform: rotateY(-70deg);
-ms-transform: rotateY(-70deg);
-o-transform: rotateY(-70deg);
transform: rotateY(-70deg);
-webkit-transition: all 500ms;
-o-transition: all 500ms;
transition: all 500ms;
opacity: 0;
}
.effeckt-show.md-effect-8 .effeckt-modal {
-webkit-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
transform: rotateY(0deg);
opacity: 1;
}

As far as I can tell it's a bug, yes, Safari is rendering intersection where it shouldn't.
For some time I thought Safari is doing it right by always rendering intersection of elements, but as far as I understand the specs, only elements in the same 3d rendering context should intersect, and that would be children of elements with a transform-style of preserve-3d.
So far the only workaround I found (only tested on Windows yet where Safari shows the same behaviour) is to translate the underlying elements away on the z-axis. Without perspective being applied it won't actually translate, but Safari/Webkit seems to think it does (which probably is because it mistakenly treats the element as if it were in the same 3d rendering context as the actually transformed dialog) and so the elements do no longer intersect.
.effeckt-overlay {
position: fixed;
width: 100%;
height: 100%;
visibility: hidden;
top: 0;
left: 0;
opacity: 0;
-webkit-transition: 500ms;
-o-transition: 500ms;
transition: 500ms;
z-index: 1000;
background: rgba(0, 0, 0, 0.5);
-webkit-transform: translateZ(-1000px);
}
http://jsfiddle.net/eJsZx/5/

I found this issue when trying to find a solution to a problem I was experiencing in Safari (Mac and iOS), where a y-rotated svg only displayed its right half for no apparent reason.
In my case, the svg was a child of a fixed-position div, and I found that both position: fixed and position: absolute on the parent caused half the svg to disappear.
Neither changing z indexes, perspective, nor translate-z seemed to solve the issue. But randomly, adding a new div around my svg and setting its background-color solved the problem. I hope this helps the next person :)

In my case, adding z-index: 0 to the parent element fixed it as per Thomas's suggestion.

None of the solutions above worked for me. In the end, this is a bug with rotate on Safari that Chrome previously had but fixed. The answer here was what solved it for me - using scale() rather than rotate().

In my case, it worked to put transform: translateZ(0); on the parent container. The object itself is an image.

Related

How to fix blurry background-image on transform scale

In my application users can scale down a specific part. I'm using tranform: scale() to achieve this.
I was able to achieve much less blurred images by using
-webkit-backface-visibility: hidden;
-ms-transform: translateZ(0);
-webkit-transform: translateZ(0);
transform: translateZ(0);
on my images.
Sadly this doesn't work for divs with background-image. Those images are still very blury.
Is there a way to fix this? (Please don't tell me to not use scale)
using transforms can cause blurry images when the transition happens or when it rescales, there's a workaround for this...the reason the blur looks like Webkit renders elements as images during animated transforms, so if scaling up an element it appears to blur until the transition has finished.
A solution might be to size the element as big as you will ever need it in the first place, and use a transformation to scale it down for initial display - e.g. if doubling the size on hover, instead of doing "scale(2,2)", start with "size:200%, scale:(.5,.5)" and on hover switch to "scale(1,1)"...
Here's a workaround:
.normal {
width: 200px;
height: 200px;
margin: 1em auto;
transition: all 1s linear;
}
.normal:hover {
transform: scale(2, 2);
}
.prescaled {
width: 400px;
height: 400px;
margin: 1em auto;
transition: all 1s linear;
transform: scale(.5, .5);
// fix positioning due to scale
position: relative;
top: -100px;
}
.prescaled:hover {
transform: scale(1, 1);
}
This one's mainly an idea about how you can implement it in your way...Let me know if it works...

Can't use scrollbar with particles.js set at fixed position

We have particles.js loaded and cannot use the scrollbar on wordpress website. We need this to work with full height and full width. Please see html code below in link.
Our html code" : website link: http://www.tcnarch.co.za/about
We have tried disabling plugins and checked dev tools for errors and there are none. Have also tried overflow-x: auto and also removed the height: 100% atribute from css but to no avail. Please help we have tried everything to our knowledge. Thank you
#particles-js {
position:fixed;
overflow-y:scroll;
overflow-x:hidden;
top: 0;
left: 0;
right: 0;
width: 100%;
}
#particles-js canvas {
display: block;
vertical-align: bottom;
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
opacity: 1;
-webkit-transition: opacity .8s ease, -webkit-transform 1.4s ease;
transition: opacity .8s ease, transform 1.4s ease
}
Problem has been resolved. Fixed this by adding right: 10px suppose it's not the ideal solution but the scrollbar now works also what might help others in future is setting pointer events to all.

Image shifting/jumping after CSS transition effect with scale transform in Firefox

I have a problem in latest Firefox browser version 34 (system: Windows 7, screen width: 1600px). I made effect with zooming images (in some container) after hover on it. I am using transform: scale(1.1) with transition: transform 0.3s ease-in-out. But when I hover on image, and after image zoom in.. it make some strange 1px-shifting. Some rendering browser bug, but I hope that existing some fix for it.
Most important CSS definition and part of HTML code:
figure {
display: block;
overflow: hidden;
position: relative;
backface-visibility: hidden;
}
figure img {
width: 100%;
transform: scale(1);
transition: transform 0.3s ease-in-out;
}
figure:hover img {
transform: scale(1.1);
}
<figure>
<img class="img-responsive" src="http://lorempixel.com/600/400/fashion/7">
</figure>
Sample with bug is online here: http://templates.silversite.pl/test/jumpingimg/
I saw also that somebody can fix it, but I do not know how, e.g. box "Our recent work" on http://demo.qodeinteractive.com/bridge/
I had a similar problem on my project. All images were position: absolute; and the transform look like that:
figure img{
transform: translate( -50%, 50%) scale(1);
position: absolute;
top: 50%;
left: 50%;
}
figure img:hover{
transform: translate( -50%, 50%) scale(1.1);
}
I replace every scale with scale3d and that solved my problem.
The final styles look like that:
figure img{
transform: translate( -50%, 50%) scale3d(1, 1, 1);
position: absolute;
top: 50%;
left: 50%;
}
figure img:hover{
transform: translate( -50%, 50%) scale3d(1.1, 1.1, 1);
}
Hope that's will fix your problem
On the link that you provided, http://demo.qodeinteractive.com/bridge/ , if you actually go here: http://demo.qodeinteractive.com/bridge/portfolio/gallery-style-condensed/two-columns-grid/ , you can see that, once looking at dev tools, that they apply a margin of "1px" on left/right side
.projects_holder.hover_text.no_space article .image img {
margin: 0 1px;
}
If you disable that style, you'll see the image move as you're describing when hovering on the image.
Therefore, your CSS for the image should be:
figure img {
width: 100%;
transform: scale(1);
transition: transform 0.3s ease-in-out;
display: block; /* (or inline-block) */
margin: 0 1px;
}
I have just run into this same problem now. The solutions here didn't fix the issue, so I'm posting what I did to get this to work.
Like OP I had a container with oveflow hidden and was the same size as the image inside it. The image would scale on hover to create a 'zoom' effect - but when initially starting and ending the transition, the image was "jumping"/growing a tiny bit on the bottom and right-hand side. This made it jumpy and not smooth.
I had calculated the dimensions of my components based off of percentages, which caused them to be non-integers (Chrome). I have a feeling Scale & Scale3d round the pixel values when scaling, which caused this jump. I gave a parent container display:table, which caused all children to have their width/heights be rounded to be an integer value. This fixed the issue for me, and the images now scale smoothly!
7,5 years later it's still an issue and the now solution is will-change css property. Only IE won't get this, but others seems to be doing fine - no more px jumping (edit: on non retina screens).
figure {
display: block;
overflow: hidden;
position: relative;
backface-visibility: hidden;
}
figure img {
width: 100%;
transform: scale(1);
transition: transform 0.3s ease-in-out;
}
figure:hover img {
transform: scale(1.1);
will-change: transform;
}
I just run over the same issue and for me it looks like that the browser corrects the decimal pixel after the scaling is done. Or some how the height and the width doesn't get scaled equals and that gets corrected in the end.
So I think the solution is to use an image with a 1 x 1 ration factor.
So for me the code of the question works fine when I use a the lorempixel with a width and height of 400px.
Let me know if that solves the issue?!
figure {
display: block;
overflow: hidden;
position: relative;
backface-visibility: hidden;
}
figure img {
width: 100%;
transform: scale(1);
transition: transform 0.3s ease-in-out;
}
figure:hover img {
transform: scale(1.1);
}
<figure>
<img class="img-responsive" src="http://lorempixel.com/400/400/fashion/7">
</figure>

Hover state not working after multiple animations

I'm a little stumped here.
This hover state transform worked when I had one animation, now that I've added a second it stops working?
.right-bird {
height: 58px;
position: relative;
top: -26px;
left: -80px;
opacity: .8;
-webkit-animation: bird-from-right 1.9s linear, jiggy 4s ease 2.5s forwards;
z-index: 50;
max-width: 100%;
&:hover {
-ms-transform: rotate(10deg);
-webkit-transform: rotate(10deg);
transform: rotate(10deg);
}
}
Any thoughts/suggestions?
IMHO your animation does works.
But: You're using rotate in the jiggy animation and in the hover state. In this case, the :hover rotate could --on hover-- replace the animation.
Btw, for exemplifying with Sass and CSS animations (cross-browser) you should put your code in a CodePen and not in a jsfiddle. At Codepen you've got a Sass compiler and autoprefixer included, otherwise debugging your code gets more complicated.

Cross Browser perspective solution?

What the problem is
I have tested this scenario of perspective usage ( a w3C validated webpage with all necessary and optional CSS browser tags) in IE, Firefox, Chrome, and Opera and found different (all inaccurate) results. So far it appears that the web browsers have all implemented perspective with slightly different displays. This question is here to see if maybe I'm missing something and there is a cross browser solution available.
If no one has a solution, well then, we have an interesting situation. Before now, I've never seen a feature in CSS that acts noticeably and irreparably inaccurate between all browsers.
I hope I'm wrong, because if not, I have to create and maintain three separate style sheets via php or javascript browser checking, a method that is very clearly out of date and frowned upon in today's web design. We prefer to use Modernizr to check features rather than browsers now, but this situation would prove that solution inviable.
Example Situation:
In Chrome, I positioned an iPhone interface simulating the use of a particular home automation app on the phone to control the channel of the tv in the background (an actual video), where the tv and iphone are made to look like they are part of the image with perspective and transform.
However, when looking at this from Firefox, the elements are completely out of place, as you can see below.
Question:
Is there any cross browser solution that will allow me to produce this result without using separate style sheets for different browsers?
Live JS Fiddle:
http://jsfiddle.net/qZSYy/1/
Purpose:
I'm developing a website for a technology company, and one of the main services provided is home automation. With a remote, or an iPhone or iPad, you can control a home's lighting, music, tv, etc. Very cool. So, I've decided to develop a section of the home automation page that simulates this.
On Chrome, it looks like this right now:
On Firefox:
Notes:
The iphone screen is actually a separate element, that turns on when hovered over and remains lit up for 10 seconds. I'm designing an interface on the iphone that will control the room's different lights, the speakers, and the tv, which is actually a separate div also that can be controlled by the iPhone as well to change channels.
The background is an image that I've render through Blender and can render different versions for the lighting changes.
CSS:
.home-auto-interactive {
width: 1250px;
height: 700px;
background-color: gray;
background-image: url('http://www.testing.agcomputers.net/style/images/Room_1.jpg');
-webkit-background-size: 100% 100%;
-moz-background-size: 100% 100%;
background-size: 100% 100%;
overflow: hidden;
-webkit-perspective: 80;
margin-left: auto;
margin-right: auto;
}
.home-auto-wrap {
width: 100%;
background-color: #252525;
}
.tv-screen {
width: 8.12%;
height: 7.8%;
position: absolute;
-webkit-transition: -webkit-transform .5s;
-moz-transition: -moz-transform .5s;
-o-transition: -o-transform .5s;
-ms-transition: -ms-transform .5s;
transition: transform .5s;
-webkit-transform: rotateY(-2deg) rotateX(0deg) rotateZ(0deg) translateX(626.7%) translateY(490%);
-moz-transform: rotateY(-2deg) rotateX(0deg) rotateZ(0deg) translateX(626.7%) translateY(490%);
-o-transform: rotateY(-2deg) rotateX(0deg) rotateZ(0deg) translateX(626.7%) translateY(490%);
-ms-transform: rotateY(-2deg) rotateX(0deg) rotateZ(0deg) translateX(626.7%) translateY(490%);
transform: rotateY(-2deg) rotateX(0deg) rotateZ(0deg) translateX(626.7%) translateY(490%);
}
.iphone-screen {
width: 22.7%;
background-color: black;
background-image: url('http://www.testing.agcomputers.net/style/images/iphone_screen_test.jpg');
-webkit-background-size: 100% 100%;
-moz-background-size: 100% 100%;
background-size: 100% 100%;
height: 50.8%;
bottom: 12.7%;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
opacity: 0;
position: absolute;
-webkit-transition-delay: 10s !important;
-moz-transition-delay: 10s !important;
-o-transition-delay: 10s !important;
-ms-transition-delay: 10s !important;
transition-delay: 10s !important;
-webkit-transition: opacity 0.5s;
-moz-transition: opacity 0.5s;
-o-transition: opacity 0.5s;
-ms-transition: opacity 0.5s;
transition: opacity 0.5s;
-webkit-transform: rotateY(-0.75deg) rotateX(1deg) rotateZ(-3deg) translateX(18.5%) translateY(0%);
-moz-transform: rotateY(-0.75deg) rotateX(1deg) rotateZ(-3deg) translateX(18.5%) translateY(0%);
-o-transform: rotateY(-0.75deg) rotateX(1deg) rotateZ(-3deg) translateX(18.5%) translateY(0%);
-ms-transform: rotateY(-0.75deg) rotateX(1deg) rotateZ(-3deg) translateX(18.5%) translateY(0%);
transform: rotateY(-0.75deg) rotateX(1deg) rotateZ(-3deg) translateX(18.5%) translateY(0%);
}
.iphone-screen:hover {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
filter: alpha(opacity=100);
opacity: 1;
-webkit-transition-delay: 0s !important;
-moz-transition-delay: 0s !important;
-o-transition-delay: 0s !important;
-ms-transition-delay: 0s !important;
transition-delay: 0s !important;
}
HTML:
<div class="home-auto-wrap">
<div class="home-auto-interactive"><!-- begin home auto interactive :: this has the purpose of displaying an interactive home automation area -->
<div class="tv-screen"><!-- begin tv screen -->
<iframe width="100%" height="100%" src="http://www.youtube.com/embed/9NFUgVa68hw?autoplay=1&rel=0&controls=0&showinfo=0&disablekb=1&iv_load_policy=3&modestbranding=1" frameborder="0" allowfullscreen></iframe>
</div><!-- end tv screen -->
<div class="iphone-screen"><!-- begin iphone screen -->
</div><!-- end iphone screen -->
</div><!-- end home auto interactive -->
</div>
You are missing the transform-style: preserve-3d; on the parent element. Also place the perspective property here, more on that later:
.home-auto-wrap {
width: 100%;
background-color: #252525;
transform-style: preserve-3d;
perspective: 80px;
}
This is part of the problem as Firefox requires it, Chrome does not - this explains why it works there. The next issue with Firefox is that overflow: hidden set on .home-auto-interactive causes all descendant elements to be flattened according to the spec: W3C Transform-style.
A workaround for this is to place the divs .tv-screen and .iphone-screen after .home-auto-interactive and position them atop. Now the 2 divs you are transforming will not be impeded.
Also opacity other than 1 will cause any descendant elements to flatten in 3D transforms, so be careful to keep that property for a div in the body with no transforming children (use z-index to position elements behind or in front of said div), or on the last node of a transforming element itself.
The background image property is not animatable, so you need to use an image tag to pull this off.
The issues you cite with TV could be due to:
The iframe, try applying the class to the iframe, though it should work as is.
The extra 0 transforms, get rid of these regardless.
The whole overflow thing, check the link above if you haven't done so.
Also, the filter property set other than none can lead to the same issue as the overflow and opacity, once again as per spec. It is not needed since IE 9, so unless you have some fallback reasons for doing so, removal is a good thing to consider. The opacity property has the same or better support than the 3D transforms:
Can I use opacity, check the 3d transforms too, I can't post more links yet. While you are at that page, check out the HTML5 video tag, it also has browser support as good as the 3d tranforms.
It looks like you need another prefix. Anywhere you call -webkit-perspective, you also need to call -moz-perspective. And the perspective needs a value: ems, px, etc..
https://developer.mozilla.org/en-US/docs/Web/CSS/perspective
http://css-tricks.com/almanac/properties/p/perspective/
This gave the elements perspective, but when you use position:absolute;, you need to also give a parent a defined position like position:relative;.
http://jsfiddle.net/NyXSa/7/
.home-auto-interactive {
width: 1250px;
height: 700px;
background-color: gray;
background-image: url('http://www.testing.agcomputers.net/style/images/Room_1.jpg');
-webkit-background-size: 100% 100%;
-moz-background-size: 100% 100%;
background-size: 100% 100%;
overflow: hidden;
-webkit-perspective: 80px;
-moz-perspective: 80px;
perspective: 80px;
margin-left: auto;
margin-right: auto;
position:relative;
}

Resources