CSS3 animation begin when hovering over a different element? - javascript

I have a navigation bar that I'm trying to get two links to animate in from off-page and end next to my other links when I hover over one of the links in my list.
Current navigation links:
<div class="links">
<ul>
<li>
link 1
</li>
<li>
link 2
</li>
<li>
link 3
</li>
</ul>
</div>
and the css for .links:
.links ul {
white-space: nowrap;
list-style-type: none;
position: fixed;
top: 8px;
left: 60%;
z-index: 4;
width: auto;
height: 67px;
}
.links li {
white-space: nowrap;
display: inline-block;
margin-right: 30px;
z-index: 4;
height: 40px;
}
And here's the relevant css, along with the animation that I have currently that works properly:
.extralinks {
position: fixed;
top: 8px;
left: 90%;
animation-name: slidey;
animation-duration: 1s;
animation-timing-function: ease;
animation-delay: 0s;
animation-iteration-count: 1;
animation-direction: normal;
animation-play-state: running;
/* Safari and Chrome */
-webkit-animation-name: slidey;
-webkit-animation-duration: 1s;
-webkit-animation-timing-function: ease;
-webkit-animation-delay: 0s;
-webkit-animation-iteration-count: 1;
-webkit-animation-direction: normal;
-webkit-animation-play-state: running;
z-index: 4;
}
#keyframes slidey {
0% {left: 90%; top: 8px;}
100% {left: 40%; top: 8px;}
}
#-webkit-keyframes slidey /* Safari and Chrome */ {
0% {left: 90%; top: 8px;}
100% {left: 40%; top: 8px;}
}
.links li:nth-child(3) {
background-color: Red;
}
markup for .extralinks
<div class="extralinks">
<ul>
<li>
link 4
</li>
<li>
link 5
</li>
</ul>
</div>
I need to make it so that when someone hovers over "link 3" the animated links slide in from the right and end next to my links. I'm not quite sure how exactly to link the animation to "link 3" in my list. Any help? I would not be opposed to using javascript/jquery, I'm just not well-versed in either.
Thank you!

I'm not exactly clear of your goals, but I made some assumptions and slapped a jsFiddle together. I used css transitions instead because I assumed it was a :hover animation and this allowed the sub menu to return to it's position.
* {
padding:0;
margin:0;
}
.links {
width:100%;
}
.links > menu {
width:100%;
text-align:center;
}
.links menu li {
display: inline-block;
position:relative;
padding:0.75em 1em;
}
.l3 .extralinks {
position:absolute;
top:2em;
left:100%;
z-index: 4;
-webkit-transition:all 1s ease-in-out 0s;
-moz-transition:all 1s ease-in-out 0s;
-o-transition:all 1s ease-in-out 0s;
-ms-transition:all 1s ease-in-out 0s;
transition:all 1s ease-in-out 0s;
}
.l3:hover .extralinks {
left:0;
}
.l3:hover .extralinks li {
display:block;
}
.links li:nth-child(3) {
background-color: Red;
}
<div class="links">
<menu>
<li>
link 1
</li>
<li>
link 2
</li>
<li class="l3">
link 3
<menu class="extralinks">
<li>
link 4
</li>
<li>
link 5
</li>
</menu>
</li>
</menu>
</div>

Related

HTML CSS/JS Bottom navbar Sliding Up

