Safari changing font weights when unrelated animations are running - animation

I'm using css animations on my page and Safari seems to change unrelated font weights elsewhere on the page when animations are running. Any idea why this happens? All other browsers work fine, include webkit ones like Chrome.
I've detailed the bug in a video here - http://www.screenr.com/gZN8
The site is also here - http://airport-r7.appspot.com/ but it might keep changing rapidly.
I'm using compass (#transition-property, #transition-duration) on the arrow icons. No transitions applied on the heading that's flashing. On a Mac - so it might be the hardware acceleration, but I'm still trying to figure it out.

When you trigger GPU compositing (eg, through CSS animation), the browser sends that element to the GPU, but also anything that would appear on top of that element if its top/left properties were changed. This includes any position:relative elements that appear after the animating one.
The solution is to give the animating element position:relative and a z-index that puts it above everything else. That way you get your animation but keep the (superior IMO) sub-pixel font rendering on unrelated elements.
Here's a demo of the problem and solution http://www.youtube.com/watch?v=9Woaz-cKPCE&hd=1
Update: Newer versions of Chrome retain sub-pixel antialiasing on GPU composited elements as long as the element has no transparency, eg has a background with no transparent or semi-transparent pixels. Note that things like border-radius introduce semi-transparent pixels.

Apparently, that's the price you pay for hardware acceleration: all text momentarily turns into images, which causes the drop in render quality.
However, applying html {-webkit-font-smoothing: antialiased} to turn off the sub-pixel anti-aliasing makes this problem go away. That's what I'm doing for now.
UPDATE: Since then, I've also come to learn that this happens only when the browser can't be sure if the section being animated is going to affect the text. This can usually be handled by having the text above (higher z-index than) the elements being animated, and/or making sure the text has a fully opaque background.

I've faced this issue numerous times and have had success adding the following css to the animated element:
z-index: 60000;
position: relative;
It seems it needs both z-index and position to be effective. In my case I was using it with Font Awesome animated spinners.

Related

Inconsistency on border radius on images across browsers and systems?

I've spotted some weird behavior across browsers border-radius implementation. Take this code: http://jsfiddle.net/pm7FZ/1/ On Windows every browser excerpt Chrome rounds inner image: http://imgur.com/54In8 Chrome doesn't and the image stays square.
I don't have OS X, but my friend send me this: https://img.skitch.com/20120925-eypjk593tdest3ud9hcji1sauf.png Seems it behaves differently. Although another friend says that if you set border-radius to 20px on OS X it will round the image corners on OS X's version of Firefox.
Question - what is happening here? Why so much inconsistency.
It's obviously easy to "fix", just curiosity.
I can only speculate but here's what I suspect is going on. If you check out the W3C spec for the basic box model (http://www.w3.org/TR/2007/WD-css3-box-20070809/) you'll see a graphic that demonstrates how elements are laid out. Each element has a content area, padding, border, and margin areas. I believe browsers render each of these areas as a layer and where FF would render the 'border layer' on top of the content layer Chrome would render the 'content layer' on top of all the other layers. In your sample if you would remove the height and width attributes from your img tag you'll see the image does get rounded but is not affected by the border itself. I haven't found any specification on the way browsers should handle this but I'm pretty sure the Chrome devs chose this method to squeeze out some more performance.

Border-radius on an image with a border is different on Firefox and Chrome

