When an elements display goes from none to some other value its animation(if it has any) activates.
Does anyone know how to prevent this?
Also it would be nice to understand why this happens. Is because the DOM is being reflown?
Here is an example of what I mean for reference:
https://jsfiddle.net/darlyp/2p2q767r/
HTML
<div class="red-square"></div>
<br/>
<button id="btn">
Hide and Show square
</button>
CSS
.red-square{
width: 100px;
height: 100px;
background-color: red;
display: inline-block;
animation: 1s both moveSquare 1;
}
#keyframes moveSquare{
0%{
margin-left: 0px;
}
50%{
margin-left: 400px;
}
100%{
margin-left: 0px;
}
}
JS
document.getElementById('btn').addEventListener("click", function() {
var currentDisplay = document.querySelector('.red-square').style.display;
if (currentDisplay === 'none') {
document.querySelector('.red-square').style.display = 'inline-block';
} else {
document.querySelector('.red-square').style.display = 'none';
}
})
https://jsfiddle.net/darlyp/2p2q767r/
When you display it, you could set the animation-play-state to paused.
JSfiddle
document.getElementById('btn').addEventListener("click", function() {
var currentDisplay = document.querySelector('.red-square').style.display;
if (currentDisplay === 'none') {
document.querySelector('.red-square').style.display = 'inline-block';
document.querySelector('.red-square').style.animationPlayState = 'paused';
} else {
document.querySelector('.red-square').style.display = 'none';
}
})
.red-square{
width: 100px;
height: 100px;
background-color: red;
display: inline-block;
animation: 1s both moveSquare 1;
}
#keyframes moveSquare{
0%{
margin-left: 0px;
}
50%{
margin-left: 400px;
}
100%{
margin-left: 0px;
}
}
<div class="red-square"></div>
<br/>
<button id="btn">
Hide and Show square
</button>
Another way would be to toggle opacity instead, and change the height to 0 when it's hidden so it doesn't occupy any space on the page.
document.getElementById('btn').addEventListener("click", function() {
document.querySelector('.red-square').classList.toggle('hide');
})
.red-square {
width: 100px;
height: 100px;
background-color: red;
display: inline-block;
animation: 1s both moveSquare 1;
}
#keyframes moveSquare {
0% {
margin-left: 0px;
}
50% {
margin-left: 400px;
}
100% {
margin-left: 0px;
}
}
.hide {
opacity: 0;
height: 0;
}
<div class="red-square"></div>
<br/>
<button id="btn">
Hide and Show square
</button>
Related
I have a container div with overflow: auto (this can't be removed) and within it there's another div that toggles between showing and hiding using an animation when a button is clicked. The problem is that when this div moves down it causes an overflow. Keep in mind that this div must be within the container.
Example of the problem
https://jsfiddle.net/wg3jzkd6/1/
The expected result:
Div moves down without causing overflow
#manuel can you move the absolute div inside the content div? if yes, try adding the overflow: hidden; on content div
document.getElementById('button').addEventListener('click', () => {
const absolute = document.getElementById('absolute-div')
const absoluteClass = absolute.getAttribute('class')
if(absoluteClass.includes('hidden'))
absolute.setAttribute('class', 'absolute-div shown')
else
absolute.setAttribute('class', 'absolute-div hidden')
})
#keyframes hide {
from {
transform: translateY(0);
}
to {
transform: translateY(100%);
}
}
#keyframes show {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
.container {
position: relative;
overflow: auto;
border: 1px solid black;
height: 80vh;
width: 40vw;
margin: 0 auto;
padding: 1rem;
}
.content {
display: flex;
justify-content: center;
align-items: center;
position: relative;
min-height: 100%;
background-color: green;
overflow:hidden;
}
.absolute-div {
background-color: blue;
min-height: 20%;
width: 100%;
position: absolute;
left: 0;
bottom:0;
display:inline;
}
.hidden {
animation: hide ease forwards 300ms;
}
.shown {
animation: show ease forwards 300ms;
}
<html>
<body>
<div id='container' class='container'>
<div class='content'>
<button id='button'>
SHOW/HIDE
</button>
<div id='absolute-div' class='absolute-div'>
Hello world
</div>
</div>
</div>
</body>
</html>
Hope this will solve the issue you are facing..
As far as I can understand your question, is that you have a container that has an extra overflow. Try using the overflow: hidden; property in your container div
Just change your overflow to hidden
document.getElementById('button').addEventListener('click', () => {
const absolute = document.getElementById('absolute-div')
const absoluteClass = absolute.getAttribute('class')
if(absoluteClass.includes('hidden'))
absolute.setAttribute('class', 'absolute-div shown')
else
absolute.setAttribute('class', 'absolute-div hidden')
})
#keyframes hide {
from {
transform: translateY(0);
}
to {
transform: translateY(100%);
}
}
#keyframes show {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
.container {
position: relative;
overflow: hidden;
border: 1px solid black;
height: 80vh;
width: 40vw;
margin: 0 auto;
padding: 1rem;
}
.content {
display: flex;
justify-content: center;
align-items: center;
position: relative;
min-height: 100%;
background-color: green;
}
.absolute-div {
background-color: blue;
min-height: 20%;
width: 100%;
position: absolute;
left: 0;
bottom:0;
}
.hidden {
animation: hide ease forwards 300ms;
}
.shown {
animation: show ease forwards 300ms;
}
<html>
<body>
<div id='container' class='container'>
<div class='content'>
<button id='button'>
SHOW/HIDE
</button>
</div>
<div id='absolute-div' class='absolute-div'>
Hello world
</div>
</div>
</body>
</html>
I do not quite understand, why overflow: auto cannot be changed. It works perfectly with the overflow attribute set to hidden.
If changing from auto invokes some kind of affect that is not explained here, I would kindly advise you to add this affect. But should there be such, it can probably be solved by putting this whole construct into another div container and isolating it, preventing any unwanted side effects.
I have two horizontally aligned responsive divs that are set to be the same height.
The left holds an embedded youtube video, the right a fixed image.
Tested in Chrome there are no issues, but if tested in Safari the youtube video is not filling the full height of the div.
html markup is:
<div id="IndexBanners">
<div class="indexbannerimages effect first">
<div id="player"></div>
<script src="https://www.youtube.com/player_api"></script>
<script>
// create youtube player
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
videoId: 'GfaiXgY114U',
autoplay: '0',
controls: '0',
width: '100%',
height: '100%',
playerVars: {
rel: 0,
showinfo: 0
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// autoplay video
function onPlayerReady(event) {
// event.target.playVideo();
}
// change mask opacity depending on player state
function onPlayerStateChange(event) {
if (event.data === -1) {
document.getElementById("mask1").setAttribute("style", "opacity:1; -moz-opacity:1; filter:alpha(opacity=100)");
}
if (event.data === 0) {
document.getElementById("mask1").setAttribute("style", "opacity:1; -moz-opacity:1; filter:alpha(opacity=100)");
}
if (event.data === 1) {
document.getElementById("mask1").setAttribute("style", "opacity:0; -moz-opacity:0; filter:alpha(opacity=0)");
}
if (event.data === 2) {
document.getElementById("mask1").setAttribute("style", "opacity:1; -moz-opacity:1; filter:alpha(opacity=100)");
}
}
</script>
<div id="mask1">
<div class="watchText">Watch The Video</div>
<div class="watch"></div>
</div>
</div>
<div class="indexbannerimages effect">
<img src="https://placehold.it/795x436">
<div id="mask2">
<div class="newsText">Latest News</div>
<div class="news"></div>
</div>
</div>
</div>
css:
#IndexBanners {
display: flex;
margin-top: 20px;
}
.indexbannerimages {
flex: 1 0 0;
position: relative;
}
img {
max-width: 100%;
height: auto;
vertical-align: top;
}
.indexbannerimages .watch {
background: url(../images/play-icon.png) no-repeat scroll 0% 25% / 14px auto;
}
.indexbannerimages .news {
background: url(../images/news-icon.png) no-repeat scroll 0% 25% / 14px auto;
}
.watchText {
color: #fff;
text-transform: uppercase;
padding-top: 23%;
margin: 0;
}
.newsText {
color: #fff;
text-transform: uppercase;
padding-top: 23%;
margin: 0;
}
.effect #mask1,
.effect #mask2 {
text-align: center;
font-size: 16px;
color: #fff;
background-color: rgba(00, 00, 00, 0.8);
opacity: 0.75;
transition: all 0.5s ease-in-out;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
cursor: pointer;
}
.effect:hover #mask1,
.effect:hover #mask2 {
visibility: hidden;
opacity: 0.0;
transition: all 0.5s ease-in-out;
}
#media (max-width:600px) {
#IndexBanners {
display: block;
}
.first {
position: relative;
padding-bottom: 56.25%;
height: 0;
}
.first iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
I've set up a fiddle here to demonstrate the issue. https://jsfiddle.net/bgaqfvxm/3/
Any suggestions on a fix for this size issue in Safari?
Issue resolved by adding the following to the css
.first iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
Thanks to #Michael Coker for the original css that was used in #media query below 600px
I have created a simple loader with css. It works fine in chrome but nor working in firefox.
https://jsfiddle.net/sunilmadaan07/4dcaLegc/
Code is as below:
HTML:
<div class='container'>
<div class='loader'>
<div class='loader--text'></div>
</div>
</div>
Content animation not working in most of all browser. You can do following using plugins.
$("#randomArea").Loadingdotdotdot({
"speed": 400,
"maxDots": 5,
"word": "Loading"
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://css-tricks.com/examples/Loadingdotdotdot/js/jquery.loadingdotdotdot.js"></script>
<div id="randomArea" style="position: relative;">done!</div>
Reference Link
Hey you can achieve the effect using plain JS but i have used jQuery..
jQUERY
// Simpler, does exactly the same thing:
var i=1;
var txt="Loading";
function go () {
console.log(i);
$('.loader--text').text(txt);
i++;
txt+=".";
if(i==5)
{
txt="Loading";
i=1;
}
setTimeout(go,1000);
}
go();
JSFIDDLE Link:
https://jsfiddle.net/4dcaLegc/5/
The problem is animation with :after pseudo is not supporting in Firefox, thats why I change some of your code a litter from content to width on parent element.
Check below snippet:
.container {
height: 100vh;
width: 100vw;
font-family: Helvetica;
}
.loader {
height: 20px;
width: 80px;
position: relative;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
.loader-text {
position: absolute;
top: 500%;
left: 0;
right: 0;
width:64px;
overflow:hidden;
animation: loadertext 3s infinite;
-moz-animation:loadertext 3s infinite;
}
#-moz-keyframes loadertext {
0% {
width:64px;
}
35% {
width:68px;
}
60% {
width:72px;
}
100% {
width:75px;
}
}
#keyframes loadertext {
0% {
width:64px;
}
35% {
width:68px;
}
60% {
width:72px;
}
100% {
width:75px;
}
}
.loader-text:after {
content: "Loading...";
font-weight: bold;
display:block;
}
<div class='container'>
<div class='loader'>
<div class='loader-text'></div>
</div>
</div>
I am facing an issue in css3 animation in IE11 only.
Here is link with issue (please open in ie11)
$(document).ready(function() {
$(".spinnerTinyBar").show();
$("#toggle").click(function() {
$(".spinnerTinyBar").toggle();
});
});
#keyframes tinybar-load1 {
0% {
box-shadow: 0 0 blue;
height: 20px;
}
40% {
box-shadow: 0 -15px blue;
height: 25px;
}
80% {
box-shadow: 0 0 blue;
height: 20px;
}
100% {
box-shadow: 0 0 blue;
height: 20px;
}
}
.spinnerTinyBar,
.spinnerTinyBar:before,
.spinnerTinyBar:after {
background: blue;
animation: tinybar-load1 1s infinite ease-in-out;
width: 2px;
height: 20px;
}
.spinnerTinyBar:before {
left: -5px;
-webkit-animation-delay: -0.32s;
animation-delay: -0.32s;
}
.spinnerTinyBar {
font-size: 9px;
position: relative;
-webkit-animation-delay: -0.16s;
animation-delay: -0.16s;
transform: translateZ(0);
}
.spinnerTinyBar:after {
left: 5px;
}
.spinnerTinyBar:before,
.spinnerTinyBar:after {
position: absolute;
top: 0;
content: "";
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="button" id="toggle" value="Toggle" />
<div class="spinnerTinyBar"></div>
JSFiddle
Issue:
For first time, the animation is working good. When I toggle by clicking on toggle button the animation is not happening for 1st and last bar. This is working fine in chrome and in all mobile devices.
Let me know if anybody figured it out and do the needful
It's a weird one this but here's a fix:
Change your html to this:
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(document).ready(function(){
$(".spinnerTinyBar").show();
$("#toggle").click(function(){
$(".divClass").toggleClass('spinnerTinyBar');
});
});
</script>
<input type="button" id="toggle" value="Toggle"/>
<div class="divClass spinnerTinyBar"></div>
</body>
Instead of hiding the element we simply change the class on it to show the animation, or not
Here's an updated fiddle working in ie11
Try this little hack for your IE
#media screen and (min-width: 0\0) {
.your-animation-parent {
transform: translate3d(0, 0, 0);
}
}
//Here is my HTML
What i need here is that on complete load of the progress bar it should redirect to another page.
any ways for that?!!!!
.text-center {
text-align: center;
}
.container {
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
}
.progress {
background-color: #e5e9eb;
height: 0.25em;
position: relative;
width: 24em;
}
.progress-bar {
-webkit-animation-duration: 3s;
-webkit-animation-name: width;
background: linear-gradient(to right, #4cd964, #5ac8fa, #007aff, #34aadc, #5856d6, #ff2d55);
background-size: 24em 0.25em;
height: 100%;
position: relative;
}
.progress-shadow {
background-image: linear-gradient(to bottom, #eaecee, transparent);
height: 4em;
position: absolute;
top: 100%;
transform: skew(45deg);
transform-origin: 0 0;
width: 100%;
}
/* ANIMATIONS */
#keyframes width {
0%, 100% {
transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
}
0% {
width: 0;
}
100% {
width: 100%;
}
}
#-webkit-keyframes width {
0%, 100% {
transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
}
0% {
width: 0;
}
100% {
width: 100%;
}
}
<div class="container">
<h2 class="text-center">Loading</h2>
<div class="progress">
<div class="progress-bar">
<div class="progress-shadow"></div>
</div>
</div>
</div>
help me out!!
And i don't have any java script here.
i would be more happy if i can do it without java script.
so please help me out with it.
UPDATE
found that java script animation end may help out.
Simply use this trick highlighted by David Walsh. He did it for transitionend, but we can swap it out for animationend instead.
His trick is to loop through the list of all vendor-prefixed and native animationend events, and check if the browser supports any of them. He then attaches the recognized animationend handler to the element of interest.
When the animationend event is fired, we simply redirect to the URL of interest using window.location.replace(), as mentioned before.
I have modified it so it would work for your scenario:
$(function() {
// Check with animationend event is supported by browser
function whichAnimationEvent(){
var t;
var el = document.createElement('fakeelement');
var animations = {
'animation':'animationend',
'OAnimation':'oAnimationEnd',
'MozAnimation':'animationend',
'WebkitAnimation':'webkitAnimationEnd'
}
for(t in animations){
if( el.style[t] !== undefined ){
return animations[t];
}
}
}
// Listen for animation
var animationEvent = whichAnimationEvent(),
progress = document.getElementsByClassName('progress-bar')[0];
animationEvent && progress.addEventListener(animationEvent, function() {
// Alert (to demonstrate the code works)
alert('Animation complete! This is the callback, no library needed!');
// Redirect script
window.location.replace('/path/to/url');
});
});
See fiddle here: http://jsfiddle.net/teddyrised/9w7pntmt/3/
ok., i found the solution completely.
if anyone have any issue with this please report.
function whichAnimationEvent() {
var t;
var el = document.createElement('fakeelement');
var animations = {
'animation': 'animationend',
'OAnimation': 'oAnimationEnd',
'MozAnimation': 'animationend',
'WebkitAnimation': 'webkitAnimationEnd'
};
for (t in animations) {
if (el.style[t] !== undefined) {
return animations[t];
}
}
}
function oload() {
var animationEvent = whichAnimationEvent(),
progress = document.getElementsByClassName('progress-bar')[0];
animationEvent && progress.addEventListener(animationEvent, function() {
window.location.replace("http://alokraj68.in");
});
}
// Listen for animation
html,
body {
height: 100%;
}
body {
background-color: #f5f7f9;
color: #6c6c6c;
font: 300 1em/1.5em"Helvetica Neue", sans-serif;
margin: 0;
position: relative;
}
h1 {
font-size: 2.25em;
font-weight: 100;
line-height: 1.2em;
margin: 0 0 1.5em;
}
.text-center {
text-align: center;
}
.container {
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
}
.progress {
background-color: #e5e9eb;
height: 0.25em;
position: relative;
width: 24em;
}
.progress-bar {
-webkit-animation-duration: 3s;
-webkit-animation-name: width;
background: linear-gradient(to right, #4cd964, #5ac8fa, #007aff, #34aadc, #5856d6, #ff2d55);
background-size: 24em 0.25em;
height: 100%;
position: relative;
}
.progress-shadow {
background-image: linear-gradient(to bottom, #eaecee, transparent);
height: 4em;
position: absolute;
top: 100%;
transform: skew(45deg);
transform-origin: 0 0;
width: 100%;
}
/* ANIMATIONS */
#keyframes width {
0%, 100% {
transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
}
0% {
width: 0;
}
100% {
width: 100%;
}
}
#-webkit-keyframes width {
0%, 100% {
transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
}
0% {
width: 0;
}
100% {
width: 100%;
}
}
<html>
<head>
<meta charset="UTF-8">
<title>alokraj68.in--Loading!!</title>
<link rel="stylesheet" href="css/loading.css">
<script src="js/script.js"></script>
</head>
<body onload="oload()">
<div class="container">
<h1 class="text-center">alokraj68.in</h1>
<h2 class="text-center">Loading</h2>
<div class="progress">
<div id="pb" class="progress-bar">
<div class="progress-shadow"></div>
</div>
</div>
</div>
</body>
</html>
Try this coding.
if anyone finds any issues, please tell me.