css transitions don't work when changes are made in javascript - javascript

#loading_screen {
display: none;
z-index: 1;
height: 100vh;
width: 100vw;
opacity: 0;
background-color: red;
transition: opacity 4s 0s ease;
}
<div id="loading_screen" class="page">
</div>
<script>
function hide_page() {
const loading = document.getElementById('loading_screen');
loading.style.display = 'block';
loading.style.opacity = '1';
}
hide_page()
</script>
The loading_screen div appears instantly, as if the transition didn't even exist
Is there a chance that the css is not functional immediately when I run the page?

You need to wait for the browser to update and paint the loading element first, then you can use setTimeout to change the opacity after the browser has done its paint.
function hide_page() {
const loading = document.getElementById('loading_screen');
loading.style.display = 'block';
setTimeout(() => {
loading.style.opacity = '1';
});
}
hide_page();
#loading_screen {
display: none;
z-index: 1;
height: 100vh;
width: 100vw;
opacity: 0;
background-color: red;
transition: opacity 4s ease;
}
<div id="loading_screen" class="page">
</div>

Related

CSS transition not working when adding class via jquery

I am adding a class to show an image when the mouse is over a div, but the transition isnt working at all.
I am using opacity, I know that the visibily: hidden is not animable.
The code is in the snippet:
$(document).ready(function() {
$("#trigger").on("mouseenter", function () {
$("#imgPuffo").addClass("visible");
$("#trigger").on("mouseout", function () {
$("#imgPuffo").removeClass("visible");
});
});
});
#trigger {
height: 100px;
width: 100px;
background: red;
}
img {
opacity: 0;
animation: opacity 2s;
}
.visible {
visibility: visible;
opacity: 1;
animation: opacity 2s;
}
.imgPuffo {
height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="trigger"></div>
<img id="imgPuffo" class="imgPuffo" src="https://www.pinclipart.com/picdir/big/449-4499911_how-to-draw-papa-smurf-from-the-smurfs.png" alt="">
There's a bit of confusion as animation is being used, but animation will look for an #keyframes sequence to tell it what animation to run. In fact it looks as though we don't need a full CSS animation in this case, just a CSS transition.
I've added transition: all 2s in case you want to transition anything else in future, like the scale, but if you just want to stick with transitioning opacity you could do transition: opacity 2s instead.
$(document).ready(function() {
$("#trigger").on("mouseenter", function () {
$("#imgPuffo").addClass("visible");
$("#trigger").on("mouseout", function () {
$("#imgPuffo").removeClass("visible");
});
});
});
#trigger {
height: 100px;
width: 100px;
background: red;
}
img {
opacity: 0;
/* animation: opacity 2s; */
transition: all 2s;
}
.visible {
visibility: visible;
opacity: 1;
/* animation: opacity 2s; */
}
.imgPuffo {
height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="trigger"></div>
<img id="imgPuffo" class="imgPuffo" src="https://www.pinclipart.com/picdir/big/449-4499911_how-to-draw-papa-smurf-from-the-smurfs.png" alt="">
if you want to use animations check the docs. You need to use #keyframes
$(document).ready(function() {
$("#trigger").on("mouseenter", function () {
$("#imgPuffo").addClass("visible");
$("#trigger").on("mouseout", function () {
$("#imgPuffo").removeClass("visible");
});
});
});
#trigger {
height: 100px;
width: 100px;
background: red;
}
img {
opacity: 0;
animation: opacity 2s;
}
.visible {
visibility: visible;
opacity: 1;
transition: opacity 2s ease-in-out;
}
.imgPuffo {
height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="trigger"></div>
<img id="imgPuffo" class="imgPuffo" src="https://www.pinclipart.com/picdir/big/449-4499911_how-to-draw-papa-smurf-from-the-smurfs.png" alt="">
How about a solution for css using a :hover, without jquery?
#trigger {
height: 100px;
width: 100px;
background: red;
}
#trigger:hover + .imgPuffo {
opacity: 1;
}
.imgPuffo {
opacity: 0;
height: 200px;
transition: opacity 2s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="trigger"></div>
<img id="imgPuffo" class="imgPuffo" src="https://www.pinclipart.com/picdir/big/449-4499911_how-to-draw-papa-smurf-from-the-smurfs.png" alt="">

Background transition does not work properly

I'm going to change back ground an element in a setInterval function. the background is getting changed imediately, but I would like to make it transited in couple of seconds.
var act = true;
setInterval(function(){
if (act) {
$("div").addClass("back2")
$("div").removeClass("back")
act = false
} else {
$("div").addClass("back")
$("div").removeClass("back2")
act = true
}
}, 10000)
.back{
width:100px;
height:100px;
background-image:url("https://www.skoobe.de/static/v/7b2334ac8a86ab5d764bc6e94df87df4aa5b4e2adc78c783e73ae2cbaf613745.jpg");
display:block;
transition: .5s ;
}
.back2{
width:100px;
height:100px;
background-image:url("https://www.skoobe.de/static/v/a5c0d3825217f88c4c893e7b630c4f1c5eb4c9bec834e1112383614270b5d583.jpg");
display:block;
transition: .5s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="c">tz</div>
background-image is not an animatable property. As you can see in this list on the mozilla dev page, this is not possible: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
What you can do is have two divs with one background image each overlapping each other and then make one of them transparent to create a blending effect.
I made a fiddle to illustrate the idea:
https://jsfiddle.net/Lpduw3mq/
// find elements
var firstDiv = $("#first")
var secondDiv = $("#second")
// Swap backgrounds
var act = true;
setInterval(function(){
if (act) {
firstDiv.addClass("transparent")
secondDiv.removeClass("transparent")
act = false
} else {
firstDiv.removeClass("transparent")
secondDiv.addClass("transparent")
act = true
}
}, 5000)
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
.base {
position: absolute;
top: 0;
left: 0;
}
.back {
width: 100px;
height: 100px;
background-image: url("https://www.skoobe.de/static/v/7b2334ac8a86ab5d764bc6e94df87df4aa5b4e2adc78c783e73ae2cbaf613745.jpg");
display: block;
opacity: 1;
transition: opacity 0.5s;
}
.back2 {
width: 100px;
height: 100px;
background-image: url("https://www.skoobe.de/static/v/a5c0d3825217f88c4c893e7b630c4f1c5eb4c9bec834e1112383614270b5d583.jpg");
display: block;
opacity: 1;
transition: opacity 0.5s;
}
.transparent {
opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="first" class="base back"></div>
<div id="second" class="base back2 transparent"></div>
You can use an unordered list of two items absolutely styled with the image backgrounds and use keyframe animation to change between these two items while smoothly changing a background opacity. Check this out http://tympanus.net/codrops/2012/01/02/fullscreen-background-image-slideshow-with-css3/

Multiple actions for one button

I'm trying to make full screen menu like a modal.
Everything is fine except fadeOut animation.
Can someone explain what is wrong with my scripts/codes?
I want to make this content fades in when click the button but fades out when its clicked again. My script sets the value of "display" but in animation only fade in effect works fine. In reverse fade out do effect instantly (without 0.5s animation duration). Button has got z-index = 101 and menu-content = 100 so the button stay at the same place all the time.
Thanks
function myMenu() {
var x = document.getElementById("menu-content");
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
if (x.style.animation === "fadeIn 0.5s ease-in-out") {
x.style.animation = "fadeOut 0.5s ease-in-out";
} else {
x.style.animation = "fadeIn 0.5s ease-in-out";
}
}
#menu-content {
display: none;
position: absolute;
height: 100%;
width: 100%;
background: linear-gradient(-25deg, #c0a0ae, #6f448a);
z-index: 100;
top: 0;
left: 0;
animation: fadeOut 0.5s ease-in-out;
}
.menu-content-properties {
height: 100%;
width: 100%;
display: grid;
grid-template-columns: auto;
background: #000000;
opacity: 0.5;
}
#keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
#keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
<button id="menu-button" style="z-index: 101; position: absolute; top: 0;
left: 0;" onclick="myMenu();">Menu</button>
<div id="menu-content"></div>
<div id="menu-content">
<div class="menu-content-properties">
<div>1</div>
<div></div>
<div>2</div>
</div>
</div>
Okay, so there are a couple of issues.
Firstly, in your HTML, there are 2 elements with the same ID (menu-content) which will cause a couple of problems, so remove one of those.
Secondly, when you set display: none in your myMenu function, it will immediately be hidden, so that's why the animation is not shown.
You have a couple of options:
Put that code within a setTimeout so that it isnt set to display: none until the animation has finished, OR
Don't use display: none
Personally, I think you're better off not using display: none, otherwise you need to amend your javascript whenever you change the duration of the animation.
I've managed to get it working without the need for display none, and using CSS transitions which works quite nicely
function myMenu() {
var x = document.getElementById("menu-content");
if (x.classList.contains("open")) {
x.classList.remove("open");
} else {
x.classList.add("open");
}
}
#menu-content {
position: absolute;
height: 100%;
width: 100%;
background: linear-gradient(-25deg, #c0a0ae, #6f448a);
z-index: 100;
top: 0;
left: 0;
transition: opacity 0.5s ease-in-out;
opacity: 0;
}
#menu-content.open {
opacity: 1;
}
.menu-content-properties {
height: 100%;
width: 100%;
display: grid;
grid-template-columns: auto;
background: #000000;
opacity: 0.5;
}
<button id="menu-button" style="z-index: 101; position: absolute; top: 0;
left: 0;" onclick="myMenu();">Menu</button>
<div id="menu-content">
<div class="menu-content-properties">
<div>1</div>
<div></div>
<div>2</div>
</div>
</div>

Hard transition of other properties when display property is involved

I want to fade between two differently sized elements within a container overlaying each other. The first element should be faded out, then the container resized and finally the other element faded in.
Here's the related snippet:
var layer1 = document.getElementById("layer1");
var layer2 = document.getElementById("layer2");
function switchLayers() {
layer1.addEventListener("transitionend", function() {
layer2.classList.add("fadein");
});
layer1.classList.add("fadeout");
}
#container {
position: relative;
background-color: yellow;
padding: 10px;
overflow: hidden;
}
.layer {
position: relative;
width: 400px;
}
#layer1 {
height: 100px;
float: left;
background-color: blue;
}
#layer2 {
height: 150px;
background-color: red;
display: none;
opacity: 0;
}
#layer1.fadeout {
opacity: 0;
transition: opacity 1s ease-out;
}
#layer2.fadein {
display: block;
opacity: 1;
transition: opacity 1s ease-out;
}
<button onclick="switchLayers()">Switch layers</button>
<div id="container">
<div id="layer1" class="layer"></div>
<div id="layer2" class="layer"></div>
</div>
When the second layer's display property is set to block it works as expected, i.e. the opacity is changed from 0 to 1 within a second. Though if it's set to none, the transition suddenly is discrete.
I've tried to set all within the transition value to transition all properties and also tried to include the display property in the transition like this:
transition: display 0s, opacity 1s ease-out;
Though without success. Note that because the container should resize to the size of the currently displayed layer, the visibility property can't be used (as it hides the element but still lets it occupy the space).
How to made this work?
Try using the visibility property instead of display.
For more information regarding the state changes in visibility and display, refer article.
For transitioning the parent height, you have to manually change the height property of the #container. Using display: block & display: none will never transition the parent.
Refer code:
var layer1 = document.getElementById("layer1");
var layer2 = document.getElementById("layer2");
function switchLayers() {
layer1.addEventListener("transitionend", function() {
layer2.classList.add("fadein");
document.getElementById("container").style.height = "170px";
});
layer1.classList.add("fadeout");
}
#container {
position: relative;
background-color: yellow;
padding: 10px;
height: 100px;
overflow: hidden;
transition: all 0.5s;
}
.layer {
position: relative;
width: 400px;
}
#layer1 {
height: 100px;
float: left;
background-color: blue;
}
#layer2 {
height: 150px;
background-color: red;
visibility: none;
opacity: 0;
}
#layer1.fadeout {
visibility: none;
opacity: 0;
transition: all 1s ease-out;
}
#layer2.fadein {
visibility: visible;
opacity: 1;
transition: all 1s ease-out;
}
<button onclick="switchLayers()">Switch layers</button>
<div id="container">
<div id="layer1" class="layer"></div>
<div id="layer2" class="layer"></div>
</div>
There is no straightforward way. Transitions do not work on display, nor do they work on auto height. So, visibility is a good bet.
Note that because the container should resize to the size of the
currently displayed layer, the visibility property can't be used (as
it hides the element but still lets it occupy the space).
Then, you will need to hack it out. You can make use of min-height. Give a faux min-height to your container, and then apply the height of your layer2 to it once the transition ends. Also, because display on layer2 will block the transition, you need to separate out the classes for display and opacity and space out their application using a zero timeout in between.
Here is a crude idea:
var layer1 = document.getElementById("layer1"),
layer2 = document.getElementById("layer2"),
container = document.getElementById("container"),
h = window.getComputedStyle(layer2).getPropertyValue("height");
container.addEventListener("transitionend", function(e) {
if (e.target.id === 'layer1') {
// apply layer2 height to container min-height
container.style.minHeight = h;
}
if (e.target.id === 'container') {
// First show the layer2
layer2.classList.add("show");
// Then a dummy pause to fadein
setTimeout(function(){
layer2.classList.add("fadein");
}, 0);
}
}, false);
function switchLayers() {
layer1.classList.add("fadeout");
}
#container {
position: relative;
background-color: yellow;
padding: 10px; overflow: hidden;
min-height: 1px; /* faux min-height */
transition: min-height 1s linear;
}
.layer { position: relative; width: 400px; }
#layer1 {
height: 100px; float: left;
background-color: blue;
transition: all 1s linear;
}
#layer2 {
height: 150px; background-color: red;
display: none; opacity: 0;
transition: opacity 1s linear;
}
#layer1.fadeout { opacity: 0; }
#layer2.show { display: block; } /* Separate out display */
#layer2.fadein { opacity: 1; } /* Separate out opacity */
<button onclick="switchLayers()">Switch layers</button>
<div id="container">
<div id="layer1" class="layer"></div>
<div id="layer2" class="layer"></div>
</div>

