I’ve been trying to solve this issue on having my .content
children appear (either be added or opacity going from 0-100%) as the current animation is going over that element if that makes sense. I tried using JS AnimationIteration Event listener
but that also didn’t work as I require multiple iterations to be made which is not what I’m looking for. Also cannot think of any way to hard code this for examples but I made a basic way of how I want my animation to appear and also the other elements showing before the animation. NOTE: IDK why height: 100%;
does not cover the entire content height including all the children.
Informal section below
Image I have 3 elements that are inside the .content
div and I have a dropdown menu that animates the background of the .content
to appear going downwards from 0% {height: 0} -> 100%: {height: 100%}
and as the animation reaches 33% I want 1st child of .content
to appear while the other 2 are still hidden and wont show until the animation reaches them / goes past them and then the child appears. I want to also make it so that if in the future I add lets say extra 5 elements I don’t have to go into the code and adjust the timings and it will automatically know when to start the child animation appearing.
I don’t have a clue if this is possible or not, or my imagination is being too much for my skill level. I’m working on a very modular website for my personal projects and this is one of the things I would love to have a part of it. If this is too much I just wont bother with this but would be awesome to see potentially some things that people can help me with to solve this.
Old Example
*{
padding: 0;
margin: 0;
font-size: 10px;
}
body{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: black;
}
.dropbtn {
width: 4rem;
height: 4rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.dropbtn i {
color: red;
scale: 1.9;
}
.dropdown {
position: relative;
display: inline-block;
}
.content {
display: none;
position: absolute;
background-color: orange;
width: 100px;
z-index: 1;
}
.dropdown:hover .content {
display: block;
height: 100%;
animation: test 2s ease-in-out;
}
.content a {
color: white;
padding: 12px 16px;
text-decoration: none;
display: block;
}
@keyframes test {
0% {
height: 0;
}
100% {
height: 100%;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Advanced Animated Dropdown Menu Prototype</title>
<link rel="stylesheet" type="text/css" href="main.css">
<link href='https://unpkg.com/[email protected]/icons/css/arrow-down-r.css' rel='stylesheet'>
</head>
<body>
<div class="dropdown">
<div class="dropbtn">
<i class="gg-arrow-down-r"></i>
</div>
<div id="content" class="content">
<a href="#">Item 1</a>
<a href="#">Item 2</a>
<a href="#">Item 3</a>
</div>
</div>
<script src="main.js" defer></script>
</body>
</html>
Updated code
Possible solution that I managed to get is this using overflow: auto
I’m happy with outcome but still would like custom animations on children of the parent and issue of 100% height
still there dont have a clue why.
*{
padding: 0;
margin: 0;
font-size: 10px;
}
body{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: black;
}
.dropbtn {
width: 4rem;
height: 4rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.dropbtn i {
color: red;
scale: 1.9;
}
.dropdown {
position: relative;
display: inline-block;
}
.content {
display: none;
position: absolute;
background-color: orange;
width: 100px;
z-index: 1;
overflow: auto;
overflow-y: hidden;
overflow-x: hidden;
}
.dropdown:hover .content {
display: block;
height: 100px;
animation: test 2s ease-in-out;
}
.content a {
color: white;
padding: 12px 16px;
text-decoration: none;
display: block;
}
@keyframes test {
0% {
height: 0;
}
100% {
height: 100px;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Advanced Animated Dropdown Menu Prototype</title>
<link rel="stylesheet" type="text/css" href="main.css">
<link href='https://unpkg.com/[email protected]/icons/css/arrow-down-r.css' rel='stylesheet'>
</head>
<body>
<div class="dropdown">
<div class="dropbtn">
<i class="gg-arrow-down-r"></i>
</div>
<div id="content" class="content">
<a href="#">Item 1</a>
<a href="#">Item 2</a>
<a href="#">Item 3</a>
</div>
</div>
<script src="main.js" defer></script>
</body>
</html>
Resources used
W3Schools as always to understand some animations but W3Schools is sapposably outdated
Element: animationiteration event(s) For animation events
I also tried ChatGPT
but I only have access to 3.5 not 4 so it was a waste of time AHAHA like always.
2
Answers
After working on this issue for over a day I have come up with a solution that doesn't match what I wanted but works as I wanted. (I will try to update my question to match the solution so people who might want this can understand better what I meant). This solution works with any number of children and the width of the dropdown scales with the span / input size as that's the intended use case on my part.
I was having an issue with loading all the code so it might not work all the time so I made this CodePen link to check out the solution if it doesn't work here.
As we don’t know the height of .content and as we can’t animate to fit-content height, here’s another way of doing similar to the second example given.
This works by putting an after pseudo element on .content, it has the height of its ‘parent’ (.content) which has the same color as the overall background (black in this instance). This pseudo element is anchored at the bottom of .content and it transitions between 100% and 0 height.
With this method you don’t have to know how many children .content has or how high they are.
Now, for the more general question of having different animations on .content’s children. For this I think you will need JS and another element instead of the pseudo element. Then use IntersectionObserver to see when the element overlaps with a child of .content.