I want to achieve a simple animation on hover in CSS, but while hovering off, the animation jumps/flicking and makes it look silly. Is there a way to avoid that? I want the dropdown image to disappear and the tag to slide back to its original place.
.elementor-widget-wp-widget-woocommerce_product_categories .product-categories li > a:before {
background: url("/dropdown.svg") no-repeat center/contain;
content: "";
border: none;
display: inline-block;
height: 1em;
opacity: 0;
transform: rotate(-90deg);
transition-property: margin,opacity;
width: 1em;
}
.elementor-widget-wp-widget-woocommerce_product_categories .product-categories li > a:hover::before {
opacity: 1;
transition: .3s ease all;
}
.product-categories li > a:hover{
margin-left: 30px;
}
.elementor-widget-wp-widget-woocommerce_product_categories .product-categories li a:after {
content: none;
}
Always use transform: instead of margin for css animations, they don't change the occupied space.
For example your code here should be:
.elementor-widget-wp-widget-woocommerce_product_categories .product-categories li > a:before {
transform: translateX(0px) rotate(-90deg);
transition-property: transform,opacity;
}
.product-categories li > a:hover{
transform: translateX(-30px) rotate(-90deg);
}
We keep the rotate property the same in both as I assume you don't want that to change in this instance.
Related
Please view this code jsfiddle:
http://jsfiddle.net/rflfn/6wCp6/
<div id="menu">
<ul>
<li>Link #1</li>
<li>Link #2</li>
<li>Link #3</li>
<li>Link #4</li>
</ul>
</div>
CSS:
*{
margin: 0;
padding: 0;
text-decoration: none;
font-family: arial;
font-size: 16px;
}
a{
color: #000000;
}
a:hover{
color: #860000;
}
#menu{
margin: 15px auto;
padding: 20px;
width: 300px;
background: #DDDDDD;
border-radius: 5px;
box-shadow: 0 0 5px #000000;
}
#menu ul{
list-style: none;
}
#menu li:before{
margin-right: 10px;
content: url("http://st.deviantart.net/emoticons/s/smile.gif");
transition: all 0.5s ease 0s;
/* transition: content 0.5s ease 0s; */
}
#menu li:hover:before{
content: url("http://st.deviantart.net/emoticons/r/razz.gif");
}
I have one image on tag 'li' and other image on 'li:hover', is possible make transition with fade only using css?
You can do this by using both pseudo elements :before/after and using the CSS3 transition to animate the opacity of both on hover. This will create a fade transition between both images.
DEMO
CSS :
*{
margin: 0;
padding: 0;
text-decoration: none;
font-family: arial;
font-size: 16px;
}
a{
color: #000000;
}
a:hover{
color: #860000;
}
#menu{
margin: 15px auto;
padding: 20px;
width: 300px;
background: #DDDDDD;
border-radius: 5px;
box-shadow: 0 0 5px #000000;
}
#menu ul{
list-style: none;
}
#menu ul li{
position:relative;
}
#menu li:before{
margin-right: 10px;
content: url("http://st.deviantart.net/emoticons/s/smile.gif");
transition: opacity 0.5s ease;
-webkit-transition: opacity 0.5s ease;
}
#menu li:after{
content: url("http://st.deviantart.net/emoticons/r/razz.gif");
position:absolute;
left:0;
opacity:0;
transition: opacity 0.5s ease;
-webkit-transition: opacity 0.5s ease;
}
#menu li:hover:after{
opacity:1;
}
#menu li:hover:before{
opacity:0;
}
EDIT :
Even better, you can position both images one on top of the other and with z-index and css transition animate the opacity of ony one image :
DEMO
Your case in particular
Not sure why're you trying to put images in content,
you could simply add that image as a background-image to the :before,
set it size & display: inline-block; and you would just animate the background-image like so: http://jsfiddle.net/7f695m1q/ , since background-image transition is supported :)
TL;DR: Can content CSS property be animated? No.
MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
OUTDATED w3.org official document: https://www.w3.org/TR/2017/WD-css-transitions-1-20171130/#animatable-css
This may however change in future because this list is missing in current official sources:
missing in working draft https://www.w3.org/TR/css-transitions-1/
missing in editor's draft https://drafts.csswg.org/css-transitions/
So in theory there is a possibility this list will be updated and changes made in future browser versions, but currently it doesn't work.
Is content affected by other animations? Yes.
Content not being animatable in itself doesn't mean it's not affected by other animations like opacity, visibility etc. It can be leveraged in at least 2 simple ways:
a) answer by #web-tiki provides a smooth&always visible fade effect, however, you have to sacrifce both :after and :before to it
b) if fadeOut => fadeIn is an option for you you can levarage CSS animations & #keyframes
#keyframes changeContent {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
content: "See? I've changed seemlessly!";
}
}
div:before{
content: "HOVER OVER ME!";
background: green;
transition: all 1s linear;
animation-direction: reverse;
}
div:hover:before{
animation-fill-mode: forwards;
animation: changeContent 3s linear forwards;
background: orange;
}
<div />
Important here is to put the "forward" - it's an animation fill mode that basically says "stop the animation at it's end", otherwise it'd jump back.
There is also one drawback - it's not easily animatable on hover-out - if I find some reasonable way I will edit this answer or please comment if you know.
I think #web-tiki 's answer suits your needs and it's simpler. But just to show another possible solution:
You can separate the icons in two elements, each with its own content. Then, apply the transition on the li:hover event, setting the element's opacity inverted. Like this example:
FIDDLE: http://jsfiddle.net/2J7b9/1/
<ul>
<li>
<div class="img1"></div>
<div class="img2"></div>
test
</li>
</ul>
CSS:
li {
position: relative;
padding-left: 30px;
}
li .img1, li .img2 {
position: absolute;
top: 0;
left: 0;
}
li .img1 {
opacity: 1;
transition: all .25s ease-in-out;
}
li .img2 {
opacity: 0;
transition: all .25s ease-in-out;
}
li .img1:before {
content: url("http://st.deviantart.net/emoticons/s/smile.gif");;
}
li .img2:before {
content: url("http://st.deviantart.net/emoticons/r/razz.gif");
}
li:hover .img1 {
opacity: 0;
}
li:hover .img2 {
opacity: 1;
}
I'm trying to have a span appear from the bottom by css I wrote the following code that'snot working,
span {
display: inline !important;
background-color: transparent !important;
overflow: hidden;
animation: from-btm 1s !important;
#keyframes from-btm {
from {
margin-bottom: -5%;
}
to {
margin-bottom: 0%;
}
}
}
Use position: relative and bottom for the animation positioning (margin-bottom won't apply to an inline element). The overflow: hidden needs to be on a parent container and the keyframes rule needs to be outside the CSS rule for the span:
span {
position: relative;
display: inline !important;
background-color: transparent !important;
animation: from-btm 1s !important;
}
#keyframes from-btm {
from {
bottom: -80%;
}
to {
bottom: 0%;
}
}
.container {
background: yellow;
overflow: hidden;
}
<div class="container">
<span>The Span</span>
</div>
There are two issues in your code. First, the span has to be inline-block secondly keyframes are to be declared outside span selector in CSS.
span {
display: inline-block !important;
background-color: transparent !important;
overflow: hidden;
animation: from-btm 1s !important;
}
#keyframes from-btm {
from {
margin-bottom: -5%;
}
to {
margin-bottom: 0%;
}
}
<span>ABCD</span>
Working Fiddle code
You need to write your keyframe outside of your style. It should be like that:
span {
display: inline !important;
background-color: transparent !important;
overflow: hidden;
animation: from-btm 1s !important;
}
#keyframes from-btn {
0% {
margin-bottom: -5%;
}
100% {
margin-bottom: 0%;
}
}
Your #keyframes property should be outside the span element. It should stay outside the span element because it is it's own element. Like This:
span {
display: inline !important;
background-color: transparent !important;
overflow: hidden;
animation: from-btn 1s ease 0s 1;
}
#keyframes from-btm {
from {
margin-bottom: -5%;
}
to {
margin-bottom: 0%;
}
}
Also you animation shorthand is not "that properly written" it should be animation: "animation-name" "animation-duration" "animation-display(ease, ease-in, ease-out, linear)" "animation-delay" animation-count(any number or even infinite); as seen above.
Also for performance reasons you should consider animate the position using the transform element like this: eg.
#keyframes from-btm {
from {
transform: translateY(200%);
}
to {
transform: translateY(10%);
}
}
Also when using transform make sure to add a position propery to your element span for example position: absolute or position: relative
I'm a developer so CSS isn't my strong point and animations definitely not so.
However, I'm trying to create a simple animation - which now works to some degree - just not how I need it to:
&:before
{
background-color:rgba(255,255,255,0.3);
height:100%;
transform:scale(0);
width:100%;
}
&:hover, &:focus, &:active
{
&::before
{
.animation(ripple .4s ease-out);
.keyframes(ripple;
{
100%
{
.transform(scale(1));
}
});
}
}
The idea is that on hover,focus, or active states the background scales outward from the centre - this it does.
However when the animation is complete - and the background is fully sized, it then returns to its original state (disappears) whilst still in hover state.
What changes do I need to make to ensure the background remains visibile whilst in focus?
you may use forwards and inbricate a transition with the animation to freeze it for a while:
a,
a:before,
a:after {
display: inline-block;
}
a:before,
a:after {
content: "\\o/";
transform: scale(0);
transition: 99999s;
/* delay as much as possible return to normal */
}
a:hover:before,
a:hover:after {
transition: 0s;/* reset transition timing */
animation: grow 1s forwards;
color: green;
}
#keyframes grow {
100% {
transform: scale(1);
}
}
html {
display: flex;
height: 100%;
width: 100%;
font-size: 5em;
}
body {
margin: auto;
}
link
codepen to play with.
I am working on an exercise about CSS 3 animation. I am stuck on how to keep the item falling down the page at full speed without requiring the user to follow it down with the mouse without resorting to javascript. So just when you hover the mouse over the box the box will fall down.
Here is my code:
<p class="exp9"><strong>box</strong></p>
strong {
margin-top: 20em;
}
p:hover strong {
display: block;
}
p:hover strong:hover {
margin-top: 20em;
}
My code just make the text inside the box drop down. Any idea? Thank you
Use this
/*newly added items start faded out and translated 400px upwards on the y-axis*/
li.new-item {
opacity: 0;
animation: new-item-animation .3s linear forwards;
}
#keyframes new-item-animation {
from {
opacity: 0;
transform: translateY(-400px);
}
to {
opacity: 1;
transform : translateY(0);
}
}
Here is an example of what you can do:
<div class="box">
<p class="innerbox">
Hover
</p>
</div>
CSS:
.innerbox
{
Width:150px;
height:20px;
background-color: lightBlue;
Text-align: center;
Padding:10px 0px;
}
.box
{
Display:inline-block;
Transition: 0.3s 0s All linear;
}
.box:hover
{
Padding-top:20em;
}
In the context of your HTML:
strong
{
Text-align: center; /* this makes it more aesthetic */
Padding:10px 20px; /* this makes the text more easy to hover over */
}
p
{
Display: inline-block; /* this is so the box doesn't stretch the width of the page */
Transition: 0.3s 0s all linear;
}
p:hover
{
padding-top: 20em;
}
Not sure if this is the result you want.
p{
width: max-content; /*add this if you don't want the paragraph to take the whole width*/
}
p strong{
display: block;
}
p:hover strong{
animation: fall .1s linear forwards;
}
#keyframes fall{
0%{
transform: translateY(0);
}
100%{
transform: translateY(20em);
}
}
<p class="exp9"><strong>box</strong></p>
Please view this code jsfiddle:
http://jsfiddle.net/rflfn/6wCp6/
<div id="menu">
<ul>
<li>Link #1</li>
<li>Link #2</li>
<li>Link #3</li>
<li>Link #4</li>
</ul>
</div>
CSS:
*{
margin: 0;
padding: 0;
text-decoration: none;
font-family: arial;
font-size: 16px;
}
a{
color: #000000;
}
a:hover{
color: #860000;
}
#menu{
margin: 15px auto;
padding: 20px;
width: 300px;
background: #DDDDDD;
border-radius: 5px;
box-shadow: 0 0 5px #000000;
}
#menu ul{
list-style: none;
}
#menu li:before{
margin-right: 10px;
content: url("http://st.deviantart.net/emoticons/s/smile.gif");
transition: all 0.5s ease 0s;
/* transition: content 0.5s ease 0s; */
}
#menu li:hover:before{
content: url("http://st.deviantart.net/emoticons/r/razz.gif");
}
I have one image on tag 'li' and other image on 'li:hover', is possible make transition with fade only using css?
You can do this by using both pseudo elements :before/after and using the CSS3 transition to animate the opacity of both on hover. This will create a fade transition between both images.
DEMO
CSS :
*{
margin: 0;
padding: 0;
text-decoration: none;
font-family: arial;
font-size: 16px;
}
a{
color: #000000;
}
a:hover{
color: #860000;
}
#menu{
margin: 15px auto;
padding: 20px;
width: 300px;
background: #DDDDDD;
border-radius: 5px;
box-shadow: 0 0 5px #000000;
}
#menu ul{
list-style: none;
}
#menu ul li{
position:relative;
}
#menu li:before{
margin-right: 10px;
content: url("http://st.deviantart.net/emoticons/s/smile.gif");
transition: opacity 0.5s ease;
-webkit-transition: opacity 0.5s ease;
}
#menu li:after{
content: url("http://st.deviantart.net/emoticons/r/razz.gif");
position:absolute;
left:0;
opacity:0;
transition: opacity 0.5s ease;
-webkit-transition: opacity 0.5s ease;
}
#menu li:hover:after{
opacity:1;
}
#menu li:hover:before{
opacity:0;
}
EDIT :
Even better, you can position both images one on top of the other and with z-index and css transition animate the opacity of ony one image :
DEMO
Your case in particular
Not sure why're you trying to put images in content,
you could simply add that image as a background-image to the :before,
set it size & display: inline-block; and you would just animate the background-image like so: http://jsfiddle.net/7f695m1q/ , since background-image transition is supported :)
TL;DR: Can content CSS property be animated? No.
MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
OUTDATED w3.org official document: https://www.w3.org/TR/2017/WD-css-transitions-1-20171130/#animatable-css
This may however change in future because this list is missing in current official sources:
missing in working draft https://www.w3.org/TR/css-transitions-1/
missing in editor's draft https://drafts.csswg.org/css-transitions/
So in theory there is a possibility this list will be updated and changes made in future browser versions, but currently it doesn't work.
Is content affected by other animations? Yes.
Content not being animatable in itself doesn't mean it's not affected by other animations like opacity, visibility etc. It can be leveraged in at least 2 simple ways:
a) answer by #web-tiki provides a smooth&always visible fade effect, however, you have to sacrifce both :after and :before to it
b) if fadeOut => fadeIn is an option for you you can levarage CSS animations & #keyframes
#keyframes changeContent {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
content: "See? I've changed seemlessly!";
}
}
div:before{
content: "HOVER OVER ME!";
background: green;
transition: all 1s linear;
animation-direction: reverse;
}
div:hover:before{
animation-fill-mode: forwards;
animation: changeContent 3s linear forwards;
background: orange;
}
<div />
Important here is to put the "forward" - it's an animation fill mode that basically says "stop the animation at it's end", otherwise it'd jump back.
There is also one drawback - it's not easily animatable on hover-out - if I find some reasonable way I will edit this answer or please comment if you know.
I think #web-tiki 's answer suits your needs and it's simpler. But just to show another possible solution:
You can separate the icons in two elements, each with its own content. Then, apply the transition on the li:hover event, setting the element's opacity inverted. Like this example:
FIDDLE: http://jsfiddle.net/2J7b9/1/
<ul>
<li>
<div class="img1"></div>
<div class="img2"></div>
test
</li>
</ul>
CSS:
li {
position: relative;
padding-left: 30px;
}
li .img1, li .img2 {
position: absolute;
top: 0;
left: 0;
}
li .img1 {
opacity: 1;
transition: all .25s ease-in-out;
}
li .img2 {
opacity: 0;
transition: all .25s ease-in-out;
}
li .img1:before {
content: url("http://st.deviantart.net/emoticons/s/smile.gif");;
}
li .img2:before {
content: url("http://st.deviantart.net/emoticons/r/razz.gif");
}
li:hover .img1 {
opacity: 0;
}
li:hover .img2 {
opacity: 1;
}