I am having some troubles styling my div. I would like to allow overflow-y only when the height transition ends (from 80px to 100% of the parent div). If I uncoment the below "overflow-y: auto" line, the overflow-y works fine but the scroller is visible during the animation which does not look good.
.mydiv{
position: absolute;
width: 100%;
bottom: 0;
border-radius: 0 0 2px 2px;
border: solid 1px #eee;
background-color: #fff;
height: 80px;
transition: all 0.5s;
transition-timing-function: ease-in-out;
overflow: hidden;
clear: both;
}
.mydiv:hover{
height: 100%;
border-radius: 2px;
/* overflow-y: auto; !!! */
}
Edit: Sorry, I forgot to add the animation-fill-mode: forwards so it will pause on end frame and stay as long as hovered. Fixed now.
Edit 2: Added code to reverse anim on mouse out.
I think the only way you may be able to do what you are aiming for is with either css animation frames, or javascript.
CSS Animation (transition the properties that should animate through 99% of animation and only transition overflow property between final 1% of animation:
.mydiv:hover{
animation-duration: 0.5s;
animation-name: 'myAnim';
animation-iteration-count: 1;
animation-timing-function: ease-in-out;
animation-fill-mode: forwards;
}
#keyframes myAnim {
0% {
height: 80px;
border-radius: 0 0 2px 2px;
overflow: hidden;
}
99% {
height: 100%;
border-radius: 2px;
overflow: hidden;
}
100% {
height: 100%;
border-radius: 2px;
overflow: auto;
}
}
That will animate on hover, but on mouse out it will just snap back to original state. You can reverse the animation on mouse out but doing so comes with some issues that should be considered. The only way I know to play animation on mouse out with pure css is to add it to the elements default state.
The reverse animation will play on initial page load. The only workarounds I know are javascript based.
The reverse animation will play from its beginning on mouse-out even if the hover anim didn't have time to complete. This can cause a sudden snap if hovered only briefly. I think this can be addressed with css animation-fill-mode: and animation-delay: values, but I have not managed to make it work.
because of the snapping that may happen on very brief hovers, it is better to use a separate anim for mouse-out so the scrollbar doesn't flicker.
.mydiv{
position: absolute;
width: 100%;
bottom: 0;
border-radius: 0 0 2px 2px;
border: solid 1px #eee;
background-color: #fff;
height: 80px;
overflow: hidden;
clear: both;
animation-duration: 0.5s;
animation-name: 'myAnim';
animation-iteration-count: 1;
animation-timing-function: ease-in-out;
animation-fill-mode: forwards;
}
.mydiv:hover{
animation-duration: 0.5s;
animation-name: 'myAnim';
animation-iteration-count: 1;
animation-timing-function: ease-in-out;
animation-fill-mode: forwards;
}
#keyframes myAnim {
0% {
height: 80px;
border-radius: 0 0 2px 2px;
overflow: hidden;
}
99% {
height: 100%;
border-radius: 2px;
overflow: hidden;
}
100% {
height: 100%;
border-radius: 2px;
overflow: auto;
}
}
#keyframes myAnimOut {
0% {
height: 100%;
border-radius: 2px;
overflow: hidden;
}
100% {
height: 80px;
border-radius: 0 0 2px 2px;
overflow: hidden;
}
}
Related
The keyframes aren't making the block move. I'm new to using keyframes so I'm bad at it.
#block{
width: 20px;
height: 20px;
background-color: blue;
position: relative;
top: 130px;
left: 480px;
animation: block is infinite linear;
}
#keyframes block{
0%{left:480px;}
100%{left: -40px;}
}
I fixed your code using the examples on developer.mozilla.org. I hope this is the expected behavior.
animation-iteration-count: infinite; will make the animation repeat forever.
animation-name defines the identifier used in #keyframes.
animation-duration specifies how many seconds or milliseconds the animation takes to complete.
See also https://www.w3schools.com/cssref/css3_pr_animation.asp.
#block{
width: 20px;
height: 20px;
background-color: blue;
position: absolute;
top: 130px;
left: 480px;
animation-duration: 3s;
animation-name: block;
animation-iteration-count: infinite;
}
#keyframes block {
0% {
left: 480px;
}
100% {
left: -40px;
}
}
<div id="block"></div>
I've spent the past hour trying to find a way to get a sliding animation from bottom to top using only CSS. It's supposed to be a test tube with fluid filling it. (This is what I want it to look like), however during the animation it overflows around the edges at the bottom and doesn't sit flush (like this).
HTML & CSS:
.testTube #border {
width: 40px;
height: 150px;
margin-top: 15px;
background-color: white;
border: 2px solid black;
border-radius: 5px 5px 25px 25px;
position: absolute;
}
.testTube #fluidLeft {
width: 20px;
height: 100px;
margin-left: 2px;
background-color: #ff007f;
border-radius: 0% 0% 0% 25px;
position: absolute;
animation-name: fluid;
animation-direction: normal;
animation-duration: 3s;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
.testTube #fluidRight {
width: 20px;
height: 0px;
margin-left: 22px;
background-color: #ff1a8c;
border-radius: 0% 0% 25px 0%;
position: absolute;
animation-name: fluid;
animation-direction: normal;
animation-duration: 3s;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
#keyframes fluid {
from {
height: 0px;
margin-top: 167px;
}
to {
height: 100px;
margin-top: 67px;
}
}
<div class="testTube">
<div id="border"></div>
<div id="fluidLeft"></div>
<div id="fluidRight"></div>
</div>
You can move the #fluidLeft and #fluidRight divs into the #border div. That way, you can add "overflow: hidden" on to the border div (now the parent) which will make it so the fluid divs (now children of the border div) don't overlap outside of the border. I also tweaked the "margin-left" on the fluids by 2px so it was centered in the tube.
.testTube #border {
width: 40px;
height: 150px;
margin-top: 15px;
background-color: white;
border: 2px solid black;
border-radius: 5px 5px 25px 25px;
position: absolute;
overflow: hidden;
}
.testTube #fluidLeft {
width: 20px;
height: 100px;
background-color: #ff007f;
border-radius: 0% 0% 0% 25px;
position: absolute;
animation-name: fluid;
animation-direction: normal;
animation-duration: 3s;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
.testTube #fluidRight {
width: 20px;
height: 0px;
margin-left: 20px;
background-color: #ff1a8c;
border-radius: 0% 0% 25px 0%;
position: absolute;
animation-name: fluid;
animation-direction: normal;
animation-duration: 3s;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
#keyframes fluid {
from {
height: 0px;
margin-top: 167px;
}
to {
height: 100px;
margin-top: 67px;
}
}
<div class="testTube">
<div id="border">
<div id="fluidLeft"></div>
<div id="fluidRight"></div>
</div>
</div>
Alright, here's what I have a nifty little scroller (they've been done to death but I wanted to take my hand at making one) and I want it to scroll to the left for X amount of pixels, which is no problem. The problem is, if the user hovers over the left side and starts scrolling the text back, I want it to stop at its initial starting point.
body {
background-color: black;
}
.wrapper {
position: absolute;
left: 50%;
margin-left: -250px;
overflow: hidden;
width: 500px;
height: 300px;
z-index: 98;
border: 3px solid 2a3439;
background-color: #353839;
}
.scroller {
color: white;
width: 1980px;
background-color: transparent;
height: 100%;
position: relative;
padding: 5px;
margin-left: 0px;
transition: all 2s linear 10s;
-moz-transition: all 2s linear 10s;
-webkit-transition: all 2s linear 10s;
}
.go-left:hover~.scroller {
margin-left: -250px;
transition: all 2s linear;
-moz-transition: all 2s linear;
-webkit-transition: all 2s linear ;
}
.go-left {
opacity: 0;
height: 300px;
background-color: red;
width: 200px;
z-index: 99;
position: absolute;
top: 0;
}
.go-right {
opacity: 0;
height: 300px;
background-color: red;
width: 200px;
z-index: 99;
position: absolute;
top: 0;
left: 300px
}
.go-right:hover+.scroller {
margin-left: 250px;
transition: all 2s linear;
-moz-transition: all 2s linear;
-webkit-transition: all 2s linear;
}
.image {
display: block;
overflow: hidden;
Height: 490px;
}
In that example, if you hover to the left I don't want it to move past it's starting point, so clamping it. You can see the working model on jsfiddle https://jsfiddle.net/Kaanha/puy6t4og/51/
This wouldn't be hard using some java, but the main thing here is, I need it to be pure CSS only. No java.
Thanks in advance for all help!
Demo on CodePen
<pre>
.parent
border: 1px solid tomato
height: 300px
margin: 0 auto
margin-top: 30px
width: 80%
.box
width: 50px
height: 50px
position: absolute
animation-name: falling
animation-iteration-count: infinite
.box-1
background-color: lightblue
right: 60vw
animation-duration: 6s
#keyframes falling
0%
top: -10vh
100%
top: 90vh
.box-2
background-color: lightgreen
right: 70vw
animation-duration: 8s
#keyframes falling
0%
top: -10vh
100%
top: 90vh
</pre>
As you can see in the demo, the animation speed of the cube is slowing down the closer it gets to the bottom.
I'd like to make animation the same speed during the fall.
Thank you.
The default animation-timing-function in CSS is ease - accelerate in the start, slow after the middle. You need a linear timing function, that has a constant speed.
Change the box timing function to linear (pen):
.box
width: 50px
height: 50px
position: absolute
animation-name: falling
animation-iteration-count: infinite
animation-timing-function: linear
You can use animation function linear. Have a look at the snippet below:
.parent {
border: 1px solid tomato;
height: 300px;
margin: 0 auto;
margin-top: 30px;
width: 80%;
}
.box {
width: 50px;
height: 50px;
position: absolute;
animation-name: falling;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
.box-1 {
background-color: lightblue;
right: 60vw;
animation-duration: 6s;
}
#keyframes falling {
0% {
top: -10vh;
}
100% {
top: 90vh;
}
}
.box-2 {
background-color: lightgreen;
right: 70vw;
animation-duration: 8s;
}
#keyframes falling {
0% {
top: -10vh;
}
100% {
top: 90vh;
}
}
<div class="parent">
<div class="box box-1"></div>
<div class="box box-2"></div>
</div>
Hope this helps!
Here's the CodePen.
The square changes to a circle as expected when it slides to the right, but when it returns back to the left, it stays a circle instead of changing to a square.
Also, I can only click the <a> once. If I try to click multiple times, it doesn't work.
Trying to do this with only CSS (if possible).
body {
margin-top: 30px;
background: gainsboro;
}
.container {
margin: auto;
width: 100%;
}
.path {
position: relative;
overflow: hidden;
width: 100%;
height: 80px;
x-background: white;
}
#keyframes ani {
0% {
left: 0;
}
50% {
left: 95%;
}
100% {
left: 0;
}
}
.shape:target {
border-radius: 50%;
transition: all .7s ease-in-out;
animation-name: ani;
animation-duration: 2s;
animation-direction: alternate;
animation-fill-mode: none;
}
.shape {
position: absolute;
left: 0;
background-color: slateblue;
width: 80px;
height: 80px;
display: block;
border-radius: none;
transition: border-radius .4s ease-out;
}
<div class="container">
<div class="path">
<span id="elem" class="shape"></span>
</div>
</div>
The closest you can get with just CSS is this, as far as I know:
body {
margin-top: 30px;
background: gainsboro;
}
.container {
margin: auto;
width: 100%;
}
.path {
position: relative;
overflow: hidden;
width: 100%;
height: 80px;
x-background: white;
}
#keyframes ani {
0% {
left: 0;
}
50% {
left: 95%;
}
100% {
left: 0;
}
}
.path a:focus .shape {
border-radius: 50%;
transition: all .7s ease-in-out;
animation-name: ani;
animation-duration: 2s;
animation-direction: alternate;
animation-fill-mode: none;
}
.shape {
position: absolute;
left: 0;
background-color: slateblue;
width: 80px;
height: 80px;
display: block;
border-radius: none;
transition: border-radius .4s ease-out;
}
<div class="container">
<div class="path">
<span id="elem" class="shape"></span>
</div>
</div>
The problem before was triggering the state with :target:. This is tough to debug with sites like Codepen or other embedded editors, since you can't see the hash change. Basically, clicking the link would append #elem to the URL, apply the :target styles to .shape, and stay like that until the hash changes.
This solution uses :focus, which gets you closer to your goal, but not all the way. To repeat the animation, you need to defocus/blur the circle, then click it again.
I'm usually all for CSS-only effects, but I'm pretty sure you'll need Javascript for this. Something as simple as applying a class on click, waiting 2 seconds, then removing the class would accomplish the same effect more reliably.