Reputation: 5386
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:
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. :)
Upvotes: 4
Views: 5915
Reputation: 488
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?
opacity: 0
after click: 18px (2px + 6px + 2px + 6px + 2px)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?
opacity: 0;
it will be a margin size + the object height, so 8px in our example.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;
}
Upvotes: 4
Reputation: 3994
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>
Upvotes: 1
Reputation: 5411
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.
Upvotes: 1
Reputation: 7157
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.
Upvotes: 2