How "transition-timing-function:cubic-bezier();" property works - css

Can someone please explain how exactly "transition-timing-function:cubic-bezier();" works please?
Here is my code
.sample_box{
background-color: orange;
height: 70px;
width: 35%;
transition: width 2s;
transition-timing-function: cubic-bezier(0.1,0.1,0.8,3.0);
}
.sample_box:hover{
width: 100%;
}
I've tried to break up the 2 seconds into 4 parts as "cubic-bezier" value but my box went insane, it goes completely out of the screen when hover in both directions

You need a bit of math background to really understand in depth about the cubic-bezier function as this function defines the control points of a cubic-bezier curve. I am not a math expert and so can only clarify the CSS portion of it. If you really need details on how a cubic bezier curve is drawn then wait to see if you get a better answer here (or) try asking on one of the math SE sites whichever is better suited to the question.
A cubic-bezier curve is a curve that is drawn based on four points P0, P1, P2 and P3. Here the points P0 and P3 are the start and end points of the curve whereas P1 and P2 are the control points that go towards defining the curvature of curve.
The four input values that are supplied to the cubic-bezier timing function specify the coordinates of the control points P1 and P2 of the cubic bezier curve (for the curve used by CSS, the points P0 and P3 are always (0,0) and (1,1) respectively). Based on the curve that is drawn (using the input values), the UAs will determine the amount of progress the transition or the animation must have made at any given point in time.
As specified in the W3C Specs, the values for x (parameters 1 and 3) should always be between 0 -1 whereas the values for y (parameters 1 and 4) can exceed this range. Below is the extract:
Both x values must be in the range [0, 1] or the definition is invalid. The y values can exceed this range.
For a live demo of how the curve is drawn based on the input value and how that shows the progress at any given point in time, you can refer to this great page created by Lea Verou. It allows you to alter the values of the control points on the graph, see how the curve changes based on it and also allows you to see a demo of how that curve would work on an actual transition.
The curve that is drawn for cubic-bezier(0.1,0.1,0.8,3.0) would look like this and as you can see it is completely normal that with this curve, the width exceeds 100% before the transition is completed and then comes back down to 100% by the end (as that is the end value). For the hover out, it will be the reverse behavior and so it will go the other way before coming to the end value (for your example, you won't see it because width cannot be lower than 0% but you'll see it in the second one below.)
.sample_box {
background-color: orange;
height: 70px;
width: 35%;
transition: width 2s;
transition-timing-function: cubic-bezier(0.1, 0.1, 0.8, 3.0);
}
.sample_box:hover {
width: 100%;
}
/* just for demo */
div.container {
height: 200px;
width: 300px;
border: 1px solid;
margin: 0px auto;
}
.sample_box_2 {
background-color: tomato;
height: 70px;
width: 35%;
transform: translate(0%, 0%);
transition: transform 2s;
transition-timing-function: cubic-bezier(0.1, 0.1, 0.8, 3.0);
}
.container.second:hover .sample_box_2 {
transform: translate(100%, 100%);
}
<div class='container'>
<div class='sample_box'></div>
</div>
<div class='container second'>
<div class='sample_box_2'></div>
</div>

Related

transform: rotateY() making element disappear

I am trying to apply a simple transform: rotateY(90deg) on an div but it's (the div) disappearing as a result, dev tools is not throwing any error on that line, any suggestions or anything I might be missing?
This happens because when you rotate something on the Y axis by 90 degrees it has spun so that it's essentially facing a different direction. In the below example I've added a transition to show how the element changes over time (hover over it):
figure {
background: red;
height: 100px;
transition: 1s;
width: 100px;
}
div:hover figure {
transform: rotateY(90deg);
}
<div>
<figure></figure>
</div>
As our viewport looks directly onto the element and features no depth, it appears that the element has disappeared altogether.
If we do add some depth, it's easier to visualise what's happening:
The cube on the left is our pre-transform cube and the cube on the right is our cube after it's had rotateY(90deg) applied to it. As we have no depth at all and we're looking at our element front on, we can't see anything when it gets rotated by 90 degrees.

Strange animation with transition on transform matrix