I've done some research and it doesn't seem that I can find exactly what I'm looking for. My goal is to have a navigation bar on the bottom of my JS-app and when a user clicks a certain button, it would start an animation where the navbar travels from the bottom of the app to the top of the app. Here's some edits I made to illustrate what I mean:
default position
after user presses "profile" button, for example
Not sure what JS library would help me with this or if there is a code-sample. The key here is that I dont want it to shift on any button clicked, only certain ones. For example, if the user clicks on "Library" from my example above, I want it to stay on the bottom.
Might anyone know how I can accomplish this?
EDIT: so the reason im doing this is because this is an electron app that i want some content to be local, and some content to be remote. This is why when the users presses "Library" i would want the navbar to remain stationary. However if the user presses "Profile" it would shift to the top and the "content" window would act sort of like a web-browser in that it would load a page on a remote webserver. I hope that helps. And thanks for all the info!
EDIT 2: A little off-topic, but i get this weird padding that im not sure where is coming from:
weird space
EDIT 3:
Heres the HTML and CSS:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript" src="renderer.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
<link rel="stylesheet" href="styles.css">
<body>
<script>
function toggleNavLocation() {
//alert('clciiikkkked');
$('nav').toggleClass('top');
}
</script>
<nav>
<div id="logo_container"><img id="logo"
src="./assets/images/poscon_nav.jpg" width="100px" height="55px" /></div>
<div id="navitems">
<ul>
<li id="dashboard">DASHBOARD</li>
<li id="pilotclient">PILOT CLIENT</li>
<li id="livemap">LIVE MAP</li>
<li id="community">COMMUNITY</li>
<li id="profile" onclick="toggleNavLocation()">PROFILE</li>
<li id="training">TRAINING</li>
<li id="support">SUPPORT</li>
<li id="library">LIBRARY</li>
</ul>
</div>
</nav>
<div id="right_content">
<div id="user_pane">
<span id="username"></span>
</div>
</div>
<div id="center_content">
</div>
<div id="left_content">
</div>
</body>
</html>
CSS:
body {
font-family: "Arial", Serif;
background-color: rgb(27, 27, 27);
overflow-x: hidden;
overflow-y: hidden;
}
nav {
position: absolute;
bottom: 0;
left: 0;
width:850;
height:75px;
background: rgb(27, 27, 80);
-webkit-transition: all 1s ease;
-moz-transition: all 1s ease;
-o-transition: all 1s ease;
-ms-transition: all 1s ease;
transition: all 1s ease;
}
nav.top {
bottom:calc(100% - 50px);
-webkit-transition: all 1s ease;
-moz-transition: all 1s ease;
-o-transition: all 1s ease;
-ms-transition: all 1s ease;
transition: all 1s ease;
}
#dashboard, #pilotclient, #livemap, #community, #profile, #training,
#support, #library, #search_img {
font-size: 11px;
color: rgb(81, 81, 81);
padding-top: 22px;
display: inline-block;
width: 75px;
height:75px;
background:rgb(27, 27, 27);
text-align:center;
}
#dashboard:hover, #pilotclient:hover, #livemap:hover, #community:hover,
#profile:hover, #training:hover, #support:hover, #library:hover {
background: #252525;
}
#logo_container {
display: inline-block;
position: absolute;
left: 10px;
bottom: 2px;
}
#navitems {
display: inline-block;
margin-left: 150px;
height: 100px;
}
#right_content {
width: 250px;
height: 575px;
position: absolute;
top: 0px;
right: 0px;
background-color: red;
}
#center_content {
width: 500px;
height: 575px;
position:absolute;
top: 0px;
right: 250px;
background-color: blue;
}
#left_content {
width: 250px;
height: 575px;
position:absolute;
top: 0px;
left: 0px;
background-color: green;
}
#user_pane {
width: 250px;
height: 250px;
position: absolute;
top: 0px;
right: 0px;
background-color: green;
}
#username {
width: 200px;
height: 25px;
position: absolute;
top: 175px;
left: 20px;
text-align: center;
background-color: white;
}
You can use some JS to add a class to your nav bar to do the animation, and you can add this class when clicking on a button with specific IDs.
Below is a snippet that demonstrates this:
$('#profile').on('click', function(){
toggleNavLocation();
});
function toggleNavLocation() {
$('nav').toggleClass('top');
}
nav {
width:100vw;
height:50px;
background:#000;
bottom: 0;
color:#fff;
-webkit-transition: all 1s ease;
-moz-transition: all 1s ease;
-o-transition: all 1s ease;
-ms-transition: all 1s ease;
transition: all 1s ease;
position: absolute;
}
nav.top {
bottom:calc(100% - 50px);
-webkit-transition: all 1s ease;
-moz-transition: all 1s ease;
-o-transition: all 1s ease;
-ms-transition: all 1s ease;
transition: all 1s ease;
}
li {
display:inline-block;
width:100px;
height:25px;
background:rgba(255,255,255,0.2);
text-align:center;
line-height:25px;
cursor:pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<nav>
<ul>
<li id="profile">Profile</li>
<li id="library">Library</li>
</ul>
</nav>
</body>
</html>
If you don't want it to animate, but just jump to top or bottom, then you can remove all of these lines:
-webkit-transition: all 1s ease;
-moz-transition: all 1s ease;
-o-transition: all 1s ease;
-ms-transition: all 1s ease;
transition: all 1s ease;
Here is a snippet demonstrating this:
$('#profile').on('click', function(){
toggleNavLocation();
});
function toggleNavLocation() {
$('nav').toggleClass('top');
}
nav {
width:100vw;
height:50px;
background:#000;
bottom: 0;
color:#fff;
position: absolute;
}
nav.top {
bottom:calc(100% - 50px);
}
li {
display:inline-block;
width:100px;
height:25px;
background:rgba(255,255,255,0.2);
text-align:center;
line-height:25px;
cursor:pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<nav>
<ul>
<li id="profile">Profile</li>
<li id="library">Library</li>
</ul>
</nav>
</body>
</html>
These examples us some JQuery, but if you want pure JS, you should be able to port it over to Vanilla with a bit of thought put into the code I have supplied.
It seems pretty straight forward but we need to know which property did you use to position the navbar at the bottom?. Best solution would be to create two css Properties of different properties in flexbox behavior then just use JavaScript to change the nav id corresponding the properties when the profile is clicked.
You can animate the navbar to slide between 2 vertical positions with css as such:-
#keyframes animatebottom {
from {
bottom: -300px;
opacity: 0
}
to {
bottom: 0;
opacity: 1
}
}
Modify the "bottom" property to suit your page height and other requirements.

Jumping dots animation

So let's say I have three dots as spans inside a parent element.
I need to create a parent hover animation that will make the dots jump one by one with delay. I accomplished this without hover but I need the animation to work when I hover the parent element. At the moment when I hover the parent element no delay is applied to the children.
.dots-cont {
position: absolute;
right: 0px;
bottom: 0px;
}
.dot {
width: 12px;
height: 12px;
background: #22303e;
display: inline-block;
border-radius: 50%;
right: 0px;
bottom: 0px;
margin: 0px 2.5px;
position: relative;
}
.dots-cont:hover > .dot {
position: relative;
bottom: 0px;
animation: jump 1s infinite;
}
.dots-cont .dot-1{
-webkit-animation-delay: 100ms;
animation-delay: 100ms;
}
.dots-cont .dot-2{
-webkit-animation-delay: 200ms;
animation-delay: 200ms;
}
.dots-cont .dot-3{
-webkit-animation-delay: 300ms;
animation-delay: 300ms;
}
#keyframes jump {
0% {bottom: 0px;}
20% {bottom: 5px;}
40% {bottom: 0px;}
}
<span class="dots-cont">
<span class="dot dot-1"></span>
<span class="dot dot-2"></span>
<span class="dot dot-3"></span>
</span>
You just need to add the animation property to .dot base instead of the :hover version. This way, you will get the same behavior no matter what. You can add any properties you want to the hover class, like changing the color.
.dots {
animation: jump 1s infinite;
}
https://jsfiddle.net/3gampq0b/5/
EDIT: To prevent animation on dot hover.
.dots-cont:hover > .dot {
animation: none;
}
https://jsfiddle.net/3gampq0b/6/
EDIT: Only animate on parent hover.
You can also add padding to the .dots-cont so the hover surface area is greater.
.dots-cont:hover > * {
animation: jump 1s infinite;
}
https://jsfiddle.net/3gampq0b/7/
By Using "animation: jump 1s infinite;" directly, you are overriding the animation-delay property for .dot elements.
Try Below snippet, see if this is what you are trying to do:
.dots-cont{
position: absolute;
left: 100px;
top: 100px;
}
.dot{
width: 12px;
height: 12px;
background: #22303e;
display: inline-block;
border-radius: 50%;
right: 0px;
bottom: 0px;
margin: 0px 2.5px;
position: relative;
}
.dots-cont:hover > .dot {
position: relative;
bottom: 0px;
animation-name: jump;
animation-duration: .3s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-timing-function: ease;
}
.dots-cont .dot-1{
-webkit-animation-delay: 100ms;
animation-delay: 100ms;
}
.dots-cont .dot-2{
-webkit-animation-delay: 200ms;
animation-delay: 200ms;
}
.dots-cont .dot-3{
-webkit-animation-delay: 300ms;
animation-delay: 300ms;
}
#keyframes jump {
from {bottom: 0px}
to {bottom: 20px}
}
#-webkit-keyframes jump {
from {bottom: 0px}
to {bottom: 10px}
}
<span class="dots-cont">
<span class="dot dot-1"></span>
<span class="dot dot-2"></span>
<span class="dot dot-3"></span>
</span>
I changed
.dots-cont:hover > .dot {
position: relative;
bottom: 0px;
animation: jump 1s infinite;
}
to
.anim .dot {...}
Then i add and remove anim class with jQuery.

