Reputation: 13
I would like to have a span within the .btn rotate 180 deg when I click the .btn. However, the span also moved to the right and went down after it was rotated. Could anyone help me explain why it moved like that. I tried to transform: translate(-21px, 1px) after rotation then the span will moved the right place but I believe there will be another better way to fix it. I also tried transform-origin: 50% 50% but it doesn't work either.
$('.btn').on('click', function(){
$(this).toggleClass('open');
})
@import "https://fonts.googleapis.com/css?family=Raleway";
body {
background-color: #ddd;
font-family: "Raleway", "Microsoft JhengHei", Arial, sans-serif;
color: #7a7b7c;
}
.btn {
width: 80px;
height: 80px;
background-color: #6F7272;
border-radius: 50%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 0 2rem #babbbc;
position: absolute;
}
.btn span {
width: 40px;
height: 2px;
background-color: #ffffff;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
.btn::before, .btn::after {
content: "";
width: 40px;
height: 2px;
background-color: #ffffff;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
.btn::before {
margin-top: -7px;
}
.btn::after {
margin-top: 7px;
}
.open {
transition: 0.3s ease-in-out;
background-color: #6F7272;
}
.open span {
transition: .3s ease-in-out;
transform: rotate(180deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn">
<span></span>
</div>
Upvotes: 1
Views: 178
Reputation: 7109
Your approach isn't working as expected, because after click event, you are transforming the X
& Y
values of your span
using translate
property and then rotating
it. This causes it to shift it's location when transformed.
You used position: absolute
to place your span
in middle. this can be also be achieved via other CSS properties like display: table
or display :flex
Check out the below suggestion - most of the code is all yours with just slight change.
$('.btn').on('click', function() {
$(this).toggleClass('open');
})
@import "https://fonts.googleapis.com/css?family=Raleway";
body {
background-color: #ddd;
font-family: "Raleway", "Microsoft JhengHei", Arial, sans-serif;
color: #7a7b7c;
}
.btn {
width: 80px;
height: 80px;
background-color: #6F7272;
border-radius: 50%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 0 2rem #babbbc;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
}
.btn span {
width: 40px;
height: 2px;
background-color: #ffffff;
/* top: 50%;
left: 50%;
transform: translate(-50%, -50%);
position: absolute; */
}
.btn::before,
.btn::after {
content: "";
width: 40px;
height: 2px;
background-color: #ffffff;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
.btn::before {
margin-top: -7px;
}
.btn::after {
margin-top: 7px;
}
.open {
transition: 0.3s ease-in-out;
background-color: #6F7272;
}
.open span {
transition: .3s ease-in-out;
transform: rotate(180deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn">
<span></span>
</div>
Upvotes: 0
Reputation: 4418
If you remove transform: translate(-50%, -50%);
and just keep left:26%
and top: 49%
It works fine.
To your question why it is happening. Because you have moved it using left and top position and again you are trying to neutralise it by translate. which is moving the center of animation to different position.
$('.btn').on('click', function(){
$(this).toggleClass('open');
})
@import "https://fonts.googleapis.com/css?family=Raleway";
body {
background-color: #ddd;
font-family: "Raleway", "Microsoft JhengHei", Arial, sans-serif;
color: #7a7b7c;
}
.btn {
width: 80px;
height: 80px;
background-color: #6F7272;
border-radius: 50%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 0 2rem #babbbc;
position: absolute;
}
.btn span {
width: 40px;
height: 2px;
background-color: #ffffff;
top: 49%;
left: 26%;
// transform: translate(-50%, -50%);
position: absolute;
}
.btn::before, .btn::after {
content: "";
width: 40px;
height: 2px;
background-color: #ffffff;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
.btn::before {
margin-top: -7px;
}
.btn::after {
margin-top: 7px;
}
.open {
transition: 0.3s ease-in-out;
background-color: #6F7272;
}
.open span {
transition: .3s ease-in-out;
transform: rotate(180deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn">
<span></span>
</div>
Upvotes: 2
Reputation: 4633
Check if this is what you are trying to achieve.
Here, I have added a single line to the css transform-origin: 10px;
. Everything else is the same. The change in JS is to remove the add
class as soon as the animation carried out. Otherwise, you will need to click double times on the button to see the animation again.
$('.btn').on('click', function(){
$(this).addClass('open');
setTimeout(function() {
$('.btn').removeClass('open');
}, 300);
})
body {
background-color: #ddd;
font-family: "Raleway", "Microsoft JhengHei", Arial, sans-serif;
color: #7a7b7c;
}
.btn {
width: 80px;
height: 80px;
background-color: #6F7272;
border-radius: 50%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 0 2rem #babbbc;
position: absolute;
}
.btn span {
width: 40px;
height: 2px;
background-color: #ffffff;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
.btn::before, .btn::after {
content: "";
width: 40px;
height: 2px;
background-color: #ffffff;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
.btn::before {
margin-top: -7px;
}
.btn::after {
margin-top: 7px;
}
.open {
transition: 0.3s ease-in-out;
background-color: #6F7272;
}
.open span {
transition: .3s ease-in-out;
transform: rotate(180deg);
transform-origin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn">
<span></span>
</div>
Upvotes: 0
Reputation: 13417
Update this style
.open span {
transition: .3s ease-in-out;
transform: rotate(180deg) translate(20px, 1px );
}
$('.btn').on('click', function(){
$(this).toggleClass('open');
})
@import "https://fonts.googleapis.com/css?family=Raleway";
body {
background-color: #ddd;
font-family: "Raleway", "Microsoft JhengHei", Arial, sans-serif;
color: #7a7b7c;
}
.btn {
width: 80px;
height: 80px;
background-color: #6F7272;
border-radius: 50%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 0 2rem #babbbc;
position: absolute;
}
.btn span {
width: 40px;
height: 2px;
background-color: #ffffff;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
.btn::before, .btn::after {
content: "";
width: 40px;
height: 2px;
background-color: #ffffff;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
.btn::before {
margin-top: -7px;
}
.btn::after {
margin-top: 7px;
}
.open {
transition: 0.3s ease-in-out;
background-color: #6F7272;
}
.open span {
transition: .3s ease-in-out;
transform: rotate(180deg) translate(20px, 1px );
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn">
<span></span>
</div>
Upvotes: 0