I have crafted a small css drop down button/menu which I am now trying to animate.
I had the menu initially going from display: none to display:block when hovering the parent, but I cannot animate this - so I have tried swapping to opacity: 0, height: 0 to opacity: 1, height: auto but this is causing some weird functionality with the menu. Let me show you what I mean. Here is the original menu code :
HTML :
<div className="account-dropdown">
<button className="dropbtn">
<FormattedMessage
id="header.account"
defaultMessage={`Account`} />
</button>
<div className="dropdown-content">
<a>Order History</a>
<a>Settings</a>
<a onClick={logOut}>Logout</a>
</div>
</div>
The scss :
.account-dropdown {
position: relative;
display: inline-block;
&:hover {
.dropdown-content {
display: block;
}
.dropbtn {
color: red;
}
}
.dropbtn {
border: none;
cursor: pointer;
margin: 2rem 1rem;
transition: all 0.3s;
color: black;
background-color: #fff;
}
.dropdown-content {
display: none;
padding: 3rem 3rem 1rem 3rem;
position: absolute;
top: 5rem;
left: -17.6rem;
background-color: #fff;
min-width: 250px;
width: 100%;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2);
border: solid 1px #e8e8e8;
z-index: 1;
color: rgba(0, 0, 0, 0);
transition: all 0.3s;
&:after, &:before {
bottom: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
&:after {
border-color: rgba(255, 255, 255, 0);
border-bottom-color: #ffffff;
border-width: 7px;
left: 75%;
margin-left: 26px;
}
&:before {
border-color: rgba(113, 158, 206, 0);
border-bottom-color: #e8e8e8;
border-width: 8px;
left: 75%;
margin-left: 25px;
}
a {
text-align: left;
color: black;
padding-bottom: .8rem;
text-decoration: none;
display: block;
cursor: pointer;
transition: all 0.3s;
&:hover {
color: black;
}
&:last-child {
margin-top: .4rem;
padding-top: .8rem;
border-top: solid 1px #e8e8e8;
}
}
}
}
Here it is running in a fiddle (without the rems or scss vars) https://jsfiddle.net/tqf1r0mm/7/
And here is a fiddle when I swap the display none for opacity and height -> https://jsfiddle.net/tqf1r0mm/10/ .
You can see both that the animation is janky and also if you hover below account button the menu opens (I would only like it to open when the user hovers account).
Any ideas on how to fix this to get a nice smooth animation? Any advice would be great. Thanks!
you may be using the atribute transition: all and is because that the animation looks like that
but instead of using height:0; you can use: visibility:hidden; and visibility:visible on hover to avoid that animation problem
something like this
.test {
padding-left: 300px;
.account-dropdown {
position: relative;
display: inline-block;
&:hover {
.dropdown-content {
opacity: 1;
visibility:visible;
}
.dropbtn {
color: black;
}
}
.dropbtn {
border: none;
cursor: pointer;
margin: 20px 10px;
transition: all 0.3s;
color: black;
background-color: #fff;
}
.dropdown-content {
opacity: 0;
visibility:hidden;
padding: 3rem 3rem 1rem 3rem;
position: absolute;
top: 50px;
left: -176px;
background-color: #fff;
min-width: 250px;
width: 100%;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2);
border: solid 1px #e8e8e8;
z-index: 1;
color: rgba(0, 0, 0, 0);
transition: all 0.3s;
&:after,
&:before {
bottom: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
&:after {
border-color: rgba(255, 255, 255, 0);
border-bottom-color: #ffffff;
border-width: 7px;
left: 75%;
margin-left: 26px;
}
&:before {
border-color: rgba(113, 158, 206, 0);
border-bottom-color: #e8e8e8;
border-width: 8px;
left: 75%;
margin-left: 25px;
}
a {
text-align: left;
color: black;
padding-bottom: 8px;
text-decoration: none;
display: block;
cursor: pointer;
transition: all 0.3s;
&:hover {
color: black;
}
&:last-child {
margin-top: 4px;
padding-top: 8px;
border-top: solid 1px #e8e8e8;
}
}
}
}
}
Use visibility instead of height, but use the opacity as well, because you can't animate visibility either. Also put the trigger on .dropbtn instead of .account-dropdown to avoid it activating the hover state when you hover anywhere except the button.
I don't know SCSS so I used CodePen to convert to regular CSS. Here's the code I used:
.test {
padding-left: 300px;
}
.test .account-dropdown {
position: relative;
display: inline-block;
}
.test .account-dropdown .dropbtn:hover~.dropdown-content {
visibility: visible;
opacity: 1;
}
.test .account-dropdown .dropdown-content:hover {
visibility: visible;
opacity: 1;
}
.test .account-dropdown:hover .dropbtn {
color: black;
}
.test .account-dropdown .dropbtn {
border: none;
cursor: pointer;
margin: 20px 10px;
transition: all 0.3s;
color: black;
background-color: #fff;
}
.test .account-dropdown .dropdown-content {
opacity: 0;
visibility: hidden;
padding: 3rem 3rem 1rem 3rem;
position: absolute;
top: 50px;
left: -176px;
background-color: #fff;
min-width: 250px;
width: 100%;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2);
border: solid 1px #e8e8e8;
z-index: 1;
color: transparent;
transition: all 0.3s;
}
.test .account-dropdown .dropdown-content:after,
.test .account-dropdown .dropdown-content:before {
bottom: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.test .account-dropdown .dropdown-content:after {
border-color: rgba(255, 255, 255, 0);
border-bottom-color: #ffffff;
border-width: 7px;
left: 75%;
margin-left: 26px;
}
.test .account-dropdown .dropdown-content:before {
border-color: rgba(113, 158, 206, 0);
border-bottom-color: #e8e8e8;
border-width: 8px;
left: 75%;
margin-left: 25px;
}
.test .account-dropdown .dropdown-content a {
text-align: left;
color: black;
padding-bottom: 8px;
text-decoration: none;
display: block;
cursor: pointer;
transition: all 0.3s;
}
.test .account-dropdown .dropdown-content a:hover {
color: black;
}
.test .account-dropdown .dropdown-content a:last-child {
margin-top: 4px;
padding-top: 8px;
border-top: solid 1px #e8e8e8;
}
<div class="test">
<div class="account-dropdown">
<button class="dropbtn">
Account
</button>
<div class="dropdown-content">
<a>Order History</a>
<a>Settings</a>
<a>Logout</a>
</div>
</div>
</div>
I also added another hover class when you hover over .dropdown-content otherwise it dissappears when you try to click on one of the links.
Related
I'm unable to get the hover background color timing to sync with :before. How can I fix this issue?
When you hover over the button, you will notice the transition of the background color is not in sync.
JSFIDDLE DEMO: https://jsfiddle.net/7c25wmuz/
.btn-primary {
background-color: #2c9ff5;
border-color: #2c9ff5;
text-transform: capitalize;
}
.btn.btn-primary:hover {
background-color: #45aff6;
border-color: #45aff6;
}
.btn-donate {
background-color: #053a86;
color: #fff;
margin-left: 15px;
padding-left: 40px;
padding-right: 30px;
padding-top: 2px;
text-transform: uppercase;
border-radius: 4px 0 0 4px;
height: 30px;
position: relative;
border: none;
}
.btn-donate:before {
content: '';
position: absolute;
top: 0;
left: 0;
border-top: 30px solid white;
border-right: 20px solid #053a86;
width: 0;
}
.btn-donate:hover::before {
border-right: 20px solid #45aff6;
}
Donate
Clip path is the solution you need for something like this.
.btn-primary {
background-color: #2c9ff5;
border-color: #2c9ff5;
text-transform: capitalize;
clip-path: polygon(20% 0, 100% 0, 100% 100%, 0% 100%);
}
.btn.btn-primary:hover {
background-color: #45aff6;
border-color: #45aff6;
}
.btn-donate {
background-color: #053a86;
color: #fff;
margin-left: 15px;
padding-left: 40px;
padding-right: 30px;
padding-top: 2px;
text-transform: uppercase;
border-radius: 4px 0 0 4px;
height: 30px;
position: relative;
border: none;
transition: .5s all ease;
}
Donate
You can just add a background transition to .btn-donate and border transition to .btn-donate:before like so:
(added padding bottom to see things)
body {
margin-top: 15px;
}
.btn-primary {
background-color: #2c9ff5;
border-color: #2c9ff5;
text-transform: capitalize;
}
.btn.btn-primary:hover {
background-color: #45aff6;
border-color: #45aff6;
}
.btn-donate {
background-color: #053a86;
color: #fff;
margin-left: 15px;
padding-left: 40px;
padding-right: 30px;
padding-top: 2px;
padding-bottom: 1rem;
text-transform: uppercase;
border-radius: 4px 0 0 4px;
height: 30px;
position: relative;
border: none;
transition: .3s ease background;
}
.btn-donate:before {
content: '';
position: absolute;
top: 0;
left: 0;
border-top: 30px solid white;
border-right: 20px solid #053a86;
width: 0;
transition: .3s ease border;
}
.btn-donate:hover::before {
border-right: 20px solid #45aff6;
}
Donate
It seems you runned into conflict with browser default styles. You can see default styles in your Developer tools (F12) you just need to enable it. Go to developer tools settings and check "Show browser styles".
This issue can be simply fixed by overriding default styles with your own.
body {
margin-top: 15px;
}
.btn {
transition: unset; /* override, this is all you need */
display: block;
height: 30px;
}
.btn-primary {
background-color: #2c9ff5;
border-color: #2c9ff5;
text-transform: capitalize;
}
.btn.btn-primary:hover {
background-color: #45aff6;
border-color: #45aff6;
}
.btn-donate {
background-color: #053a86;
color: #fff;
margin-left: 15px;
padding-left: 40px;
padding-right: 30px;
padding-top: 2px;
text-transform: uppercase;
border-radius: 4px 0 0 4px;
height: 30px;
position: relative;
border: none;
}
.btn-donate:before {
content: '';
position: absolute;
top: 0;
left: 0;
border-top: 30px solid white;
border-right: 20px solid #053a86;
width: 0;
}
.btn-donate:hover::before {
border-right: 20px solid #45aff6;
}
Donate
I'm attempting to make a button that has an ::after content of transparent background and white border. Button is supposed to fall into that content without ::after changing any position.
I'm having some trouble figuring it out.
Here's the code.
button {
position: relative;
color: black;
font-size: 1.625rem;
background-color: yellow;
border: 1px solid white;
padding: 15px 50px;
cursor: pointer;
}
button::after {
content: "";
position: absolute;
left: 0.8rem;
top: 0.8rem;
width: 100%;
height: 100%;
background: transparent;
border: 1px solid white;
transition: all 0.3s;
z-index: -1;
}
You can find exact look on this JFiddle Link: https://jsfiddle.net/d7knzb1p/6/
thank you all
You can try to have :hover for your button and button::after
button:hover::after to reset the shadowed layer to the original button
Another key change here is that we'd use translate for the better animation
body {
background-color: black;
}
button {
position: relative;
color: black;
font-size: 1.625rem;
background-color: yellow;
border: 1px solid white;
padding: 15px 50px;
cursor: pointer;
transition: all 0.2s;
}
button:hover {
background-color: transparent;
transform: translate(0.8rem, 0.8rem);
color: white;
}
button:hover::after {
content: "";
transform: translate(-0.8rem, -0.8rem);
}
button::after {
content: "";
position: absolute;
left: 0.8rem;
top: 0.8rem;
transform: translate(0, 0);
width: 100%;
height: 100%;
background: transparent;
border: 1px solid white;
transition: all 0.2s;
z-index: -1;
}
<button>
BUY
</button>
.btn-text {
background: transparent;
box-sizing: border-box;
text-decoration: none;
box-shadow: inset 0 0 0 1px transparent;
border-bottom: 1px solid transparent;
color: red;
padding: 8px 12px 0;
font-size: inherit;
font-weight: 500;
position: relative;
width:100px;
display:block;
vertical-align: middle;
animation: before 0.4s ease;
transition: all 0.4s ease;
margin-top: 30px;
}
.btn-text::before, .btn-text::after {
box-sizing: inherit;
content: "";
position: absolute;
width: 100%;
height: 100%;
}
.btn-text:active {
transform: translateY(0);
box-shadow: 0 1rem 0.5rem rgba(0, 0, 0, 0.2);
}
.btn-text:hover {
text-decoration: none;
color: red;
border-bottom: 1px solid transparent;
}
.btn-text::before, .btn-text::after {
top: 0;
left: 0;
height: 100%;
width: 100%;
transform-origin: center;
}
.btn-text::before {
border-top: 1px solid red;
border-bottom: 1px solid red;
transform: scale3d(0, 1, 1);
}
.btn-text::after {
border-left: 1px solid red;
border-right: 1px solid red;
transform: scale3d(1, 0, 1);
}
.btn-text:hover::before, .btn-text:hover::after {
animation: border 0.5s ease forwards;
}
.btn-text span {
display: block;
border-bottom: 1px solid red;
margin-top: 8px;
}
#keyframes border {
to{
transform: scale3d(1,1,1);
}
}
<a href="#!" class="btn-text " style="width: fit-content">know
more
<span></span>
</a>
I am trying to add a cool hover in animation effect. When I hover over the button I am calling an animation which scaling up borders .
My problem is that when I hover out of button it goes back to the initial state without animation.
I want that the same animation should reverse when I hover out.
You don't need an animation for this, you need a transition...like so:
Codepen Demo
* {
box-sizing: border-box;
}
.btn-text {
background: transparent;
text-decoration: none;
box-shadow: inset 0 0 0 1px transparent;
border-bottom: 1px solid transparent;
color: red;
padding: 8px 12px 0;
font-size: inherit;
font-weight: 500;
position: relative;
width: 100px;
display: block;
vertical-align: middle;
margin-top: 30px;
margin-left: 30px;
}
.btn-text::before,
.btn-text::after {
box-sizing: inherit;
content: "";
position: absolute;
width: 100%;
height: 100%;
transition: transform .5s;
}
.btn-text:hover {
text-decoration: none;
color: red;
border-bottom: 1px solid transparent;
}
.btn-text::before,
.btn-text::after {
top: 0;
left: 0;
height: 100%;
width: 100%;
transform-origin: center;
}
.btn-text::before {
border-top: 1px solid red;
border-bottom: 1px solid red;
transform: scale3d(0, 1, 1);
}
.btn-text::after {
border-left: 1px solid red;
border-right: 1px solid red;
transform: scale3d(1, 0, 1);
}
.btn-text:hover::before {
transform: scale3d(1, 1, 1);
}
.btn-text:hover::after {
transform: scale3d(1, 1, 1);
}
.btn-text span {
display: block;
border-bottom: 1px solid red;
margin-top: 8px;
}
<a href="#!" class="btn-text " style="width: fit-content">know more
<span></span>
</a>
How can i make this buttons responsive?
(with the phone) i want see the buttons with a full width, but i can't and i don't know why!
PS: You can change everything you want, but please help me!
PS2: The buttons have an animation, i know how to block this so use only this code.
If you need more information about this, just ask, i will answer you soon i can! Sorry for my bad english and thank you for the help!
.bottoni {
display: block;
z-index: 999;
width: 100px;
height: 100%;
position: absolute;
top: 50%; bottom: 0; right: 0;
transform:translateX(-190%);
margin-top: -200px;
text-align: left;
}
.bottoni > a {
display: inline-block;
padding: 10px 40px;
min-width: 240px;
margin: 20px;
background: rgba(0, 0, 0, 0.9);
border-left: 15px solid #f45341;
border-right: 3px solid #f45341;
text-decoration: none;
color: #fff;
text-transform: uppercase;
font-size: 30px;
background: linear-gradient(to left, #f45341 50%, rgba(96, 96, 96, 0.4) 50%);
background-position: 0% 0%;
background-size: 200%;
transition: background 150ms ease-in-out, color 150ms ease-in-out;
transition: .3s;
font-family: pricedown;
border-radius: 5px;
text-align: left;
}
.bottoni > a:hover {
color: #fff;
background-position: -100% 0%;
cursor: pointer;
border-left: 15px solid #f45341;
}
.bottoni2 {
display: block;
z-index: 999;
width: 100px;
height: 100%;
margin: 0;
position: absolute;
top: 50%; bottom: 0; left: 0;
transform:translateX(-100%);
margin-top: -200px;
text-align: right;
}
.bottoni2 > a {
display: inline-block;
padding: 10px 40px;
min-width: 240px;
margin: 20px;
background: rgba(0, 0, 0, 0.9);
border-right: 15px solid #f45341;
border-left: 3px solid #f45341;
text-decoration: none;
color: #fff;
text-transform: uppercase;
font-size: 30px;
background: linear-gradient(to right, rgba(96, 96, 96, 0.4) 50%, #f45341 50%);
background-position: 0% 0%;
background-size: 200%;
transition: background 150ms ease-in-out, color 150ms ease-in-out;
transition: .3s;
font-family: pricedown;
border-radius: 5px;
text-align: right;
}
.bottoni2 > a:hover {
color: #fff;
background-position: -100% 0%;
cursor: pointer;
border-right: 15px solid #f45341;
}
#media only screen and (max-width: 768px) {
.bottoni{
width: 100%;
position: relative;
display: inline-block;
transform:translate(0%,0%);
top: 0; bottom: 0; right: 0; left: 0;
}
}
<div class="bottoni">
<a target="blank_" id="store" href="http://store.sparocraft.eu">Store</a>
<a target="blank_" id="votaci" href="http://vota.sparocraft.eu">Votaci</a>
</div>
<div class="bottoni2">
<a target="blank_" id="ts" class="offline" href="ts3server://ts.sparocraft.eu">TeamSpeak</a>
<a target="blank_" id="bans" class="offline" onclick="offline();">Bans</a>
</div>
There are a couple things going on:
First, I changed your CSS to have mobile/small screens first. This way you can have all your styles for the buttons and then just change the positioning for larger screens. Second, you can easily combine styles for your buttons so you don't have a bunch of repeating styles.
Hopefully this is what you're looking for:
* {
box-sizing: border-box;
}
.bottoni,
.bottoni2 {
position: relative;
}
.bottoni > a,
.bottoni2 > a {
display: block;
width: 100%;
padding: 10px 40px;
margin: 20px 0;
background: rgba(0, 0, 0, 0.9);
border-left: 15px solid #f45341;
border-right: 3px solid #f45341;
text-decoration: none;
color: #fff;
text-transform: uppercase;
font-size: 30px;
background: linear-gradient(to left, #f45341 50%, rgba(96, 96, 96, 0.4) 50%);
background-position: 0% 0%;
background-size: 200%;
transition: background .3s ease-in-out, color .3s ease-in-out;
font-family: pricedown;
border-radius: 5px;
text-align: left;
}
.bottoni > a:hover,
.bottoni2 > a:hover {
color: #fff;
background-position: -100% 0%;
cursor: pointer;
}
#media screen and (min-width: 768px) {
.bottoni,
.bottoni2 {
position: absolute;
width: 300px;
top: 50%;
right: 0;
transform: translatey(-100%);
}
.bottoni > a,
.bottoni2 > a {
position: relative;
width: 300px;
}
.bottoni2 {
left: 0;
right: auto;
}
.bottoni2 > a {
border-right: 15px solid #f45341;
border-left: 3px solid #f45341;
}
.bottoni2 > a:hover {
border-right: 15px solid #f45341;
}
}
<div class="bottoni">
<a target="blank_" id="store" href="http://store.sparocraft.eu">Store</a>
<a target="blank_" id="votaci" href="http://vota.sparocraft.eu">Votaci</a>
</div>
<div class="bottoni2">
<a target="blank_" id="ts" class="offline" href="ts3server://ts.sparocraft.eu">TeamSpeak</a>
<a target="blank_" id="bans" class="offline" onclick="offline();">Bans</a>
</div>
Here is the fiddle so you can check it out:
https://jsfiddle.net/sxcg1o7u/1/
I'm not new to CSS but for some reason I've not played with animations or transitions up to this point. I want to learn how to apply any form of transition to a tooltip that I've made, but every time I read code and then try I seem to fail. I have a quick example of code I put together and maybe someone can quickly show me what I'm doing wrong.
Note: This is only an example, I don't plan to use a 2 second transition, makes it clear that it's working.
Following is the key code, please see the jsfiddle here.
label[data-tooltip] {
border-bottom: 1px dotted rgba(0, 0, 0, 0.3);
padding-bottom: 2px;
position: relative;
cursor: pointer;
&:hover:after {
transition: all 2s ease-in-out;
.borderRadius(3px);
content: attr(data-tooltip);
background: rgba(83, 83, 83, 0.95);
text-transform: none;
position: absolute;
line-height: 18px;
padding: 5px 10px;
font-size: 13px;
width: 100px;
z-index: 99;
color: #fff;
bottom: 120%;
left: -5px;
}
&:after {
display: none;
}
&:hover:after {
display: block;
}
}
Try this solution
you should assign all the styles to the after
and to the hover status just the attribute you want to animate
label[data-tooltip] {
border-bottom: 1px dotted rgba(0, 0, 0, 0.3);
padding-bottom: 2px;
position: relative;
cursor: pointer;
&:after {
transition: all ease 5s;
content: attr(data-tooltip);
background: rgba(83, 83, 83, 0.95);
text-transform: none;
position: absolute;
line-height: 18px;
padding: 5px 10px;
font-size: 13px;
width: 100px;
z-index: 99;
color: #fff;
bottom: 120%;
left: -5px;
opacity: 0;
}
&:hover:after {
opacity: 1;
}
}
.formRow {
background: #EFEFEF;
margin: 50px auto;
padding: 10px;
width: 50%;
}
.formRow-label {
display: inline-block;
margin-right: 20px;
}
.formRow-input {
display: inline-block;
}