Preloader fade out and content fade in

I'm sure this is easy fix. I need that my preloader fade out slowly. I tried with css animation but didn't work. Can somebody tell me how should i do that in javascript ? As you can see in example, the transition is very rough. I don't want that.
<script> <!--Preloader-->
var myVar;
function preloader() {
myVar = setTimeout(showPage, 1500);
}
function showPage() {
document.getElementById("preloader").style.display = "none";
document.getElementById("wrapper").style.display = "block";
}
</script>
CODEPEN EXAMPLE
Add following changes into your codes.
#preloader {
transition:1s ease;
}
#wrapper {
opacity:0;/*Remove display and hide opacity*/
}
function showPage() {
document.getElementById("preloader").style.opacity = 0;
document.getElementById("wrapper").style.opacity = 1;
}
transition doent work with display block and none..
use
var myVar;
function preloader() {
myVar = setTimeout(showPage, 1500);
}
function showPage() {
document.getElementById("preloader").style.opacity = 0;
document.getElementById("wrapper").style.opacity = 1;
}
and
#preloader {
position: absolute;
z-index: 1000;
background-color:black;
width: 100vw;
height: 100vh;
color:white;
transition: 0.5s all linear
}
You can't animate display: none itself, what you can do is animate opacity: 0 for example.
You'll add display: block, while opacity is still 0. After that add opacity: 1 and animate that
Try this example may helps you.
$(function() {
$("#loader-image").fadeIn(500, function() {
$("#loader-image").fadeOut(1000, function() {
$(".loader-container").fadeOut(1000, function() {
alert("loaded!");
});
});
});
});
body {
background-color: black;
}
.loader-container {
background-color: yellow;
height: 200px;
}
#loader-image {
display: none;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<body>
<div class="loader-container">
<img src="image.png" alt="Image" id="loader-image" />
</div>
</body>
You can use a CSS transition.
Change your preloader styles to:
#preloader {
position: absolute;
z-index: 1000;
background-color:black;
width: 100vw;
height: 100vh;
color:white;
display: block;
opacity: 1; // Add opacity
transition: 1s opacity ease-in; // Add transition
}
Add styles for the hidden class:
#preloader.hidden {
opacity: 0;
}
Then when you call showPage()
function showPage() {
// Add the newly defined hidden class to the preloader element
document.getElementById("preloader").classList.add('hidden');
}
Here is a working example.

Categories