I'm getting a weird behaviour in my animation when I'm using transition on transform:matrix(). I'm only changing one parameter, but in the transition it looks like it's handling multiple parameters.
Hard to explain, so here's an example:
div {
width: 200px;
height: 400px;
border: 1px solid black;
position: relative;
overflow: hidden;
}
span {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: red;
transform: matrix(1, -.5, 0, 1, 0, 0);
transform-origin: left bottom;
transition: transform .5s ease;
}
div:hover span {
transform: matrix(1, 0, 0, 1, 0, 0);
}
<div>
<span></span>
</div>
External jsbin link
As you can see, it's only supposed to animate the bottom right corner (the top left is animated too, but out of view), but it seems to be doing something strange in the upper left hand corner. Any ideas how to get around this? Is there some trick to transitioning between transform:matrix?
You can use transform: skewY(-28deg); rather than transform: matrix(1,-.5,0,1,0,0); and transform: skewY(0); rather than transform: matrix(1,0,0,1,0,0);
Like I say here
When animating or transitioning transforms, the transform function lists must be interpolated. Two transform functions with the same name and the same number of arguments are interpolated numerically without a former conversion. The calculated value will be of the same transform function type with the same number of arguments.
Special rules apply to rotate3d(), matrix(), matrix3d() and perspective(). The transform functions matrix(), matrix3d() and perspective() get converted into 4x4 matrices first and interpolated. If one of the matrices for interpolation is singular or non-invertible (iff its determinant is 0), the transformed element is not rendered and the used animation function must fall-back to a discrete animation according to the rules of the respective animation specification.
maybe at some point in the transition(you'll have to do the math) appears a singular matrix and the animation function must fall-back to a discrete animation
Here is the full information
What you can do is to increase the scaleX and scaleY then decrease the translateX:
transform: matrix(1.2, 0, 0, 1.2, -30, 0);
DEMO
Trick? I don't think so, but it behaves like using skew in a photo editor (e.g Photoshop).
If you skew an element and then skew it again to bring it back to its original state(by doing it slowly) you may see the same behaviour

CSS3 Transform only plays first item

I am trying to get my div to rotate 360deg every time I click it, using CSS3 transform rotate. However, I'm also using the CSS3 transform translate to vertically align my div.
On the first click, it applies all the required CSS but doesn't actually rotate, however will rotate all clicks after that. It stays vertically aligned the whole time.
Unsure how to solve this and any help is appreciated :)
My css:
#my-div {
height: 300px;
width: 300px;
transition: all 0.5s ease-in-out;
display: block;
margin: auto;
/*to vertically align*/
position: relative;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
My javascript
var angle = 360
$('#my-div').click(function() {
$(this).css({
'-webkit-transform' : 'translateY(-50%) rotate('+angle+'deg) ',
'transform' : 'translateY(-50%) rotate('+angle+'deg)'
})
angle += 360
});
In fact the transition works properly only when the 2 ends are explicitly set, here intially the rotate transform is not set explicitly, after the first click, it's explicitly set to rotate(360deg) and hence the next clicks work. To solve this, you just need to apply rotate(0deg) for your div initially via the CSS code:
#my-div {
/*...*/
-webkit-transform: translateY(-50%) rotate(0deg);
transform: translateY(-50%) rotate(0deg);
}
Note that I emphasized on the properly word, in fact if you set the initial angle to some angle equal or smaller than 180deg, you'll see it transitions OK. I doubt that if you don't set the initial rotate transform explicitly, the behavior is determined by the browser, that is 360deg won't make any transition, otherwise the rotating transition may be clockwise (if the angle % 360 is less than or equal to 180deg) and counter-clockwise if the angle % 360 is greater than 180deg (note about the modulo operation between angle and 360).
Demo.

why negative value in rotateX in css doesnt change the direction of rotation

If you put in css transform: rotateY(-30deg) vs transform: rotateY(30deg). You will have two different results, the results you would expect. Rotate in one direction or the other. Same with Z axis.
But with X axis it doesnt seem to be the case. I want top side to come in front while bottom side to go back when rotating over X axis.
Check out the demo:
http://jsfiddle.net/techsin/x5Qgx/3/
Is it bug in css?
I know I could give it value like 330 or something but that rotates it two times and messes up the animation I want. If it wasn't for the animation I'd have used that.
Sooo frustrating.
It works for Y, Z but why not for X?
Because it is showing the orthographic projection.
You need to define the perspective to the parent element:
-webkit-perspective: 500px;
-moz-perspective: 500px;
-o-perspective: 500px;
perspective: 500px;
More info at MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective

How to determine direction of rotation in CSS3 transitions?

I'd like to rotate an object from -180 degrees to 180 degrees via CSS3 transforms and transitions. This works fine, but I'd like to control the direction of rotation. How to determine if it will be going clockwise or counter clockwise?
0 .. 180 is clockwise, 0 .. -180 is counterclockwise. So, positive number rotates clockwise, negative - other way around. You can also keep increasing/decreasing the number to continue rotation, the browser will remove additional 360s.
I created an example of how to rotate:
<html>
<style type="text/css">
.rotatedDiv {
margin-top: 200px;
margin-left: 200px;
-webkit-transition: -webkit-transform 3s ease-in;
-webkit-transform: rotate(1deg);
-moz-transform: rotate(1deg);
}
</style>
<body>
<div class="rotatedDiv" onclick="this.style.webkitTransform='rotate(-100deg)'">
This div will do a spin when clicked!
</div>
</body>
</html>
First we display rotated div. When you click on it, it will rotate. Depending on the value - negative or positive it will rotate counter-clockwise or clockwise.
It seems that you also need to remember to put in the "from" initial concrete values, otherwise the +/- direction sign won't behave well.

Resources