This question already has answers here:
How to apply multiple CSS3 rotation transformations (compounded) without javascript?
(2 answers)
Closed 7 years ago.
So I have the following CSS:
div {
transform: translate(10, 10);
}
div.active {
transform: scale(1.1);
}
The problem is that a div.active doesn't translate and only scales.
Ain't there a CSS-only (with JS I know I can) way to write something like:
div.active {
transform: inherit scale(1.1);
}
?
Is this some kind of CSS3 design issue?
div {
transform: translate(10px, 10px);
width: 100px;
height: 100px;
background: lightblue;
display: inline-block;
margin: 50px;
}
div.active {
transform: translate(10px, 10px) scale(1.1);
}
div.active2 {
transform: scale(1.1) translate(10px, 10px) rotate(45deg);
}
<div></div>
<div class="active"></div>
The transform property of your active class is overwriting the original value.
You would have to state both in your active class.
Note: translate values require units
div {
transform: translate(10px, 10px);
}
div.active {
transform: translate(10px, 10px) scale(1.1);
}
Related
I am trying to animate a line that expands both ways from the centre using transform:scale but for some reason the line kind of "rewinds" slightly when it reaches the end, but only on the right side of the line. This only seems to happen on firefox, (both on mobile and desktop) but seems fine on chrome.
<div class="line"></div>
<style>
.line {
height: 4px;
width: 5px;
background-color: #5d496a;
margin: 0 50%;
animation: line_animation 1s forwards ;
}
#keyframes line_animation {
0% {
transform: scale(1,1);
}
100%{
transform: scale(22,1);
}
}
</style>
I am still learning animations so I am not sure what I am doing wrong. Any help would be very appreciated.
https://www.w3schools.com/code/tryit.asp?filename=GRA6EYT2GLSX
Looks like it was an issue with scale being greater than 1.
Fixed by changing width: 5px; to width: 15%; and changed
#keyframes line_animation {
0% {
transform: scale(1,1);
}
100%{
transform: scale(22,1);
}
}
to
#keyframes line_animation {
from {
transform: scale(0.01,1);
}
to{
transform: scale(1,1);
}
}
I've been fiddling around with a small problem with an animation that I can't really figure out the problem to.
I have this perfectly working example from w3 schools, but my case is a little different. I am trying to have 2 visible lines in my burger menu, and they are both supposed to be a little smaller.
I have this working code.
The code that is causing me trouble is the following:
.change .bar1 {
-webkit-transform: rotate(-45deg) translate(-9px, 6px);
transform: rotate(-45deg) translate(-9px, 6px);
}
.change .bar3 {
-webkit-transform: rotate(45deg) translate(-8px, -8px);
transform: rotate(45deg) translate(-8px, -8px);
}
I have tried to change the translate statements with so many different numbers and I tried reading to figure out exactly what the translate-statements do when they are placed like they are after the rotate. I just can't figure out exactly how to make the two lines create a cross on their "starting" location (that is without moving to the right or left - too much)
My question is:
What does the translate statements do when they are placed like they
are?
How could I figure out how to make my lines create a cross in their starting position?
I am basically looking for a good method to figure out my problem myself. But if a bright mind out there could supply me with my solution I wouldn't mind. :)
function myFunction(x) {
x.classList.toggle("change");
}
.container {
display: inline-block;
cursor: pointer;
}
.bar1, .bar3 {
width: 35px;
height: 2px;
background-color: #333;
margin: 6px 0;
transition: 0.4s;
}
.invis {
width: 35px;
height: 2px;
margin: 6px 0;
}
.change .bar1 {
-webkit-transform: rotate(-45deg) translate(-5px, 6px);
transform: rotate(-45deg) translate(-5px, 6px);
}
.change .bar3 {
-webkit-transform: rotate(45deg) translate(-5px, -6px);
transform: rotate(45deg) translate(-5px, -6px);
}
<p>Click on the Menu Icon to transform it to "X":</p>
<div class="container" onclick="myFunction(this)">
<div class="bar1"></div>
<div class="invis"></div>
<div class="bar3"></div>
</div>
Should work.
Those numbers are X and Y position. Because you removed the middle line, the position is a little off.
X: Should be same for both. Increase/decrease moves it either left or right.
Y: Should be opposite, so they form a nice cross.
You do not need to guess the numbers for translate through trial and error. You can calculate them pretty simply.
That is why it would be useful to add to the answers above, how to calculate the numbers which should be used for translations.
Speaking about your example.
.bar1, .invis, .bar3 {
width: 35px;
height: 2px;
background-color: #333;
margin: 6px 0;
transition: 0.4s;
}
The height of the bar is 2px and both of the spaces between bar1-invis and invis-bar3 is 6px each. Keep in mind that these bars have collapsing margins. That means that these margins overlap and the distance between the bars will equal the size of one margin.
Vertically we should move the bars to the middle (the position of invis bar).
What is the height of the entire hamburger icon?
For bar2 with opacity: 0 after click: 18px (2px + 6px + 2px + 6px + 2px)
For bar2 with display: none after click: 10px (2px + 6px + 2px)
In this example our borders are 0px, so we do not take them into account.
How much we would need to move bar1 and bar3 in order for them to be in the same position in the middle?
In the case of opacity: 0; it will be a margin size + the object height, so 8px in our example.
In the case of display: none; (I assume the object is vertically centred), it will be (margin + height) / 2 (in our case 4px).
Then we rotate one of the bars by 45 degrees and another one by -45 degrees.
This is a visual presentation of how it works:
Then you add the transition to your CSS.
What you are left with is this:
.change .bar1 {
-webkit-transform: rotate(-45deg) translateY(8px);
transform: rotate(-45deg) translateY(8px);
}
.change .bar3 {
-webkit-transform: rotate(45deg) translateY(-8px);
transform: rotate(45deg) translateY(-8px);
}
.change .invis {
opacity: 0;
}
or this:
.change .bar1 {
-webkit-transform: rotate(-45deg) translateY(4px);
transform: rotate(-45deg) translateY(4px);
}
.change .bar3 {
-webkit-transform: rotate(45deg) translateY(-4px);
transform: rotate(45deg) translateY(-4px);
}
.change .invis {
display: none;
}
What does the translate statements do when they are placed like they
are?
Because the center point of each bar is different, so their references are different.
How could I figure out how to make my lines create a cross in their
starting position?
You have to move the bars somehow, using position properties (top/right/bottom/left), translate or other way. It's not easy to make it right, because it is inside a container with specific size, so each case is different and the bars are placed in different positions.
I strongly recommend to use DevTools to adjust the element inside the container.
This is how it is in the middle of the container:
.change .bar1 {
transform: rotate(-45deg) translate(-7px, 5px);
}
.change .bar3 {
transform: rotate(45deg) translate(-6px, -4px);
}
I hope this helps to clarify some points.
With some playing with numbers I've reached this:
It looks Like Exact X icon.
function myFunction(x) {
x.classList.toggle("change");
}
.container {
display: inline-block;
cursor: pointer;
}
.bar1, .bar3 {
width: 35px;
height: 2px;
background-color: #333;
margin: 6px 0;
transition: 0.4s;
}
.invis {
width: 35px;
height: 2px;
margin: 6px 0;
}
.change .bar1 {
transform: rotate(-45deg) translate(-5px, 6px) ;
}
.change .bar3 {
transform: rotate(45deg) translate(-5px, -6px);
}
<p>Click on the Menu Icon to transform it to "X":</p>
<div class="container" onclick="myFunction(this)">
<div class="bar1"></div>
<div class="invis"></div>
<div class="bar3"></div>
</div>
I've got a series of elements, as shown in the image below:
They are rotated 45 degrees to one side (the content inside -45 degrees, to remain upright).
Now I'd like to rotate each element around a vertical axis, going through the element's center. RotateY doesn't work, as it is at a 45-degree angle.
How would you go about doing this?
The trick is to set this rotation before the 45 degrees rotation:
Notice also that to make the rotation behave really as expect, you need to set it to 0 in the base state
.container {
width: 200px;
height: 200px;
margin: 100px;
border: solid 1px;
transform: rotateY(0deg) rotate(45deg); /* needs Y at 0 deg to behave properly*/
transition: transform 2s;
}
.container:hover {
transform: rotateY(180deg) rotate(45deg); /* notice the order */
}
.inner {
margin: 50px;
transform: rotate(-45deg);
}
<div class="container">
<div class="inner">INNER</div>
</div>
This is how I interpret the question. I'm not very happy with the demo since it needs a lot of structure.
But maybe you can verify the behavior?
Basically I use a wrapper to rotate on the y-axis.
It is key to set the transform origin to the center.
The additional wrapper is used to prevent a flickering on mouse hover.
https://jsfiddle.net/nm59mqky/1/
.tile {
transform: rotateY(0);
transform-origin: center center;
}
.wrapper:hover .tile {
transform: rotateY(180deg);
}
I dont know exactly what your code looks like, but for a simple spinning tile (div) i would try something like this:
#keyframes rotate-vertical {
0% {
transform: rotate3d(0, 1, 0, 0deg);
}
100% {
transform: rotate3d(0, 1, 0, 360deg);
}
}
body {
padding: 20px;
}
.tile {
width: 65px;
height: 65px;
background-color: red;
text-align: center;
transform: rotate3d(0, 0, 1, 45deg);
display: inline-block;
}
.turndiv {
width: 65px;
}
.turndiv:hover {
animation: rotate-vertical 1.1s ease-out;
}
<div class="turndiv">
<div class="tile">
</div>
</div>
You could just do it with transform: rotate3d(); and without a parent div, but to keep it easy i did it like this.
I have a CSS3 Animation for an indeterminate progress bar. In the animation I have a gradient oscillating back and forth along the progress bar. I would like to flip the image of gradient horizonally as it travels back to the left side of the progress bar. Basically the gradient always fades out the opposite direction the image is moving. Unfortunately I can't figure out a way for the image to flip horizontally BEFORE it starts moving back towards the left and am getting some odd transformations of the image as it flips.
I have created a JSFiddle to show how it looks right now.
http://jsfiddle.net/MtWzL/
Here is the CSS I'm currently using for the animation:
#-webkit-keyframes loader {
0% {
-webkit-transform: scaleX(1);
-webkit-transform: translateX(-100px);
-webkit-transform-origin:left;
}
50% {
-webkit-transform: translateX(300px);
}
100% {
-webkit-transform: translateX(-100px);
-webkit-transform: scaleX(-1);
}
}
#keyframes loader {
0% {
transform: scaleX(1);
transform: translateX(-100px);
transform-origin:left;
}
50% {
transform: translateX(300px);
}
100% {
transform: translateX(-100px);
transform: scaleX(-1);
}
}
.slider
{
animation: loader 2.5s infinite linear;
-webkit-animation: loader 2.5s infinite linear; /* Safari and Chrome */
background: url('http://s23.postimg.org/mglkwgxuv/indeterminate_bg.png') no-repeat;
border-radius: 10px;
height: 10px;
position: relative;
width: 100px;
z-index: 999;
opacity: .6;
}
.container {
background: -webkit-linear-gradient(#00c3ff,#0071bc);
background: linear-gradient(#00c3ff,#0071bc);
border-radius: 3px;
height: 10px;
overflow: hidden;
width: 300px;
}
.background {
background: rgba(0,0,0,0.7);
border-radius: 3px;
display: inline-block;
padding: 10px;
}
There are 2 issues that need to be fixed
first of all, this
-webkit-transform: scaleX(1);
-webkit-transform: translateX(-100px);
won't work as you expect; the second property over-rides the first one, as you can not set 2 different values for a property in separate lines.
the correct syntax would be
-webkit-transform: translateX(-100px) scaleX(1);
And second, if you want a sudden change in some value, you need to set it from a keyframe to another keyframe close enough to the first one.
So, the solution would be
#-webkit-keyframes loader {
0% { -webkit-transform: translateX(-100px) scaleX(1); }
50% { -webkit-transform: translateX(300px) scaleX(1); }
51% { -webkit-transform: translateX(300px) scaleX(-1); }
100% { -webkit-transform: translateX(-100px) scaleX(-1); }
}
corrected fiddle
I have corrected only the webkit transforms, but the same concept applies to the rest.
I was watching for your problem since you put it here, but I guess its some kind of bug we won't solve or maybe I just dont understand why it is working like that.
Since I had no clue how to solve it I manage to do example for you with alternative solution
EXAMPLE
As you can see I modified your jsfiddle, simple words, created another slide loader .sliderBack that goes backwards. Hope it will helps you somehow. Peace :)
When an object is rotated +180° everything inside it gets flipped so that it is still readable (I guess), I want to avoid that , how to do it?
Just wrap your text in a div and rotate it with an opposite value of the degree that you assign to your parent div:
div.flipped {
background: lightblue;
padding-left: 150px;
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
}
div.noflipped {
background: lightblue;
padding-left: 150px;
-webkit-transform: rotate(-180deg);
-moz-transform: rotate(-180deg);
}
Demo: http://jsfiddle.net/uTGXx/7/