In this snippet, using keyframes and animation and display none/block, the div animates to slide down on hover.
h1 { padding: 20px; }
div {
width: 100%; background: pink; padding: 20px;
display: none;
}
body:hover div {
display: block;
-webkit-animation: slide-down .3s ease-out;
-moz-animation: slide-down .3s ease-out;
}
#-webkit-keyframes slide-down {
0% { opacity: 0; -webkit-transform: translateY(-100%); }
100% { opacity: 1; -webkit-transform: translateY(0); }
}
#-moz-keyframes slide-down {
0% { opacity: 0; -moz-transform: translateY(-100%); }
100% { opacity: 1; -moz-transform: translateY(0); }
}
<div>Hello</div>
<h1>Hover me</h1>
How can it be made to also slide back up when hover is removed?
Try applying the transition property to the actual element:
h1 { padding: 20px; }
div {
position: absolute;
width: 100%; background: pink; padding: 20px;
visibility: hidden;
opacity: 0;
transform: translateY(0);
transition: all .3s ease-out;
}
body:hover div {
visibility: visible;
opacity: 1;
transform: translateY(100%);
}
<div>Hello</div>
<h1>hover me</h1>
Related
I use an image and three spans as siblings within a wrapper (.avatar), to display a small avatar. I added two animations. The animated elements are the spans. They are animated with a small delay.
One animation is executed immediately (#keyframes rings-load). The other one (#keyframes rings-hover) executes, when .avatar is hovered.
Problem: After hovering .avatar, leaving the element, the initial animation is triggered a second time. Why is that? What would be considered best practice to prevent this behaviour?
Expected: Animation rings-load executes once on page load and is not executed again. Animation rings-hover executes once on every hover on element with class .avatar.
/* vars */
:root {
--avatar-size: 140px;
}
/* general */
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
background: #333;
margin: 0;
padding: 0;
}
main {
display: flex;
flex-flow: column wrap;
justify-content: center;
align-content: center;
height: 100vh;
}
/* avatar */
.avatar-container {
margin: 2rem;
padding: 21px;
}
.avatar img {
width: var(--avatar-size);
height: var(--avatar-size);
border-radius: 100%;
padding: 2px;
cursor: pointer;
}
.avatar span {
border-radius: 100%;
position: absolute;
width: var(--avatar-size);
height: var(--avatar-size);
border: 1px solid #ffffffee;
background: #333;
z-index: -1;
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation: rings-load 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
animation: rings-load 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
}
.avatar span:nth-child(2) {
-webkit-animation-delay: 200ms;
animation-delay: 200ms;
}
.avatar span:nth-child(3) {
-webkit-animation-delay: 300ms;
animation-delay: 300ms;
}
.avatar:hover span {
-webkit-animation: rings-hover 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94) infinite;
animation: rings-hover 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94) infinite;
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
}
.avatar:hover span:nth-child(2) {
-webkit-animation-delay: 200ms;
animation-delay: 200ms;
}
.avatar:hover span:nth-child(3) {
-webkit-animation-delay: 300ms;
animation-delay: 300ms;
}
/* animations */
#-webkit-keyframes rings-load {
75% {
opacity: 1;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
#keyframes rings-load {
75% {
opacity: 1;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
#-webkit-keyframes rings-hover {
0% {
opacity: 0;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
50% {
opacity: 1;
}
75% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
}
#keyframes rings-hover {
0% {
opacity: 0;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
50% {
opacity: 1;
}
75% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
}
<main>
<div class="avatar-container">
<div class="avatar">
<span></span>
<span></span>
<span></span>
<img src="https://picsum.photos/140/140/?17" alt="Avatar Books" />
</div>
</div>
</main>
Your hover resets the base animation. Then, when you unhover, it is apllied again, so it plays again.
Instead, on hover add the new animation on top of the previous one. This will make the animation not to be reset, and the unhover won't trigger it
Alos, you can forget about webkit prefixes.
/* vars */
:root {
--avatar-size: 140px;
}
/* general */
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
background: #333;
margin: 0;
padding: 0;
}
main {
display: flex;
flex-flow: column wrap;
justify-content: center;
align-content: center;
height: 100vh;
}
/* avatar */
.avatar-container {
margin: 2rem;
padding: 21px;
}
.avatar img {
width: var(--avatar-size);
height: var(--avatar-size);
border-radius: 100%;
padding: 2px;
cursor: pointer;
}
.avatar span {
border-radius: 100%;
position: absolute;
width: var(--avatar-size);
height: var(--avatar-size);
border: 1px solid #ffffffee;
background: #333;
z-index: -1;
opacity: 0;
transform: scale(1);
animation: rings-load 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
animation-iteration-count: 1;
}
.avatar span:nth-child(2) {
animation-delay: 200ms;
}
.avatar span:nth-child(3) {
animation-delay: 300ms;
}
.avatar:hover span {
animation: rings-load 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94),
rings-hover 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94) 1;
}
.avatar:hover span:nth-child(2) {
animation-delay: 200ms;
}
.avatar:hover span:nth-child(3) {
animation-delay: 300ms;
}
/* animations */
#-webkit-keyframes rings-load {
75% {
opacity: 1;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
#keyframes rings-load {
75% {
opacity: 1;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
#-webkit-keyframes rings-hover {
0% {
opacity: 0;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
50% {
opacity: 1;
}
75% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
}
#keyframes rings-hover {
0% {
opacity: 0;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
50% {
opacity: 1;
}
75% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
}
<main>
<div class="avatar-container">
<div class="avatar">
<span></span>
<span></span>
<span></span>
<img src="https://picsum.photos/140/140/?17" alt="Avatar Books" />
</div>
</div>
</main>
I have a little problem with my CSS file. I try to make an icon that scale to infinite (works), and when I click on icon, an animation rotate the parent to 90deg and the icon rotate to 45deg (works). But, if I combine the 2 behavior, the rotate of icon break. I want rotate the icon of 45deg, and keep the animation.
A demo example: https://codepen.io/KevinPy/pen/ooEbKY?editors=1100
In my demo, the first occurence works with the rotate to 45deg. The second occurence add the animation (via class), but the rotate is break.
Thank you for your answers.
HTML
<div id="first"><span>+</span></div>
<div id="second"><span class="anim">+</span></div>
SCSS
div {
margin: 25px;
display: inline-block;
position: relative;
background-color: blue;
width: 80px;
height: 80px;
&::before {
position: absolute;
top: 20px;
left: -20px;
content: '';
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-right: 20px solid blue;
}
&.open {
transition: .2s transform linear;
transform: rotate(90deg);
span {
transition: .2s transform linear;
transform: rotate(-45deg);
}
}
&.close {
transition: .2s transform linear;
transform: rotate(0deg);
span {
transition: .2s transform linear;
transform: rotate(0deg);
}
}
}
span {
position: absolute;
top: 5px;
bottom: 0;
left: 0;
right: 0;
text-align: center;
color: white;
font-size: 60px;
}
.anim {
animation: keyAnim 3.4s linear infinite;
transform-origin: 50%;
}
#keyframes keyAnim {
0%, 100% {
transform: scale(1);
}
35%, 65% {
transform: scale(1.2);
}
50% {
transform: scale(1.5);
}
}
Your animation overrides the transform attribute. You could add a surrounding element:
var first = document.querySelector('#first');
first.onclick = function(event) {
if (first.classList.contains('open')) {
first.classList.remove('open');
first.classList.add('close');
} else {
first.classList.add('open');
first.classList.remove('close');
}
};
var second = document.querySelector('#second');
second.onclick = function(event) {
if (second.classList.contains('open')) {
second.classList.remove('open');
second.classList.add('close');
} else {
second.classList.add('open');
second.classList.remove('close');
}
};
div {
margin: 25px;
display: inline-block;
position: relative;
background-color: blue;
width: 80px;
height: 80px;
}
div::before {
position: absolute;
top: 20px;
left: -20px;
content: '';
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-right: 20px solid blue;
}
div.open {
-webkit-transition: .2s transform linear;
transition: .2s transform linear;
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
}
div.open .anim_wrap {
-webkit-transition: .2s transform linear;
transition: .2s transform linear;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
div.close {
-webkit-transition: .2s transform linear;
transition: .2s transform linear;
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
div.close .anim_wrap {
-webkit-transition: .2s transform linear;
transition: .2s transform linear;
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
span {
position: absolute;
top: 5px;
bottom: 0;
left: 0;
right: 0;
text-align: center;
color: white;
font-size: 60px;
}
.anim {
-webkit-animation: keyAnim 3.4s linear infinite;
animation: keyAnim 3.4s linear infinite;
-webkit-transform-origin: 50%;
transform-origin: 50%;
}
#-webkit-keyframes keyAnim {
0%, 100% {
-webkit-transform: scale(1);
transform: scale(1);
}
35%, 65% {
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
50% {
-webkit-transform: scale(1.5);
transform: scale(1.5);
}
}
#keyframes keyAnim {
0%, 100% {
-webkit-transform: scale(1);
transform: scale(1);
}
35%, 65% {
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
50% {
-webkit-transform: scale(1.5);
transform: scale(1.5);
}
}
<div id="first"><span class="anim_wrap">+</span></div>
<div id="second"><span class="anim_wrap"><span class="anim">+</span></span></div>
I have titles that I want to add CSS3 animation to it
I want to transform
Title
to
[Title]
And I want the square brackets to animate from the center of the word to the borders of it with animation.
something like..
Ti[]tle
to
[Title]
with animation (ofcourse i'm using :before :after to add the brackets with opacity 0 to 1)
my p style:
p:before {
content: "[";
position: absolute;
left: 50%; /*to add the bracket to the center of the word*/
opacity: 0;
transition: all 0.7s ease;
}
Thank You !
p {
display: table;
position: relative;
}
p:before,
p:after{
position: absolute;
opacity: 0;
transition: all 0.7s ease;
}
p:before {
content: "[";
left: 50%;
}
p:after {
content: "]";
right: 50%;
}
p:hover:before {
left: -5px;
opacity: 1;
}
p:hover:after {
right: -5px;
opacity: 1;
}
<p>Title</p>
<p>A Longer Title</p>
Is this what you are looking for?
with this html:
<div>
TESTING
</div>
and these css's:
div{
padding: 18px 0 18px 0;
display: inline-block;
margin-right: 40px;
}
a {
color: #999;
display: inline-block;
text-align: center;
width: 200px;
text-decoration: none;
}
a:before, a:after {
display: inline-block;
opacity: 0;
-webkit-transition: -webkit-transform 0.3s, opacity 0.2s;
-moz-transition: -moz-transform 0.3s, opacity 0.2s;
transition: transform 0.3s, opacity 0.2s;
}
a:before {
margin-right: 10px;
content: '[';
-webkit-transform: translate(20px, -1px);
-moz-transform: translate(20px, -1px);
transform: translate(20px, -1px);
vertical-align: top;
}
a:after {
margin-left: 10px;
content: ']';
-webkit-transform: translate(-20px, -1px);
-moz-transform: translate(-20px, -1px);
transform: translate(-20px, -1px);
}
a:hover:after {
opacity: 1;
-webkit-transform: translate(0px, -1px);
-moz-transform: translate(0px, -1px);
transform: translate(0px, -1px);
}
a:hover:before {
opacity: 1;
-webkit-transform: translate(0px, -1px);
-moz-transform: translate(0px, -1px);
transform: translate(0px, -1px);
}
You get this JSFIDDLE
You can achieve this using frame animations. This way you won't have to hover the element (or anything else) for the animation to start.
See: http://jsfiddle.net/Paf_Sebastien/j2cvagjf/
Set :before and :after like this :
h1:before {
content: "[";
position: absolute;
display: block;
top: 0;
-webkit-animation: bracketleft 1s 1 forwards;
animation: bracketleft 1s 1 forwards;
}
Then handle the animation :
#-webkit-keyframes bracketleft {
0% { opacity: 0; left: 50%; }
100% { opacity: 1; left:-10px; }
}
#-webkit-keyframes bracketright {
0% { opacity: 0; right: 50%; }
100% { opacity: 1; right: -10px; }
}
I am trying to make a box slide in from the left of my page while in the viewport, however it's making my page too wide and I can't get it to reverse once out of the viewport once I've scrolled past it. This is what I have:
.box {
background: #2db34a;
border-radius: 6px;
cursor: pointer;
height: 95px;
line-height: 95px;
text-align: center;
transition-property: background;
transition-duration: 1s;
transition-timing-function: linear;
width: 95px;
margin-top: 500px;
}
#slide {
position: absolute;
right: -100px;
width: 100px;
height: 100px;
background: blue;
overflow: hidden;
animation: slide 0.5s forwards;
animation-delay: 1s
-webkit-animation: moveToRight .6s ease both;
animation: moveToRight .6s ease both;
-webkit-animation: moveFromRight .6s ease both;
animation: moveFromRight .6s ease both;
}
#-webkit-keyframes moveToRight {
from { }
to { -webkit-transform: translateX(100%); }
}
#keyframes moveToRight {
from { }
to { -webkit-transform: translateX(100%); transform: translateX(100%); }
}
#-webkit-keyframes moveFromRight {
from { -webkit-transform: translateX(100%); }
}
#keyframes moveFromRight {
from { -webkit-transform: translateX(100%); transform: translateX(100%); }
}
</style>
</head>
<body>
<div id="slide" class="box">Box</div>
</body>
</html>
I can't use any plug-ins to do this either.
So I want to hover over a Box and have it activate another div with easing effects. You can see below the .images{} has a 0s infinite scroll, and then .box:hover > .images{} is when I change the 0s to 10s to start the slideshow.
HTML:
<div class="slideshow">
<div class="images"></div>
<div class="box"></div>
</div>
CSS:
.slideshow {
position: relative;
overflow: hidden;
height: 220px;
width: 100%;
}
.box {
width:100px;
height:100px;
position: absolute;
left: 0;
top: 0;
background-color: #333;
}
.images {
background: url('http://jamesebeling.com/testing/jamesebeling/wp-content/uploads/2013/08/buildings.png');
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 300%;
-webkit-transition: all 1s ease-out;
-moz-transition: all 1s ease-out;
-o-transition: all 1s ease-out;
transition: all 1s ease-out;
-webkit-animation: slideshow 0s linear infinite;
-moz-animation: slideshow 0s linear infinite;
}
#-webkit-keyframes slideshow {
0% { left: 0; }
100% { left: -200%; }
}
#moz-keyframes slideshow {
0% { left: 0; }
100% { left: -200%; }
}
/* Hey browser, use your GPU */
-webkit-transform: translate3d(0, 0, 0);
}
#-webkit-keyframes moveSlideshow {
0% {
-webkit-transform: translateX(0);
}
100% {
-webkit-transform: translateX(-200%);
}
}
#-moz-keyframes moveSlideshow {
0% {
-moz-transform: translateX(0);
}
100% {
-moz-transform: translateX(-200%);
}
}
.box:hover > .images {
.images {
background: url('http://jamesebeling.com/testing/jamesebeling/wp-content/uploads/2013/08/buildings.png');
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 300%;
-webkit-transition: all 1s ease-out;
-moz-transition: all 1s ease-out;
-o-transition: all 1s ease-out;
transition: all 1s ease-out;
-webkit-animation: slideshow 10s linear infinite;
-moz-animation: slideshow 10s linear infinite;
}
#-webkit-keyframes slideshow {
0% { left: 0; }
100% { left: -200%; }
}
#moz-keyframes slideshow {
0% { left: 0; }
100% { left: -200%; }
}
/* Hey browser, use your GPU */
-webkit-transform: translate3d(0, 0, 0);
}
#-webkit-keyframes moveSlideshow {
0% {
-webkit-transform: translateX(0);
}
100% {
-webkit-transform: translateX(-200%);
}
}
#-moz-keyframes moveSlideshow {
0% {
-moz-transform: translateX(0);
}
100% {
-moz-transform: translateX(-200%);
}
}
If you change your HTML to include the box class before the images class, you can use the adjacent selector to select the .images when it's preceded by .box:hover:
.box:hover + .images { ... }
Working demo.
I also added z-index: 1 to .box so it sits on top of the images element.