I have quite a few page effects on the load, and they can cause the page to disfigure on load. To stop this, I'm fading the body in and out. However, it only works when display:none; is attributed to the body section of the CSS.
CSS
body {
position: relative;
min-height: 100%;
margin: 0 0 0 0;
padding: 0 0 0 0;
border-collapse: collapse;
font-size: 12px;
display: none;
}
JS
window.onload = function () {
$('body').fadeIn();
main(); // my effect function
};
window.onbeforeunload = function () {
$('body').fadeOut();
};
I'm using a the design editor in VS 2015 and I can't see my pages because display:none; is set.
Is there any reason it's not working without display:none;?
fadeIn animates the opacity from its current state to 1 (i.e. no transparency).
If the element is completely hidden, that will be a transition from 0 to 1. If the element has a 50% opacity, it will be a transition from 0.5 to 1.
If, on the other hand, the element is already visible, there will be no animation at all, as the element is already at the target state.
Related
I have a form and inside this form a button. Initially the button is statically positioned at its default position based on usual layout. On an event (in the example below, button click) I want to move it to the center of the form through animation and during this animation doing a horizontal flip (using scale transform) and when the animation is in the middle (when the rendered width is 0) changing the contents of the button to a paragraph that once loaded will show an animation probably done with svg and a link.
This snippet does a part of what I want (everything until the second part of the flip with changing the contents and resizing the button to be bigger), but without an initial static position from which to start the animation:
var form = $("form")
var button = $("button")
button.on("click", function(){
var x = (form.outerWidth() - button.outerWidth()) / 2;
var y = (form.outerHeight() - button.outerHeight()) / 2;
button.css({
transform: `translateX(${x}px) translateY(${y}px) scaleX(0)`
});
})
form {
background: #aaa;
border-radius: 4px;
padding: 20px;
font-size: 25px;
transition: all 0.2s;
margin: 0 auto;
width: 300px;
position: relative;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
position: absolute;
left: 0;
top: 0;
transition: transform 1s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<p>Hello World</p>
<button onclick="return false;">Do something</button>
</form>
(https://jsfiddle.net/silviubogan/L1ogpf6a/)
How can I achieve what I want in the most correct manner? Please note that the rest of the form should remain in place.
Thank you.
There's two ways you can do this. First is using setTimeout (reference) with 1000ms as a parameter, since your css animation lasts 1 second, and a callback function that displays the SVG. The second is using jQuery animate (reference) instead of css, and using the parameter complete to show your SVG. Since you are already using css for the animation, let's go with the first option:
button.on("click", function(){
// hide button
window.setTimeout(transform2, 1000);
})
function transform2() {
// change contents
// resize button
}
Example fiddle: https://jsfiddle.net/eynL91qu/
I have this element that starts hidden and then gets animated with a css transition on a click event.
I know the display property cannot be animated, so what I do is remove the class that applies the display:none, and then make the change that triggers the css transition, like so:
popin.classList.remove('hidden') // removes the display:none property
setTimeout(() => {
popin.classList.remove('closed') // triggers transition
}, 10)
See this fiddle: http://jsfiddle.net/wre2674p/6/ for a full example.
I've found out that in order to work, the 2nd step must be done asynchronously. Put it in a setTimeout and it works...sort of. In Chrome, any timeout duration works (even 0).
For Firefox and Edge, the behavior varies. For 100ms, it works every time. But for a timeout of e.g. 10ms, the transition works only maybe 50% of times. Since it delays the animation, I wish to keep it as low as possible, while ensuring it works consistently.
I suspect it is related to reflow/repaint occurring when changing display property from none to block, but I lack details on these subjects to full understand what's happening and how to prevent it. Any idea?
Remove the hidden class from CSS and HTML, remove timeout from js. There is no need to display none the #popin since you already have overflow hidden. The transition can be triggered directly, you are over complicating things
document.getElementById('toggle').addEventListener('click', function(e){
let source = e.currentTarget
source.disabled = true
let popin = document.getElementById('popin')
if (popin.classList.contains('closed')){
popin.classList.remove('closed')
}
else{
popin.classList.add('closed')
}
setTimeout(() => {
source.disabled = false
}, 850)
})
body{
overflow: hidden;
}
#popin{
display: block;
position: absolute;
top: 0;
right: 0;
width: 400px;
height: 100vh;
/*transform: translate(0, 0);*/
transition: opacity 800ms;
opacity: 1;
background: lightgreen;
}
#popin.closed{
opacity: 0;
z-index: -1;
pointer-events: none;
}
<button id="toggle">toggle</button>
<div id="popin" class="closed">
<h1>Popin</h1>
</div>
I have build sidebar with css and jquery. It's working fine but i want that when sidebar opens then whole screen except sidebar should get semi-black or disabled.
Here is my working
jsFiddle
How can i make whole screen semi-black or disabled on sidebar open?
You can use a box-shadow on the sidebar:
#sidebar{
box-shadow:0 0 0 10000px rgba(0,0,0,.50);
}
This is black, at .50 opacity. It's set to 10000px to cover the full screen.
Or change rgba(0,0,0,.50) to a solid color like #5a5a5a.
In your case add to your css:
#slide-out.visible:not(.close){
box-shadow:0 0 0 10000px #666666;
}
The general concept to achieve this is fairly straightforward:
Modify the javascript to add a class to the body when the nav is open (I called it nav-open.)
Modify the CSS so that the "overlay" element (you already had one in place) is displayed when the body has the class nav-open
Adjust your overlay element CSS to cause it to show properly (for some reason, it had opacity: 0 on it, which meant it was there, but was not visible).
Here's the relevant CSS:
#sidenav-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100vw;
height: 100vh;
// removed opacity: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 997;
// set display to none by default
display: none;
}
// when the body has the class nav-open, display the overlay
.nav-open #sidenav-overlay {
display: block;
}
Here's the relevant changes to your javascript:
// no-conflict-safe document ready function
jQuery(function($) {
$('#show-hide-menu').click(function() {
if ($('#slide-out').hasClass('visible')) {
// $('#slide-out').removeClass('visible');
$('#slide-out').toggleClass('close');
} else {
$('#slide-out').addClass('visible');
}
// check if the nav is "open"
var open = !$('#slide-out').hasClass('close');
// for simplicity, always first remove the nav-open from the body
$('body').removeClass('nav-open');
// if the nav is open, add the 'nav-open' class to the body
if (open) {
$('body').addClass('nav-open');
}
});
// modify to use "on", is best-practice
// $(document).click(function(e) {
$(document).on('click', function(e) {
var sidebar = $(".sidenav, #show-hide-menu");
if (!sidebar.is(e.target) && sidebar.has(e.target).length === 0) {
$('#slide-out').toggleClass('close');
// be sure the nav-open class is removed when the sidebar is dismissed
$('body').removeClass('nav-open');
}
});
});
Here is a link to your fiddle, modified with these changes to do what you want: http://jsfiddle.net/cale_b/hThGb/8849/
Make a content div below your nav. Something like:
<div id="maincontent" class="">
<p>Lorem.</p>
</div>
Add some styling so it has min-height, etc.
#maincontent {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
min-height: 400px;
}
Add some JS so when the nav menu button is clicked, it toggles on and off a new style class for this area.
$('#show-hide-menu').click(function () {
if ($("div#maincontent").hasClass("overlayed")) {
$("div#maincontent").removeClass("overlayed");
}
else {
$("div#maincontent").addClass("overlayed");
}
});
Define the overlayed class in the CSS.
.overlayed {
background-color: rgba(0,0,0,.8);
}
I was reading this article http://semisignal.com/?p=5298 and the author wrote that
"Reflow needs to be triggered before the invisible class is removed in order for the transition to work as expected. "
My questions are :
1) Why does reflow need to be triggered?
2) I understand that we should avoid using reflow, if that is true why is the author suggesting to use reflow in order to make the transition work?
3) Instead of using reflow, is there a different method to make the transition work?
Thank you.
(Effectively: "Why can't I easily use transitions with the display property")
Short Answer:
CSS Transitions rely on starting or static properties of an element. When an element is set to display: none; the document (DOM) is rendered as though the element doesn't exist. This means when it's set to display: block; - There are no starting values for it to transition.
Longer Answer:
Reflow needs to be triggered because elements set to display: none; are not drawn in the document yet. This prevents transitions from having a starting value/initial state. Setting an element to display: none; makes the document render as if the element isn't there at all.
He suggest reflowing because it's generally accepted to hide and show elements with display: none; and display: block; - typically after the element has been requested by an action (tab or button click, callback function, timeout function, etc.). Transitions are a huge bonus to UX, so reflowing is a relatively simple way to allow these transitions to occur. It doesn't have an enormous impact when you use simple transitions on simple sites, so for general purposes you can trigger a reflow, even if technically you shouldn't. Think of the guy's example like using unminified JavaScript files in a production site. Can you? Sure! Should you? Probably not, but for most cases, it won't make a hugely noticeable difference.
There are different options available that prevent reflowing, or are generally easier to use than the method in the link you provided. Take the following snippet for a few examples:
A: This element is set to height: 0; and overflow: hidden;. When shown, it's set to height: auto;. We apply the animation to only the opacity. This gives us a similar effect, but we can transition it without a reflow because it's already rendered in the document and gives the transitions initial values to work with.
B: This element is the same as A, but sets the height to a defined size.
A and B work well enough for fading in elements, but because we set the height from auto/100px to 0 instantly, they appear to collapse on "fade out"
C: This element is hidden and we attempt to transition the child. You can see that this doesn't work either and requires a reflow to be triggered.
D: This element is hidden and we animate the child. Since the animation keyframes give a defined starting and ending value, this works much better. However note that the black box snaps into view because it's still attached to the parent.
E: This works similarly to D but we run everything off the child, which doesn't solve our "black box" issue we had with D.
F: This is probably the best of both worlds solution. We move the styling off the parent onto the child. We can trigger the animation off of the parent, and we can control the display property of the child and animate the transition as we want. The downside to this being you need use animation keyframes instead of transitions.
G: While I don't know if this triggers a reflow inside the function as I haven't parsed it myself, you can just simply use jQuery's .fadeToggle() function to accomplish all of this with a single line of JavaScript, and is used so often (or similar JS/jQuery fadeIn/fadeOut methods) that the subject of reflowing doesn't come up all that often.
Examples:
Here's a CodePen: https://codepen.io/xhynk/pen/gerPKq
Here's a Snippet:
jQuery(document).ready(function($){
$('button:not(#g)').click(function(){
$(this).next('div').toggleClass('show');
});
$('#g').click(function(){
$(this).next('div').stop().fadeToggle(2000);
});
});
* { box-sizing: border-box; }
button {
text-align: center;
width: 400px;
}
div {
margin-top: 20px;
background: #000;
color: #fff;
}
.a,
.b {
overflow: hidden;
height: 0;
opacity: 0;
transition: opacity 3s;
}
.a.show {
height: auto;
opacity: 1;
}
.b.show {
height: 100px;
opacity: 1;
}
.c,
.d {
display: none;
}
.c.show,
.d.show {
display: block;
}
.c div {
opacity: 0;
transition: 3s all;
}
.c.show div {
opacity: 1;
}
.d div {
opacity: 0;
}
.d.show div {
animation: fade 3s;
}
#keyframes fade {
from { opacity: 0; }
to { opacity: 1; }
}
.e div {
display: none;
}
.e.show div {
display: block;
animation: fade 3s;
}
.f {
background: transparent;
}
.f div {
background: #000;
display: none;
}
.f.show div {
display: block;
animation: fade 3s;
}
.g {
display: none;
}
<button id="a">A: Box Height: Auto</button>
<div class="a">This<br/>Has<br/>Some Strange<br/><br/>Content<br>But<br>That doesn't really<br>Matter<br/>Because shown,<br/>I'll be<br/>AUTO</div>
<button id="b">B: Box Height: 100px</button>
<div class="b">Content For 2</div>
<button id="c">C: Hidden - Child Transitions (bad)</button>
<div class="c"><div>Content<br/>For<br/>3<br/></div></div>
<div style="clear: both;"></div>
<button id="d">D: Hidden - Child Animates (Better)</button>
<div class="d"><div>Content<br/>For<br/>4<br/></div></div>
<div style="clear: both;"></div>
<button id="e">E: Hidden - Child Hidden & Animates</button>
<div class="e"><div>Content<br/>For<br/>5<br/></div></div>
<button id="f">F: Child Has BG & Animates (Works)</button>
<div class="f"><div>Content<br/>For<br/>5<br/></div></div>
<div style="clear: both;"></div>
<button id="g">G: This uses fadeToggle to avoid this</button>
<div class="g">I animate with<br/>JavaScript</div>
<footer>I'm just the footer to show the bottom of the document.</footer>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Ladies and Gentlemen. I have a #quicklook div.
#quicklook{
height: 500px;
width: 400px;
background: #fff;
position: absolute;
margin-top:5px;
margin-left:15px;
box-shadow: 0 0 5px #BEBEBE;
color:#000;
z-index:100;
display:none;
}
JQUERY
$(document).on('mouseenter','.quicklook-link',function(){
var quicklookLink = $(this);
quicklooktimerShow = setTimeout(function(){
createQuickLook(quicklookLink);
//some ajax request to load content in '#quicklook'
},3000);
}).on('mouseleave','.quicklook-link',function(){
clearTimeout(quicklooktimerShow);
removeQuickLook();
});
function createQuickLook(div){
removeQuickLook();
$('<div>',{
id:'quicklook'
}).append($('<div>',{ id:"quicklook-triangle"})).appendTo(div);
$('#quicklook').show();
}
function removeQuickLook(){
$('#quicklook').remove();
$('#quicklook-triangle').remove();
}
Currently when i hover over .quicklook-link for more than 3s the #quicklook is created
I want Two things to happen.
When i do .mouseenter .quicklook-link if there is not enough space
below the viewport of screen then position the #quicklook above the
.quicklook-link else let it remain below. Just like done in
google+.
Another bug is there as soon as mouse is left from .quicklook-link
the removeQuickLook() function is called and #quicklook is
hidden. But i want few seconds say(3-4s) time's delay to hide that
#quicklook.
For the time delay problem, have you tried to implement this?
http://api.jquery.com/delay/