I have the following code:
http://jsfiddle.net/RFMxG/1/
When the transition runs, you can see a padding of about 20-30 pixels on the left hand side. Despite the fact I have set the transform-origin to be 0,0,0, it is still not correctly rotating about the y-axis. The left edge of the blue box should be flush against the left hand edge at all times during the animation.
Can anyone tell me what I've done incorrectly?
Okay, there are whole bunch of issues here:
1) CSS transforms aren't animatable using transitions. If you look at the W3C list of transitionable properties, you'll notice that transform isn't there.
2) -webkit-perspective only affects the children of the element it is applied to, not the element itself. Read the Safari blog on this:
The interesting thing about -webkit-perspective is that it does not
affect the element directly. Instead, it affects the appearance of the
3D transforms on the transformed descendants of that element; you can
think of it as adding a transform that gets multiplied into the
descendant transforms. This allows those descendants to all share the
same perspective as they move around.
3) It's awesome that you posted a fiddle, but since this is a CSS problem, for future reference it would have been a lot easier if you cleaned out all the javascript, and used one set of browser prefixes only. Help us help you!
4) What you probably want to use is an animation. Here's a highly modified version of your fiddle that works on hover:
http://jsfiddle.net/RFMxG/4/
5) If javascript is your skill set, and you're at all concerned about browser compatibility (which of course you are!), I highly recommend doing these kinds of animations with jstween.
Right, so the solution was actually due to the fact the transform origin needs to be set prior to the animation starting (it cannot be set at the same time the -webkit-transform property is set).
I've updated the fiddle to demonstrate this now works correctly.
http://jsfiddle.net/RFMxG/5/
Related
I have recently been animating a fixed position element using CSS by changing the left/right propertied of the element.
This works fine but causes some 'janky' animation when it comes to Firefox/Safari. I had a look at optimisations and the general thought it to use transforms as it performs much better and you can use the GPU of your computer which means the animation runs much smoother.
The problem I have now ran into is after reading this qusetion/answer it looks like you can't run transforms on fixed position elements.
Has anyone got any ideas on where best to go with this?
Happy to setup a codepen if it helps people.
Edit: As Cbroe pointed out, it's only on fixed position children of parent elements you're applying the transforms too.
The Goal: to create a fixed background position in a transformed element that works in Firefox.
I have tried all solutions on this page (and a handful of others), but none have worked:
Fixed attachment background image flicker/disappear in chrome when coupled with a css transform
Things I have tried using are static positions, backface visibility setting, z-index setting, other background-attachment stuff.
Demo:
https://jsfiddle.net/96u9xqbn/6/
.fixed1 {
transform: translateZ(0);
}
If you remove the transform above, it works. But, If you're using something like Skrollr, or have another need for the transform, then the background is not properly fixed in firefox.
Unfortunately this is not bug, but a change of scope.
There was a problem where browsers were inconsistent in their behaviour with background-attachment:fixed; inside transformed elements, which was causing additional inconsistencies with 3D transforms.
The spec for background-attachment was adjusted to include a rule that elements within transformed elements would have their background-attachment rules set to scroll.
Firefox and Edge have both conformed to the new spec, Chrome has so far not deployed the change on their side (at the time of posting this, their bugtracker shows 30 Nov as their end date)
Workaround:
The quickest and easiest way to work around this change of spec would be to use a parallax library to hit this for you. A fairly popular one is called Skrollr, and I've adjusted your fiddle to include it.
Essentially you can just add data-0 and data-10000 attributes to your element, and then initialise the library using skrollr.init();
This has the drawback of using a library for something that was previously achievable in clean CSS, but it does also carry positive weight in that a parallax background is much easier on the eyes than a fixed background.
so I've read a lot about the current state of rotating text and not being able to perfectly get real antialiasing to happen in all browsers. It looks like the first box in the pic in chrome, but the second, jaggedy box in firefox. I've tried the most popular fixes including -webkit-backface-visibility:hidden; -webkit-font-smoothing:antialiased; and maybe one other I can't remember.
However this is not asking the same question, but a new one I havent found anywhere. These two screenshots of the same box are both taken from Firefox. The jaggedy box on the bottom is what it looks like normally, however, when I mess with the rotation attributes with another(completely different) element on the page with the css edit console, it renders the box perfect / smoothly...
I do, however, have to continue to press up or down to change the rotation value on another element for the entire box to render antialiased perfectly, then it returns to its jaggedy normal self. I rotated the div that the content is in and put the css fixes on the same div(although I did try putting the css fixes on every element) and I didn't ever seem to get any smoothness or antialising like you see in the box above...only when I rotate another element on the page in the browser. WTF?!!?!? is there a way to do this in css or is it only something the browser is doing in realtime and cannot reproduce that smoothness in CSS yet?
EDIT: PIC for comments section
For whatever reason, it seems under some circumstances browsers "forget" to antialias text while doing complex transforms.
The fix:
Using CSS to force the browser to render the transformed element in a separately-composited "layer" is one solution:
transform: rotate(…) translate3d(0px,0px,1px);
The explanation:
Many rendering engine implementations create a GPU layer for the 3d-transformed element, and composite it onto the rest of the page when painting. This alternate rendering path can force a different text-rendering strategy, resulting in better antialiasing.
The caveat:
However, this is a bit of a hack: first, we're asking for a 3-dimensional transform we don't really want; second, forcing many unnecessary GPU layers can degrade performance, especially on mobile platforms with limited RAM.
dev.opera.com hosts a good discussion of compositing, hacks using transform3d, and the CSS3 will-change property.
Jeremy if you come back and answer this I can give the answer to you. just realized I hadn't had an answer to this so I needed to put something here.
This solution worked as in the comments above:
Jeremy:
I had another thought: it could be related to creating an opengl/webgl layer behind the scenes. If you add translate3d(0px,0px,1px) after the rotate transform, does it "fuzz out" a bit more?
Answer - Yes this works to perfectly anti-alias any text in all browsers!
I'm experiencing an issue on Internet Explorer 10 when using CSS transform property to change the 3D perspective.
Random artifacts appear on the edge of some elements contained in the element with the perspective applied.
I've created a simple fiddle to demonstrate the issue:
http://jsfiddle.net/b9ztC/
To reproduce, just open the fiddle and try to select, click or play around with the text, this results in the following artifacts appearing/disappearing around the paragraph element:
More lines and artifacts appear in more complex scenarios, and the cause seems to be the following line of css:
transform: perspective(800px);
The only ways to solve the issue seem to be:
not to have the perspective applied to the element
setting the transform perspective to 0px
use perspective: 800px, instead of transform: perspective(800px)
The last one seems an easy solution but it doesn't work well in some scenarios, the following 3D flipping card demo for example (which has the same artifacts problem on the back of the card using IE10) doesn't play well when applying the perspective property separately from the rotation transform: http://www.cssplay.co.uk/menu/css3-3d-card.html
Have anyone experienced this issue? Is there any way to prevent this from happening?
I'd also like to know if this happens on every machine or it can be an hardware-related issue.
I'm seeing more or less the same issue, though only on the left side of the div, it changes depending on the transform. It seems to be the background bleeding through at the edges of the line.
I'm on Windows 7 x64 with an Radeon HD 4670 (Catalyst 13.1), using IE 10.0.9200.16686 (KB2870699).
The only practical workaround I've found so far is to apply the padding on the inner element, ie on the p instead of on the div. However I'm not sure whether the padding is actually the trigger, so this might not be applicable in other situations.
I try to make a flip-page effect in IE10.
Because IE10 doesn't support transform-style: preserve-3d;
i have to flip each side seperately. It works well in recent browsers but there is no perspective in IE10.
If i write perspective: 1000px; in the container(.flipper), backface-visibility/z-index is not working correctly.
Have a look at tis jsfiddle:
http://jsfiddle.net/wG6gk/2/
I have no clue why you have xpersepective in your CSS, IE10 is unprefixed in CSS, however the perspective property must have some kind of unit for the depth, perspective: 1000 won't be applied because the browser doesn't know what unit it is in, similarly like width and height, etc, you have to apply px, em, etc. The only browsers that assume units (and in pixels) on the perspective property are Webkit browsers, and only when it is inside the transform property.
If you do a little research you, Microsoft states:
The W3C specification defines a keyword value of preserve-3d for this property, which indicates that flattening is not performed. At this time, Internet Explorer 10 does not support the preserve-3d keyword. You can work around this by manually applying the parent element's transform to each of the child elements in addition to the child element's normal transform.
So for now, you'll just have to implement the advised fix, if you want to go down that road.
If not, you're lucky. I spent time trying to make it transition smoothly over. Originally in your fiddle, you were transforming it very awkwardly and had too many styles, in my opinion, so the techniques in this JSfiddle should help: http://jsfiddle.net/NAy2r
Explained fiddle
So basically the front content exists in the container div, while the back content exists in the back div, which exists inside the container div. This is very similar to Apple's HTML5 Card flip demo, however there is a twist when it comes to backface-visibility.
At the time that Apple relased that demo, backface-visibiity didn't work on Chrome or Firefox. Chrome had some concept of perspective, but none of backface-visibility, so when you flipped an element, you'd still see through to the back and the content of the back would show through both sides as well; However on Safari, it'd be perfect because it initially understood these concepts.
In further updates of Chrome in the months afterwards, Chrome understood the property, however it was applied literally and the back was hidden completely, regardless if you flipped it or not! What would be the point of having this property if it was going to hide the back completely no matter what? You could just apply display:none, etc, to show the back if you wanted!!
And that is where IE stands as of today, it as well doesn't recognize the 'back' of the element (an element with transform:rotateY(180deg) is considered to be the backside) like other modern browsers do. So when the element is flipped, backface-visibilty: hidden is taken literally as it was in Chrome!
So this fiddle listens on an AnimationStart event on the container div, and on the animation start, it finds the duration of the animation and it uses that to calculate halfway though the animation, so when the animation is halfway, it changes backface-visibility to visible, that way the animation smoothly transitions like it's supposed to.
This was a pain to develop, IE10 is somewhat inconsistent, as it needs time to process it the first time (probably the jQuery). Notice the relief, lack of headache and fiery red eyes. The air around you has become cooler and you can finally breathe, because now you're not alone.
Edit: I forgot to add, that if your animation or transition has a different timing, the timing in this script will have to be adjusted, as it only works with linear transitions, as of now...