I'm trying to use the following two css classes to show/hide elements with transition effects-
.hidden{
opacity: 0;
height: 0;
overflow: hidden;
visibility: hidden;
transition: all 2s;
}
.shown{
opacity: 1;
visibility: visible;
height: auto;
transition: all 2s;
}
//JS code to toggle classes -
$("#cancelLogin").click(function(){
$('form.login').toggleClass("shown").toggleClass("hidden");
$('.circles').toggleClass("concealed").toggleClass("shown");
});
.shown works fine, but no transition happening while adding .hidden class. Any idea?
Since you are using height: 0 on the hidden class, this will execute firstly and you won't see any transition during the hiding process. You can achieve this with multiple tricks and ways, like the CSS animation and do stuff in a certain order or add a delay to your height adjustment and make it execute after the transition happens.
You can use the setTimeout method to make this happen.
const div = document.querySelector("div")
const button = document.querySelector("button")
button.addEventListener("click", () => {
if (div.classList.contains("hidden")) {
div.classList.remove("hidden")
div.classList.add("shown")
div.style.height = 'auto'
} else {
div.classList.remove("shown")
div.classList.add("hidden")
setTimeout(() => {
div.style.height = 0
}, 1000)
}
})
.div {
transition: all 2s;
}
.hidden {
opacity: 0;
overflow: hidden;
visibility: hidden;
}
.shown {
opacity: 1;
visibility: visible;
}
<div class="div">div</div>
<button>change visibility</button>
NOTE: To avoid CSS rule duplication it is always better to assign the transition to the element itself instead of classes which will be triggered based on different actions.
Related
I have a sticky element I've setup for a button on mobile devices. This is the code:
.sticky-btn {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
}
Works great but I don't want the button to show when the user is at the very top of the page. It would be perfect if it only appeared after you scrolled down say 20-30 pixels. Is it possible to accomplish this in CSS somehow?
Thanks!
Brian Preston. Unfortunately, we can't do this using only CSS. We should Javascript to add "sticky" class to sticky button and toggle button using that class.
.sticky-btn {
position: fixed;
bottom: 20px;
left: 50%;
opacity: 0;
visibility: hidden;
pointer-events: none;
transform: translateX(-50%);
transition: all .3s ease-in-out;
}
.sticky-btn.sticky {
opacity: 1;
visibility: visible;
pointer-events: all;
}
And JS code should be like this.
document.addEventListener('DOMContentLoaded', function () {
var scrollPosition = window.scrollY;
var stickyBtn = document.querySelector('.sticky-btn');
window.addEventListener('scroll', function() {
scrollPosition = window.scrollY;
if (scrollPosition >= 30) {
stickyBtn.classList.add('sticky');
} else {
stickyBtn.classList.remove('sticky');
}
});
});
Hope this helps. Happy coding ~ :)
The following hides the element, but I cannot recover when I hover over it.
I've checked devtools to see that it is indeed rendered on the screen, I just can't see the contents of the div.
How do I make it so the div is visible only on hover?
.visible-on-hover {
visibility: hidden;
}
.visible-on-hover:hover {
visibility: visible !important;
}
Elements with visibility: hidden; don't receive any mouse events, so :hover never triggers on such an element.
Instead of visibility, you can work with opacity:
div {
background-color: orange;
height: 200px;
width: 400px;
padding: 50px;
}
.visible-on-hover {
opacity: 0;
transition: opacity .3s ease;
}
.visible-on-hover:hover {
opacity: 1;
}
<div class="visible-on-hover">visible only on hover</div>
you can not hover, focus or select a hidden element.
you can use opacity
.visible-on-hover {
opacity: 0;
}
.visible-on-hover:hover {
opacity: 1;
}
Is there a way to smooth the transition during a div background change? Ideally I'd like to do this within the css, and not use any js.
In my css I have:
.examplediv {
background: url(img_img.png);
}
.examplediv:hover{
background: url(brighter_img.png);
}
It's doing what I'd like it to do (changing pictures), but if there was a way to make the two backgrounds "dissolve" into one another, I'd start frothing at the mouth with gratitude.
Note: The effect I'm going for is essentially an opacity change, so if it's easier to code a dissolve with :opacity, I'm all ears!
Tanks!~
It's definitely possible using just CSS. See this Fiddle for an example: https://jsfiddle.net/ffqdmcws/
HTML:
<div class="crossfade">
<div class="static"></div>
<div class="hover"></div>
</div>
CSS:
.crossfade {
position: relative;
width: 300px;
height: 200px;
}
.static, .hover {
position: absolute;
width: 100%;
height: 100%;
transition: opacity 1s ease;
}
.static {
background: url('http://lorempixel.com/300/200/food');
opacity: 1;
}
.hover {
background: url('http://lorempixel.com/300/200/cats');
opacity: 0;
}
.crossfade:hover > .static {
opacity: 0;
}
.crossfade:hover > .hover {
opacity: 1;
}
In this case I've got a container div using the crossfade class, and a couple of other divs inside that, using classes static and hover.
The static class contains the background to be shown initially, and the hover class contains the background to fade to on hover. The initial opacities are 1 for the static class and 0 for the hover class, so you only see the div with class static.
Then, if you hook up the hover action on the container div using .crossfade:hover, in order to set opacity: 0; for static and opacity: 1; for hover, that hides static and shows hover, when you hover over the container div.
Finally, to make the backgrounds overlap use absolute positioning of the two internal divs, so they're on top of each other at all times. Additionally, for the true crossfade effect you need the transition: opacity 1s ease; rule, which says you want the opacity to transition over a period of 1 second instead of switching instantly. Both the divs changing opacity from 1->0 and from 0->1 give you the crossfade effect of the background images.
You can do it with pseudo elements which are absolutely positioned. One is visible by default and another one on hover.
.examplediv {
height: 600px;
position: relative;
}
.examplediv:before, .examplediv:after {
content: '';
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: -1;
transition: opacity 0.5s ease-out;
}
.examplediv:before {
background: url(https://pixabay.com/static/uploads/photo/2015/07/19/17/38/flower-851725_960_720.jpg)
}
.examplediv:after {
background: url(https://pixabay.com/static/uploads/photo/2015/12/07/23/56/pink-flower-1081646_960_720.jpg);
opacity: 0;
}
.examplediv:hover:before {
opacity: 0;
}
.examplediv:hover:after {
opacity: 1;
}
<div class="examplediv">
</div>
JSFIDDLE
I'm having trouble handling the "transitionend" event in Microsoft Edge, on a pseudo element.
It works in other browsers like chrome, safari, and firefox. I thought it may have been a bug with MS Edge, but it doesn't work in IE11 either, so maybe there is some other way that I'm missing in the Microsoft world.
Does anyone know how to handle this in IE?
Here's the code... the box will turn green after the fade-in completes if the transitionend event has been handled correctly.
window.setTimeout(function(){
$('#box').one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd',function(){
$(this).addClass('done');
});
$('#box').addClass('show');
},1);
#box {
position: relative;
}
#box:before {
position: absolute;
height: 100px;
width: 100px;
background-color: tomato;
transition: opacity 1s;
opacity: 0;
content: "";
}
#box.show:before {
opacity: 1;
}
#box.done:before {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div id="box"></div>
#box {
position: relative;
}
#box > .before {
position: absolute;
height: 100px;
width: 100px;
background-color: tomato;
transition: opacity 1s;
opacity: 0;
content: "";
}
#box.show > .before {
opacity: 1;
}
#box.done > .before {
background-color: green;
}
IE11 has an issue with transitionend on pseudo element. If added extra elements inside the parent container. This worked for me!
Is you used jQuery's .animate() function, you can have a function put on the end to be run, like this:
$(document).ready(function() {
$('#box').animate({opacity: 1}, 1000, function() {
$('#box').animate({background-color: green}, 1000);
});
});
The background-color will only transition to green after it has finished fading in. Hopefully this helps!
I've noticed that transition is not working when the element is also changing from display none to block. Why is that? It works if I remove the display attribute.
CSS:
#box {
width: 150px;
height: 150px;
background: red;
transform: scale(0);
display: none;
transition: transform .5s;
}
#box.active {
transform: scale(1);
display: block;
}
http://jsfiddle.net/640kL55u/
Because it has display: none to begin with, the other styles are not being taken into the dom to be transitioned once display: block is added.
Instead, you can hide the div with height, so its still on the page but not showing. Then add the height on the show div.
JS Fiddle
Any change from or to display: none won't trigger transitions.
You can, however, change the display property and then add the class name at the end of the javascript stack. For instance:
function showElem(elem) {
elem.style.display = "block";
setTimeout(function() {
elem.classList.add("active");
}, 0);
}
And then pass element nodes to this function.
You can't transition with display: none; properties...
$("button").on("click", function() {
$("#box").addClass("active");
});
#box {
width: 0;
height: 0;
overflow: hidden;
background: red;
transform: scale(0);
transition: transform .5s;
}
#box.active {
width: 150px;
height: 150px;
transform: scale(1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="box"></div>
<button>CLICK</button>