Keep css animation appearing after unhovering state

I have a div. When I hover into this div, 3 circles should pop in using css animation. But they disappear, when I move the mouse away from the div. How can I make them stay without using jquery? Here is my code:
.circle {
width: 50px;
height: 50px;
border-radius: 50px;
background-color: blue;
list-style: none;
opacity: 0;
transform: scale(0);
}
.circles li {
margin-top: 10px;
}
.hoverover:hover + .circles .circle {
animation: popin .25s forwards;
}
#keyframes popin {
80% {
transform: scale(1.15);
}
100% {
opacity: 1;
transform: scale(1);
}
}
<div class="hoverover">Hover Over Me</div>
<ul class="circles">
<li class="circle"></li>
<li class="circle"></li>
<li class="circle"></li>
</ul>
To make the circles stay as long as the .hoverover element or they are hovered you need to insert the .circles container into .hoverover, and make some changes to the way .circles behave when hovered, and not hovered:
.circles {
margin: 0;
padding: 15px;
}
.hoverover {
display: inline-block; /** limit it to the size and height of the text **/
height: 20px;
}
.hoverover:not(:hover) > .circles { /** prevent opening circles by hovering it when invisible **/
pointer-events: none;
}
.circle {
width: 50px;
height: 50px;
border-radius: 50px;
background-color: blue;
margin-top: 10px;
list-style: none;
opacity: 0;
transform: scale(0);
}
.hoverover:hover .circle {
animation: popin .25s forwards;
}
#keyframes popin {
80% {
transform: scale(1.15);
}
100% {
opacity: 1;
transform: scale(1);
}
}
<div class="hoverover">
<span>Hover Over Me</span>
<ul class="circles">
<li class="circle"></li>
<li class="circle"></li>
<li class="circle"></li>
</ul>
</div>
Previous answer:
When the .hoverover element is hovered, it applies the animation animation: popin .25s forwards; to the .circle elements. When the hover ends the animation is removed, and the element disappears.
To solve that start the animation paused on the .circle, and "resume" it when .hoverover is hovered:
.circle {
width: 50px;
height: 50px;
border-radius: 50px;
background-color: blue;
list-style: none;
opacity: 0;
transform: scale(0);
animation: popin .25s forwards;
animation-play-state: paused;
}
.circles li {
margin-top: 10px;
}
.hoverover:hover + .circles .circle {
animation-play-state: running;
}
#keyframes popin {
80% {
transform: scale(1.15);
}
100% {
opacity: 1;
transform: scale(1);
}
}
<div class="hoverover">Hover Over Me</div>
<ul class="circles">
<li class="circle"></li>
<li class="circle"></li>
<li class="circle"></li>
</ul>
You only need to pause animation with
-webkit-animation-play-state: paused; /* Chrome, Safari, Opera */
animation-play-state: paused;
And run it again on hover
-webkit-animation-play-state: running; /* Chrome, Safari, Opera */
animation-play-state: running;
<html>
<div class="hoverover">Hover Over Me</div>
<ul class="circles">
<li class="circle"></li>
<li class="circle"></li>
<li class="circle"></li>
</ul>
<style>
.circle {
width: 50px;
height: 50px;
border-radius: 50px;
background-color: blue;
list-style: none;
opacity: 0;
transform: scale(0);
}
.circles li {
margin-top: 10px;
}
.circles .circle{
animation: popin .25s forwards;
-webkit-animation-play-state: paused; /* Chrome, Safari, Opera */
animation-play-state: paused;
}
.hoverover:hover + .circles .circle {
-webkit-animation-play-state: running; /* Chrome, Safari, Opera */
animation-play-state: running;
}
#keyframes popin {
80% {
transform: scale(1.15);
}
100% {
opacity: 1;
transform: scale(1);
}
}
</style>
</html>

