Reputation: 433
I am trying to make this side navbar using HTML/CSS in which I am adding some hover animations. whenever you hover on an icon it will scale to double and the rest of the items in the navbar disperse. But my problem is not that because I already achieved that animation using javascript and CSS. The problem is the animation is not working smoothly in the reverse direction. so I was trying to add short CSS animation to check whether reverse animation transition working properly or not and it is not.
here's my CSS code:
ul{
list-style: none;
}
.navmenu{
position: fixed;
top: 50%;
transform: translateY(-50%);
}
.navmenu ul{
padding-left: 40px;
position: relative;
}
.navmenu ul li {
padding: 15px 0;
}
.navmenu ul li a{
text-decoration: none;
position: relative;
font-size: 1.8rem;
font-weight: 900;
}
.navmenu ul li a i{
-webkit-transition: all 2s ease-in;
transition: all 2s ease-in;
}
.navmenu ul li a:hover i{
-webkit-animation: slide-out-top 0.2s ease-out both;
animation: slide-out-top 0.2s ease-out both;
color: orange;
}
@-webkit-keyframes slide-out-top {
0% {
-webkit-transform: scale(1) translateY(0);
transform: scale(1) translateY(0);
}
100% {
-webkit-transform: scale(0.8,0.8) translateY(-60px);
transform: scale(0.8,0.8) translateY(-60px);
}
}
@keyframes slide-out-top {
0% {
-webkit-transform: scale(1) translateY(0);
transform: scale(1) translateY(0);
}
100% {
-webkit-transform: scale(0.8,0.8) translateY(-60px);
transform: scale(0.8,0.8) translateY(-60px);
}
}
here's its HTML code:
<nav class="navmenu">
<ul>
<li><a href="#home" class=""><i class="fas fa-home"></i><span>Home</span></a></li>
<li><a href="#projects" class=""><i class="fas fa-laptop-code"></i><span>Projects</span></a></li>
<li><a href="#skills" class=""><i class="fas fa-code"></i><span>Skills</span></a></li>
<li><a href="#training" class=""><i class="fas fa-dumbbell"></i><span>Training</span></a></li>
<li><a href="#education" class=""><i class="fas fa-user-graduate"></i><span>Education</span></a>
</li>
<li><a href="#contact_me" class=""><i class="far fa-address-book"></i><span>Contact me</span></a>
</li>
</ul>
</nav>
https://codepen.io/naveen444/pen/zYooJzd?editors=1100
I have read on the internet that animations and transitions are different and transitions can be reversed but not animations but I have used CSS animations before and I remember transitions: all 2s; can reverse all the transitions smoothly. Pardon me if I have said anything wrong. I am an absolute beginner in this and please correct me.
Upvotes: 1
Views: 3135
Reputation: 1709
You can do transform: scale(0.8) translateY(-60px);
on hover
instead of adding animation
. I've changed following css and forked your codepen. This is working as you want.
.navmenu ul li a i{
position: relative;
-webkit-transition: -webkit-transform 1s;
transition: transform 1s;
color: orange;
}
.navmenu ul li a:hover i{
-webkit-transform: scale(0.8) translateY(-60px);
transform: scale(0.8) translateY(-60px);
color: orange;
}
Here is the snippet as well.
body {
background: black;
}
ul {
list-style: none;
}
.navmenu {
position: fixed;
top: 50%;
transform: translateY(-50%);
}
.navmenu ul {
padding-left: 40px;
position: relative;
}
.navmenu ul li {
padding: 15px 0;
}
.navmenu ul li a {
text-decoration: none;
position: relative;
font-size: 1.8rem;
font-weight: 900;
}
.navmenu ul li a span {
font-size: 1rem;
padding-left: 20px;
color: orange;
/* transition: all 0.1s; */
font-weight: 600;
display: none;
}
.navmenu ul li a i {
position: relative;
-webkit-transition: -webkit-transform 1s;
transition: transform 1s;
color: orange;
}
.navmenu ul li a:hover i {
-webkit-transform: scale(0.8) translateY(-60px);
transform: scale(0.8) translateY(-60px);
color: orange;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" />
<body>
<nav class="navmenu">
<ul>
<li><a href="#home" class=""><i class="fas fa-home"></i><span>Home</span></a></li>
<li><a href="#projects" class=""><i class="fas fa-laptop-code"></i><span>Projects</span></a></li>
<li><a href="#skills" class=""><i class="fas fa-code"></i><span>Skills</span></a></li>
<li><a href="#training" class=""><i class="fas fa-dumbbell"></i><span>Training</span></a></li>
<li><a href="#education" class=""><i class="fas fa-user-graduate"></i><span>Education</span></a></li>
<li><a href="#contact_me" class=""><i class="far fa-address-book"></i><span>Contact me</span></a></li>
</ul>
</nav>
</body>
Upvotes: 1
Reputation: 8610
You could define your before and after states with class styling and add/remove these classes with event listeners. One state, would have a mouseover listener, while the other would have a mouseleave listener. You would then need to define your before and after states using css. Then add your @keyframes rules to these specific classes.
For example, you have a class that styles an element, we could call this the before state #icon
. Then you have a class that would be the hover state slidein
. Style this to how you wish the state to look when the animation finishes its tween. Set up your animation parameters in the @keyframes
rule for that specific class. Then you set up another class for the mouseout state, this has a specific style on how you want the element to look once it returns to its original state. Add the @keyframes
rule according to the elements state from mouseover. Lastly, use a setTimeout
to remove the mouseout states class that coincides with the animations timing duration.
I have added a yellow BG on elements parent to illustrate the relationship between hovering the triggering eventlistener and the animating element.
const icon = document.querySelectorAll('.icon')
const animate = (el, duration) => {
const root = document.documentElement;
// conditional that sets the CSS variable to the duration called in your function
// using the css :root element, checks if the duration is over one second and
// formats the root variable to seconds/milliseconds accordingly
if (`${duration}`.length > 3) {
let whole = `${duration}`.slice(0, `${duration}`.length - 3);
root.style.setProperty('--duration', `${whole}s`);
} else {
root.style.setProperty('--duration', `.${duration}s`);
}
el.forEach((node) => {
node.addEventListener('mouseenter', (e) => {
node.children[0].classList.add('slidein');
})
node.addEventListener('mouseleave', (e) => {
node.children[0].classList.add('slideout');
node.children[0].classList.remove('slidein');
setTimeout(() => {
node.children[0].classList.remove('slideout')
}, duration)
})
})
console.log(root)
}
animate(icon, 650)
:root {
--top-pos: -30px;
--duration: 0.7s;
--scale-to: scale(0.6)
}
#parent {
margin-top: 30px;
height: 50px;
width: 50px;
}
.icon img {
width: 50px;
height: 50px;
}
.icon {
margin: 10px 0;
background: yellow;
}
.slidein {
animation: slidein var(--duration) ease-out;
position: relative;
top: var(--top-pos);
transform: var(--scale-to);
}
.slideout {
animation: slideout var(--duration) ease-out;
position: relative;
transform: var(--scale-to);
top: 0px;
}
@keyframes slidein {
0% {
top: 0px;
transform: scale(1);
}
100% {
top: var(--top-pos);
transform: var(--scale-to);
}
}
@keyframes slideout {
0% {
top: var(--top-pos);
transform: var(--scale-to);
}
100% {
top: 0px;
transform: scale(1);
}
}
<div id="parent">
<div class="icon">
<img src="https://nextgate.com/wp-content/uploads/2018/02/icon-implementation.png">
</div>
<div class="icon">
<img src="https://res.cloudinary.com/logrhythm/image/upload/c_scale,w_175/v1519675460/icons/training-advanced-admin-icon.png">
</div>
<div class="icon">
<img src="http://haltin.com.tr/wp-content/uploads/2015/12/icon_integrity-6.png">
</div>
<div class="icon">
<img src="http://www.stephensre.com/images/icons-selling/icon-inspect.png">
</div>
</div>
Upvotes: 0
Reputation: 4459
Can you please check the below code link? Hope it will work for you.
You can do smooth animation using transition property on navbar icon using transform
and transition
property and without using animation
and @-webkit-keyframes
.
Please refer to this link: https://jsfiddle.net/yudizsolutions/zpL3yc4n/
Upvotes: 0
Reputation: 1476
These aren't classic transitions, these are key frame animations. Going with pure CSS, you can do this;
.intern {
-webkit-animation: in 1s;
}
.intern:hover {
-webkit-animation: out 1s;
}
@-webkit-keyframes in {
from { -webkit-transform: rotate(0deg); }
to { -webkit-transform: rotate(360deg);}
}
@-webkit-keyframes out {
0% { -webkit-transform: rotate(360deg); }
100% { -webkit-transform: rotate(0deg); }
}
<div style = "width : 100px; height : 100px; background-color : red" class ="intern"></div>
Run the code snippet and you can find it executing out animation on mouse out.
Upvotes: 1