This is best explained with images.
Firefox, right:
Chrome, wrong:
jsfiddle.
That is a (fully green) image with 2px (red) border and a border-radius of 6px. In my design, the border is barely visible, so the image looks completely square in Chrome.
Is it possible to achieve the correct result in Chrome without extra markup nor javascript?
I don't believe you can do this with Chrome. Images will extend over the bounds of border-radius, and I think that's the intended behavior (or else they just didn't notice).
When using a div, for example, you can see that the background behaves as it should. You could consider using a div instead of img, and using your source image as the background (and forcing its width and height).
Plainly said: In Chrome, there does not seem to be a way to force your image to be hidden by the border of itself (or even of its container) unless it is set as a background. In fact, the issue has been asked about before, and blogged about as well (and, in fact, patrickzdb's comment there may help you).
Apparently it is a bug in chrome..
I normally apply box-shadow for chrome instead of border.
so, if you don't mind to apply css hack to workaround it without javascript: http://jsfiddle.net/3cuHU/

Pan/Zoom painfully slow in IE8 RaphaelJS

I have been working on getting this seat mapping chart for a while and have created a few iterations, and the problem I keep finding is when I get to IE8 the panning for this is way to slow and delayed.
What I have at this point to cut down on load time is created a png to replace my "strokes" since I assume ie8 wanted to re-render each time I dragged the map.
I also added controls hoping to force IE8 users this option, but still there is a delay in the pan, and if I can have users with IE8 (and ie7 if possible) still drag/pan without the controls and the respond time a little faster that would be great.
Here is my current JSFiddle
I am still a little green with JS so if you have any suggestions it would be much appreciated. (PS Chrome frame is awesome but is not a option for me)
Update
I have removed the original dragging function and replaced the code using jqueryui's draggable function. Martin had suggested to just drag the div, and not the Raphael elements. Doing so lets this thing fly in ie6-8 which is great, but then came my concern about scaling. What I was seeing before on zoom my paper element WxH would stay the same ratio, cutting off my drawing when it zoomed in. After digging through the Raphael documentation I came across paper.setSize. setSize was exactly what I needed to allow this project to move and groove in ie6-8 and pretty much conquer all browsers in its path.
So in short, using jqueryui's draggable and paper.setSize has cured my cross browser zoom n' pan blues.
From what can be seen in the Fiddle, you are triggering a new rendering of the image by calling .translate() inside of a mousemove event handler:
mapContainer.translate(currentMapPosX, currentMapPosY);
rsrGroupies.translate(currentMapPosX, currentMapPosY);
This approach is toxic for performance in all browsers, let alone IE8. When dealing with VML in IE8 you should consider that each and every DOM change inside the image will result in the image being rendered again. Doing that while panning will always be painfully slow.
I see that you are already using jQuery in your Fiddle. If you want to increase performance of your panning, you should consider doing the following:
Render the image in Raphaël exactly once for the current zoom level. Do not attempt to change transformations in your VML/SVG image at any point in time while panning.
With the mousemove implementation of panning you already have, move or scroll the HTML container that holds your VML/SVG image instead. Imagine a <div> with overflow: hidden and simply move the image inside relatively, or scroll to the appropriate position.
This will require some adjustment of your coordinate calculations, but it will improve your performance in all browsers.

Using CSS3 to animate opacity with display:none

I have an element, with a child container which is initially hidden. When I hover over the parent, the child should be displayed. Simple.
Now, for real browsers, I want to add some flair and have the child fade in — while still keeping basic functionality for non-CSS3 compliant browsers. For old browsers, I simply toggle display, while I animate the opacity for all the kids with cool browsers. Should be a simple operation, right?
To my great surprise and disappointment, this is kind of buggy.
In Firefox, when I hover on, the child element switches to being fully opaque, before fading out. But hey, I want it to start as fully transparent, and then fade in!
In Webkit, the animation does not trigger — only the display toggle.
In IE (including IE10 PP) it also simply toggles display (as expected, though I had hoped it would animate in IE10).
In Opera everything works swell. <3 <3
Now, if I remove the display:none; from the initial declaration, the animation works beautifully in Fx, but then I will have problems with uncool browsers, which is sadly predominant among the visitors of this particular project.
Since I possess the powers of Modernizr, I can simply make a conditional style so that I use the display toggle only on the silly browsers, and life is great again, but the question remains:
Is this a bug in Fx/Webkitz, or is it intentional?
Here's a fiddle for you to look at: http://jsfiddle.net/TheNix/q5bAZ/4/
The problem is that transitions happen on computed value changes, and browsers don't compute values for most properties when display: none is set.
There is some ... lively discussion about what the spec should say about this. See the thread starting http://lists.w3.org/Archives/Public/www-style/2011Dec/0353.html and going over the last 4 months or so.
Simply omit the display declaration and add
-moz-opacity: 0.5;
-khtml-opacity: 0.5;
filter: alpha(opacity=x); // x = 0 ... 100.
Now with targeting the IEs and other older browsers, you should be fine.
If you want to be extra-accurate you put the filter into an extra IE-stylesheet so you don't invalidate your stylesheet with stupid IE-stuff. ( But with proprietary prefixes only xD )

Modal backdrop with opacity causing google chrome to lag

We have a simple modal in our web application.
It's nothing special and is built on twitters bootstrap library.
It contains a backdrop that is a semi transparent white background with position: fixed and width and height set to 100%.
The modal itself, however, is not statically positioned but absolutely positioned, this is because the modal might be taller than the viewport and we don't want scrolling in the modal.
Here's the dilemma, when the backdrop is present the scrolling is far from smooth in Google Chrome, if I change the position of the backdrop to absolute everything is fine.
This has the obvious downside of not covering the entire page.
I tried to reproduce it with a JSFiddle but I couldn't (most likely due to the fact that we a lot more content on our site).
Nonetheless here is my attempt: http://jsfiddle.net/LdC4w/
So, any ideas?
Oh, and I can add that having a background image instead of opacity is not an option.

Resources