How to animate an element's max-height from bottom to top?

I have an HTML menu element that I am currently animating using javascript and CSS. The menu's max-height is set to 0, with overflow: hidden.
<div class="menu">
The current CSS animation:
.menu {
-webkit-transition: max-height 0.4s ease;
-moz-transition: max-height 0.4s ease;
transition: max-height 0.4s ease;
}
In javascript, I am changing the menu max-height when a button is clicked.
This all works fine, except I would like to reveal the menu from the bottom to the top, instead of the top-down. Can this be done in simple CSS or JS?
You can transition scaleY() instead, and use transform-origin
div {
transform-origin: 0 100%;
width: 100px;
height: 100px;
background: black;
transition: transform .5s;
transform: scaleY(0);
}
body:hover div {
transform: scaleY(1);
}
<div></div>
Michael already provided a very elegant solution but it has the problem of scaling all content.
I just want to provide another approach: When using position:absolute, you can set bottom:0 to make it reveal from the bottom. I used height in the demo, because it's a bit easier to get the dimension how you want them, but max-height generally works just as fine as well.
Advantage: content does not scale
Disadvantage: needs positioning and some fixed height declarations
Whatever works best for you.
.menu {
background:#bada55;
transition: all 0.4s ease;
height:0;
overflow:hidden;
position:absolute;
bottom:0;
width:100%;
}
.container:hover .menu {
height:30px;
}
.container{
position:relative;
border:1px solid red;
height:30px;
}
<div class="container">
<div class="menu">
Menu content
</div>
</div>
Another possibility is to simply animate the positioning. Here you just manipulate the top to achieve the sliding effect.
.menu {
background: #bada55;
transition: all 0.4s ease;
overflow: hidden;
position: relative;
width: 100%;
padding:10px;
height:40px;
box-sizing:border-box;
top:100%;
}
.container:hover .menu {
top:0;
}
.container {
border: 1px solid red;
overflow:hidden;
height:40px;
}
<div class="container">
<div class="menu">
Menu content
</div>
</div>
You could use flexbox. You would need to align it to the bottom using align-items: flex-end;.
var btn = document.querySelector('button');
btn.addEventListener('click', function(){
document.querySelector('.menu').classList.toggle('active');
});
.menu {
max-height: 0;
overflow: hidden;
-webkit-transition: max-height 1s ease;
-moz-transition: max-height 1s ease;
transition: max-height 1s ease;
background: #eee;
display: flex;
align-items: flex-end;
}
.menu.active {
max-height: 300px;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
width: 100%;
}
ul li {
}
<button>Toggle Menu</button>
<div class="menu">
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4 (last item)</li>
</ul>
</div>
For reference, here is how the menu works without the flexbox aligning:
var btn = document.querySelector('button');
btn.addEventListener('click', function(){
document.querySelector('.menu').classList.toggle('active');
});
.menu {
max-height: 0;
overflow: hidden;
-webkit-transition: max-height 1s ease;
-moz-transition: max-height 1s ease;
transition: max-height 1s ease;
background: #eee;
}
.menu.active {
max-height: 300px;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
ul li {
}
<button>Toggle Menu</button>
<div class="menu">
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4 (last item)</li>
</ul>
</div>

Animated header dissappers while scrolling upwards

I created an animated header div menu that slides down on page load. I used animation-delay to delay the animation for 1 second. When the user scrolls down the header div changes colors fine but when scrolling back up the header disappears for a split second. Please help.
$(window).scroll(function() {
if ($(this).scrollTop() > 250){
$('header').addClass("sticky");
$('a').css({
color: '#fff'
});
}
else{
$('header').removeClass("sticky");
$('a').css({
color: '#151515'
});
}
});
body{
margin:0px;
}
#content{
height:500px;
width:500px;
display:block;
background-color:pink;
margin: 0 auto;
margin-top:50px;
}
header{
position: fixed;
top: -300px;
width: 100%;
height:50px;
padding-top:25px;
text-align: center;
background: red;
z-index: 1;
font-size: .8em;
-webkit-transition: all 0.4s ease;
-moz-transition: all 0.4s ease;
transition: all 0.4s ease;
animation:theheader 1s;
-moz-animation:top theheader 1s; /* Firefox */
-webkit-animation:theheader 1s; /* Safari and Chrome */
-webkit-animation-delay: 1s; /* Chrome, Safari, Opera */
animation-delay: 1s;
animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
}
header.sticky {
height:50px;
padding-top:25px;
background-color: blue;
color: #FFF;
}
#-moz-keyframes theheader
{
from {
top: -300px;
}
to {
top:0px;
}
}
<header>
MENU
</header>
<div id="content">
</div>
<div id="content">
</div>
<div id="content">
</div>
https://jsfiddle.net/qectrqg3/35/
If you're simply animating the top value, I would recommend using transition instead of animations. Transitions will ensure you don't get a flicker when changing "animation" values in the middle of a transition.

Categories

Resources