I have a fairly simple 3d transform which is essentially a bunch of flip cards which can be flipped front to back and vice versa. When they are flipped I want the animation to overlap the other cards. This works perfectly in Firefox however the animation occurs underneath the other cards in Webkit.
Fiddle is here: https://jsfiddle.net/ojdavey/kwf8vLLx/1/
If you click the "Flip" button in both Chrome/Safari and Firefox you'll see how it works differently.
I've tried a couple of things such as setting:
transform-style: flat
for the other cards while the card is flipping but that didn't seem to work.
Any help would be much appreciated!
A possible solution is to set the z-index on the parent container, when a card is flipped, like:
.box.flip.active {
z-index: 1;
}
Remove this class from all elements and add it to the current card before you flip it either way. This works in Safari as well as in Chrome.
Demo
Try before buy
The demo includes the updated JavaScript code too. This is not optimized. It's only to demonstrate the behavior:
$(".flip .flip-button").on("click", function() {
$('.col4').removeClass('active');
$(this).closest(".col4").addClass('active');
$(this).closest(".card").addClass("flipped");
});
$(".flip .close").on("click", function() {
$('.col4').removeClass('active');
$(this).closest(".col4").addClass('active');
$(this).closest(".card").removeClass("flipped");
});
Related
We are running into a weird bug with disappearing elements in the new Firefox (version 34.0.5).
The bug occurs on a page with two (or more) flash objects that are before an other element in the html. Whenever the page is loaded, the element just disappears.
You can see it in this demo:
FF 34 Flash Bug
Just open it in the newest Firefox and you will see the red div disappearing. Every repaint of that page will display it again, e.g switching the browser tab or editing the css via dev tools.
When it does work normally
- One flash file - no matter the position
- Having all flash files after the element in the html
- Having one flash file below and one flash file above the other element (html structure)
What we tried - what it produces
- Repainting the page after flash files are loaded (we are using SWFObject for adding the flash files, but we are not able to attach a load event to the files) - works on the first load of the page (cache clear), doesn't work after refreshes (F5).
- After the page is loaded, scrolling, resizing, changing tabs helps - element is then visible (in some cases)
- Creating an element with width/height with js at the end of the document - helps on first load, after refreshes it doesn't work.
- Animating with css the opacity of the object infinite (we have a wrapper around the flash files and animate this one) - works (not a permanent solution)
- Swf object with a "wmode" other than "transparent" works (not an acceptable solution for us)
What we know
- Bug happens only when MORE THAN ONE FLASH FILE is beneath the element
- Bug happens on flash versions 15 and 16 (these are tested)
- Bug happens in mozilla 34.0.5 (this one is tested)
- Multiple elements after the flash files will also disappear
- When you open the page for the first time, it doesn't show the element. If you then refresh (F5) multiple times, in some cases it will show everything normally, and in some cases it doesn't show the element nor one or both flash files that are overlapping.
Current solution
A constant browser repaint of the disappearing element (or elements!). We do this with a simple CSS3 animation that animates the opacity infinitely between 0.97 and 1 with the duration of 1s.
JavaScript:
if( navigator.userAgent.match(/Firefox\/3[4-9]/i) ){
$('.animation').addClass('firefox34FlashBug');
}
CSS:
.firefox34FlashBug {
animation: 1s linear 0s firefoxFix infinite;
}
#keyframes firefoxFix {
0% {
opacity: 0.97;
}
100% {
opacity: 1;
}
}
That is a very hacky and not a nice solution, but the only "fix" we could find that doesn't change the structure of the html (we need multiple flash files below other elements in our project).
Did anyone else ran into the same problem? We know a couple ways to deal with that behaviour, but we can't explain it yet.
Thank you very much in advance! I hope that we can find a good way of dealing with this problem and that we can find an explanation for the new ninja elements in FF 34 ;-).
Update #1:
Applying border: 1px solid transparent; to a container around every object is fixing it in the demo (also see comments in the answer from akmozo).
This worked for me:
Added to CSS:
.firefox34FlashBug {
animation: 1s linear 0s firefoxFix infinite;
}
#keyframes firefoxFix {
0% {
opacity: 0.97;
}
100% {
opacity: 1;
}
}
Added class="firefox34FlashBug" to my container div outside flash
Note: The demo URL "FF 34 Flash Bug" isn't working, you need to add "index.html" to it. IE http://quickbm.com/ff34flashbug/index.html
Thanks for the fix.
I think that the problem is because your swf objects have absolute positions.
So to avoid this problem, you can put your swf objects into a container and you can use z-index to select it's depth
compared the other elements :
CSS :
.ninja-element {
z-index: 2;
position: absolute;
...
}
.objects {
z-index: 1;
position: absolute;
...
}
HTML :
<div class="objects">
<object>
...
</object>
<object>
...
</object>
...
</div>
<div class="ninja-element">
Watch me disappear in FF 34!
</div>
I had the same problem, but for me it worked to force the browser to repaint just once. After all the SWF Objects are added, I added this line (everything inside of $(document).ready(function() ):
$('#wrapper').css("transform", "scale(1)");
Where #wrapper is a div around the disappearing elements. Scale(1) forces a repaint, but should not change anything about the design (unless you use scale for that element already).
edit:
or maybe better: $('#wrapper').css("-moz-transform", "translatez(0)");, because this will also force a repaint, but only in Firefox.
Just throwing this in there for anyone else.
FF craps the bed when you have a position: fixed element inside a parent element that has been shifted around with left (or something).
To fix this. Shift your parent element around with translate instead.
Spent hours trying to get one of these hacks to work before figuring this out... :(
I'm running into a weird problem that makes a div invisible.
My goal is to create a shadow for a 3D object, in perspective.
Because a shadow is blurry, I am using -webkit-filter: blur(8px);, but when I try to add perspective with -webkit-transform: rotateX(45deg);, and the amount of degrees is more than 45, the div just disappears.
My Chrome version is 27.0.1453.47 Beta
Check out this fiddle to reproduce the problem for yourself. (Chrome only.)
I hope you guys know more about this problem:).
On my I have a fixed DIV at the top, 3 fixed tabs and a fixed div at the bottom (this will only be shown when logged in - in the future).
I am getting poor scrolling performance on Chrome only - FF & IE are fine.
I have ready some problem reports about Chrome, Fixed Positioning and Scrolling and wanted to see if anyone had any suggestions? I really would like to fix these elements in their locations but I would also like good scrolling performance in Chrome.
Any Ideas on a fix?
Note: its much more noticeable when zoomed on chrome...
Update: I have read other people have a similar issues and updated this Chrome issue, which was later merged into 136555, allegedly fixed since Chrome 26.
Problem and How to Monitor It
The reason for this is because Chrome for some reasons decides it needs to redecode and resize any images when a fixed panel goes over it. You can see this particularly well with
► Right-Click ➔ Inspect ➔ Timeline ➔ Hit ⏺ Record
► Go back to the page and drag scrollbar up and down (Mouse-wheel scrolling not as effective)
Edit (9/1/2016): Since posting this, Chrome added new features to help monitor this:
► Right-Click ➔ Inspect ➔ Rendering (Bottom tabs)
➔ ☑ Scrolling Performance Issues
➔ ☑ Paint Flashing
➔ ☑ FPS Meter (less important, but can be useful)
This will help you identify exactly what elements require repaints on scrolls and highlight them clearly on screen.
This seems to just be a problem with the method Chrome is using to determine if a lower element needs to be repainted.
To make matters worse, you can't even get around the issue by creating a div above a scrollable div to avoid using the position:fixed attribute. This will actually cause the same effect. Pretty much Chrome says if anything on the page has to be drawn over an image (even in an iframe, div or whatever it might be), repaint that image. So despite what div/frame you are scrolling it, the problem persists.
.
The Easy Hack Solution
But I did find one hack to get around this issue that seems to have few downside.
By adding the following to the fixed elements
/* Edit (9/1/2016): Seems translate3d works better than translatez(0) on some devices */
-webkit-transform: translate3d(0, 0, 0);
Some browsers might require this to prevent flickering
-webkit-backface-visibility: hidden;
-webkit-perspective: 1000;
This puts the fixed element in its own compositing layer and forces the browser to utilize GPU acceleration.
EDIT: One potential issue was pointed out to me by albb; when using
transform, all descendant position:fixed
elements will be fixed to that composition layer rather than the
entire page.
.
Alternative Solution
Alternatively, you could simply hide the top navigation while scrolling and bring it back in afterwards. Here is an example that could work on the stackoverflow.com's header or a site like theverge.com if pasted in DevTools > Console (or manually type "javascript:" into this pages URL bar and paste in the code below after it and hit enter):
/* Inject some CSS to fix the header to the top and hide it
* when adding a 'header.hidden' class name. */
var css= document.createElement("style");
css.type = 'text/css';
css.innerHTML = 'header { transition: top .20s !important; }';
css.innerHTML += 'header.hideOnScroll { top: -55px !important; }';
css.innerHTML += 'header { top: 0 !important; position: fixed !important; }';
document.head.appendChild(css);
var header = document.querySelector("header");
var reinsertId = null; /* will be null if header is not hidden */
window.onscroll = function() {
if(!reinsertId) {
/* Hides header on scroll */
header.classList.add("hideOnScroll");
setTimeout(function() { header.style.visibility = "hidden"; }, 250);
} else {
/* Resets the re-insert timeout function */
clearTimeout(reinsertId);
}
/* Re-insert timeout function */
reinsertId = setTimeout(function(){
header.classList.remove("hideOnScroll");
header.style.visibility = "visible";
reinsertId = null;
}, 1500);
};
The first solution of #Corylulu works, but not completely (still a little stutter, but much less).
I also had to add -webkit-backface-visibility: hidden; to the fixed element to be stutter free.
So for me the following worked like a charm to prevent scroll down stutter in chrome when using fixed elements on the page:
-webkit-transform: translateZ(0);
-webkit-backface-visibility: hidden;
Edit: Webkit-transform and webkit-backface-visibility both cause blurry fonts and images. So make sure you only apply both on the hover state.
Add this rule to your fixed element,
will-change: transform;
Read about solution from Here,
and read about will-change property from Here.
There's a recent bug report on this particularly annoying issue:
http://code.google.com/p/chromium/issues/detail?id=155313
It has to do with the combination of floating elements and large images. Still a problem on Chrome Canary 24.0.1310.0.
There are a number of ways you could speed up this front end, try out the PageSpeed Insights Chrome plugin for some ideas. Personally I'd recommend rebuilding this front end with the same design on top of a framework like Twitter's Bootstrap, but if you'd like some specifics on this front end:
As you say, the positioning of your header bar is causing the most time in terms of CSS rendering (CSS stress test results). Get rid of that big image that's in there and replace it with a 1px wide background image. You're also resizing images like your logo (and every other image in this header) unnecessarily, replace with actual-size versions
You could save a lot of bytes transferred by optimizing all your content images
I have some nav elements positioned with transform: rotate() and box-shadow. When you hover them they 'pop out' a little bit to indicate you can click on them. In Chrome and Safari (indicating this is a webkit issue) when you hover some of the nav items the box shadows go haywire and cover up portions of other random elements. It works fine in Firefox.
I made a jsfiddle portraying the issue as simply as I could figure out how to:
http://jsfiddle.net/Q39eJ/1/
Hover over and then out of the first one or 2 elements and you'll see the issue in action.
The site I'm working on has the issue here:
http://temp.go-for-english.com/
(URL will soon change to http://www.go-for-english.com if this one doesn't work)
If anyone can figure out a work-around that still utilizes CSS3 to make it look normal (Maybe set the z-index again on the hovers, or some other weird workaround that I'm not sure about) I'd greatly appreciate it :) I'd really rather not resort to images :(
UPDATE:
I've been informed it looks fine on Windows Chrome =\ I'm using Mac OSX 10.6, here's a screenshot of the behavior I see:
http://s9.photobucket.com/albums/a74/nZifnab/?action=view¤t=Screenshot2012-01-19at13205PM.png
My client has also pointed out the issue because they use Safari.
I figured out a bit of a work-around that mostly works. Found this stackoverflow question: How can I force WebKit to redraw/repaint to propagate style changes? related to forcing a repaint of elements using javascript. So I updated my fiddle with this code to force a repaint of the elements with box shadows:
$(function() {
$('.top-nav a').hover(function() {
redrawMe($('.top-nav a'));
})
});
function redrawMe(obj) {
obj.hide();
obj.each(function() {
this.offsetHeight;
});
obj.show();
}
I tried only redrawing the element that was being hovered redrawMe($(this)); but it didn't work, when any of them gets hovered, I need to redraw all of them. Appears to mostly do the trick but there's still some darker shadows that appear in the cracks between each element. I feel that this is acceptable and barely noticeable. jsfiddle with my proof of concept:
http://jsfiddle.net/nzifnab/Q39eJ/4/
Haven't updated that live site with it yet, but shall soon.
If anyone can manage to find a way to make even the shadows between each element disappear I'll accept your answer instead :)
Again, this may only be happening on MacOS X in both chrome, and safari.
http://jsfiddle.net/danielcgold/SYgzJ/
When you click on the input then go on blur, artifacts are left on the screen in Chrome 15. I first noticed this issue on a site i've been developing so I eliminated everything but just the input field and a button. When I remove the button, the transition happens just fine. Any ideas?
Add this CSS to your input field:
input {
-webkit-transform: translate3d(0,0,0)
}
This will force Chrome to use your GPU to do all the rendering which will solve the artifacts problem and make your animations smother.
This is a bug in Chrome's rendering of CSS transitions. But you can workaround it by forcing element "refresh" operation. Please note that you need to refresh not the input element, but it's parent, so the following code will help you:
$(document).ready(function(){
$('#test').blur(function(){
$(this).parent().addClass('repaint');
});
$('#test').focus(function(){
$(this).parent().removeClass('repaint');
});
});
And repaint class should have something related to parent's view, for example different color:
.repaint {
color: red;
}
But you may replace color with visibility or other view-related (but not important/visible for parent) attribute.
Here is jsfiddle to demonstrate the workaround
I had a similar problem with box shadow artifacts in Safari, and found adding -webkit-transform:scale(1); to the focus rule fixed the problem.
See http://jsfiddle.net/SYgzJ/48/ – it should work fine now.
As Cesar said, -webkit-transform: translate3d(0,0,0); will fix it, but it can affect text rendering too.