The website I am building has 4 large background images that take up the entire height and width of the user's browser. They are implemented as CSS background divs. The problem is, when scrolling on larger screen sizes, it is very laggy and choppy. Scrolling between these images is done automatically via JavaScript when the user presses a button, so this is part of the core functionality of my website and I must find a way to prevent lag.
So far, I have tried preloading the images via JS and converting the images from PNG to JPEG (increase compression and decrease quality) server-side. Neither of these worked.
The minimum height of the image can be 630 pixels. How can I prevent lag while scrolling between sections?
Here's my code:
CSS:
body { height: 100%; margin: 0px; font-family: HelveticaNeue, Helvetica, Arial, sans-serif; }
.area { height: 630px; border: 0px solid red; background: repeat-x; margin-bottom: 0px; }
a { text-decoration: none; }
h1, h2, h3, h4, h5, h6 { font-family: Av, Helvetica, Arial, sans-serif; color: #292E37; font-weight: lighter; }
#top { position: fixed; width: 100%; height: 10%; background: #292E37; box-shadow: inset 0px -1px 5px #000; z-index: 1000; }
#navigation { float: right; height: 100%; }
#bottom { width: 100%; position: fixed; bottom: 0px; padding: 10px; background: #292E37; box-shadow: inset 0px 1px 5px #000; text-shadow: 0px 1px 0px #000; color: #fff; }
#sceneSelection { top: 20%; position: fixed; padding: 10px; }
#info { margin-top: 50px; margin-bottom: 50px; }
.box { margin-top: 50px; padding: 75px; background: #292E37; box-shadow: inset 0px 1px 5px #000; text-shadow: 0px 1px 0px #000; color: #fff; }
.nav { position: relative; top: 38%; height: 100%; margin-right: 35px; display: inline-block; color: #fff; text-shadow: 0px 1px #000; }
.nav:hover { color: #EA5555; }
.nimage { float: left; width: 16px; height: 16px; position: relative; top: 5%; left: -20%; }
.home { background: url(site_images/icons/nav/home.png); }
.pricing { background: url(site_images/icons/nav/pricing.png); }
.features { background: url(site_images/icons/nav/features.png); }
.blog { background: url(site_images/icons/nav/blog.png); }
.contact { background: url(site_images/icons/nav/contact.png); }
.about { background: url(site_images/icons/nav/us.png); }
.logo { font-size: 2em; text-shadow: 0px 1px #000; padding-top: 10px; padding-left: 15px; color: #EA5555; font-family: Av, Helvetica, Arial, sans-serif; }
.red { color: #EA5555; }
.white { color: #fff; text-shadow: 0px 1px 0px #000; font-weight: bold; }
.dark { color: #202020; }
.center { text-align: center; }
.left { text-align: left; }
.right { text-align: right; }
.larger { font-size: 1.25em; }
.buttoni { -webkit-border-radius: 2px; -moz-border-radius: 0px; border-radius: 4px; background: #ddd; display: block; color: #ccc; font-size: 14pt; height: 50px; text-align: right; margin: 10px; cursor: pointer; color: #505050; }
.buttoni:hover { background: #EA5555; color: #fff; }
.btext { padding: 15px; position: relative; top: 25%; }
.groundi { background: url(ground_button.png); }
.skyi { background: url(sky_button.png); }
.stratospherei { background: url(stratosphere_button.png); }
.spacei { background: url(space_button.png); }
.image { height: 50px; width: 50px; float: left; border-top-left-radius: 5px; border-bottom-left-radius: 5px; }
li { color: #EA5555; }
li span { color: #505050; }
HTML:
<div class="space area" id="a4">
</div>
<div class="stratosphere area" id="a3">
</div>
<div class="sky area" id="a2">
</div>
<div class="ground area" id="a1">
</div>
JavaScript:
function scroll_to(id, speed, margin) {
$('html, body').animate({
scrollTop: $('#' + id).offset().top - margin
}, speed);
}
function match_height() {
var heights = [11, 630, 693, 756, 819, 882, 945, 1008, 1071, 1134, 1197, 1260, 1323, 1386, 1449, 1512, 1575, 1638, 1701, 1764, 1827, 1890, 1953, 2016, 2079, 2142, 2205, 2268, 2331, 2394, 2457, 2520];
var browsery = $(window).height();
var i = 0;
while(browsery > heights[i]) {
i++;
}
var h = heights[i];
$(".area").css("height", h + "px");
$(".area").css("width", "100%");
$(".ground").css("background", "url(scenes/ground/" + h + ".png)");
$(".sky").css("background", "url(scenes/sky/" + h + ".png)");
$(".stratosphere").css("background", "url(scenes/stratosphere/" + h + ".png)");
$(".space").css("background", "url(scenes/space/" + h + ".png)");
}
match_height();
var pos = 0;
$(".buttoni").click(function() {
var id = $(this).attr("id");
if(pos != id) {
scroll_to("a" + id, 2000, 0);
}
pos = id;
});
OP,
For browsers that support 3d transforms, e.g.: -webkit-transform, you could try the following:
your.div { -webkit-transform: translate3d(0,0,1px); }
Might not look like much, but doing the above causes the div in question to be hardware-accelerated.
Should you run into any flickering issues—they've been known to turn up in some cases—the following should sort you out:
your.div {
-webkit-transform: translate3d(0,0,1px);
-webkit-backface-visibility: hidden;
}
Via David Walsh - http://davidwalsh.name/translate3d
The use of translate3d pushes CSS animations into hardware acceleration. Even if you're looking to do a basic 2d translation, use translate3d for more power! If your animation is still flickering after switching to the transform above, you can use a few little-known CSS properties to try to fix the problem
Hope that helps.
As per my understanding, the issue and the solution drafted in the OP is two-fold:
initially, within the match_height() function, the OP author retrieves the images that best fits the screen height, so that upon completed animation the user sees one full background image.
after initial load, the user can navigate up and down the sections (with their respective background images) with the help of some buttons that trigger the scroll_to() function and its contained animation. Here is where the actual problem resides.
My efforts and the resulting fiddle focus on the scroll_to() function and the associated animation. I applied the following measures that, in conjunction, result in a (as per my subjective observation) 'smoother' scolling experience:
the original animation happened against 'html' and 'body', I'm reducing the jQuery selector to one selector only. In order to be able to use jQuery 1.9 (where jQuery.browser is deprecated) I'm using feature detection to get the 'right' selector:
function getScrollerSelector() {
var $body = $("<body/>");
$body.scrollTop(1);
return $body.scrollTop() == 1 ? "body" : "html";
}
In order to reduce the browser's processing load, I'm applying a logic that, per CSS, sets the background image of invisible sections to none during scrolling:
.scrolldown.scrollto-a2 #a1,
.scrolldown.scrollto-a3 #a1, .scrolldown.scrollto-a3 #a2,
.scrolldown.scrollfrom-a3 #a4,
.scrolldown.scrollfrom-a2 #a4, .scrolldown.scrollfrom-a2 #a3,
.scrollup.scrollto-a3 #a4,
.scrollup.scrollto-a2 #a4, .scrollup.scrollto-a2 #a3,
.scrollup.scrollfrom-a2 #a1,
.scrollup.scrollfrom-a3 #a1, .scrollup.scrollfrom-a3 #a2
{ background: none; }
I played around with linear easing, but that did not necessarily improve anything
All in all, scrolling doesn't seem choppy to me any more, but please take into account that this is also dependent on the client computers processing power.
Here's the scroll_to() function:
function scroll_to(id, speed, margin) {
var currentScrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
var scrollTop = $('#' + id).offset().top - margin;
var direction = scrollTop > currentScrollTop ? "down" : "up";
$("body").addClass("scroll"+direction + " scrollto-"+id + " scrollfrom-"+getScrollFrom(direction));
$( scrollerSelector ).animate({
scrollTop: scrollTop
}, {
//easing: 'linear',
duration: speed,
complete: function() {
$("body").removeClass("scrollup scrolldown scrollto-a1 scrollto-a2 scrollto-a3 scrollto-a4 scrollfrom-a1 scrollfrom-a2 scrollfrom-a3 scrollfrom-a4");
}
}
);
}
This is the link to jsfiddle
Since you are Scaling up the image, you can tell the Browser how to handle the rendering of image.
During the animation / scrolling, you can tell browser to Optimize on Speed and on completion of Animation / scrolling, Optimize on Quality.
Here is the CSS Property you can use on img: 'image-rendering' with values as optimizeSpeed / optimizeQuality.
https://developer.mozilla.org/en-US/docs/CSS/image-rendering
One thing you could do to images is smush it using http://www.smushit.com/ysmush.it/
this reduces the size of the image without loosing quality removing all unwanted meta data.
Testing locally it seems like your code should work ok, I have firefox 15 and chrome and don't see any lagging
What if you try this for the scroll to method?
function scroll_to(id, speed, margin) {
$('html, body').animate({
scrollTop: $('#' + id)
}, speed);
}
I had a similar problem with a website I was working on. In the end the problem seemed to be because of the large dimensions of the image that the computer/browser had to compute and render on screen.
My recommendation would be to try and reduce the amount of image that needs to be shown and scrolled on screen if possible.
Most modern browsers now support hardware (graphics card) rendering instead of the traditional (usually slower) software based (CPU) rendering. Hardware based rendering should in theory reduce that lag you're experiencing. However if your PC only has base or average graphics rendering capabilities, you're not going to have much success regardless. I personally had no success with either in Chrome, FireFox or IE until I gave in and removed the images.
Related
I am trying to make a div element which when scrolled down will change properties drastically. Here is the codepen example of how I want it to work.
Instead of hover I want it so that when scrolled down, the page wide div will turn into that little circle div which when clicked will function as a back to the top button. It doesn't matter if more classes are added or anything of that sort. I am very new to js and I tried a few things and also googled about it, I got the scroll code from w3school's how to make a back to top button guide which specifies that when scrolled down by 20px the code would react, but I don't know how to turn the JavaScript to JS when scrolled down along with the transformation of the div.
Thanks in advance
I think you want to implement scroll to top functionality, very common these days in most of the web app.
You need to keep below things and design that feature.
There is one header, that should have a reference ID with hash to scroll back to top
Create a button that will always static position (JS) button, will show up when user scroll the window
Bind click event on the button that scroll back to top
Here is the you can see this implementation and use it.
.html
<h1 class="intro-copy">
Scroll down to use this simple back-to-top button made with modern vanilla javascript.
</h1>
<a class="top-link hide" href="" id="js-top">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 6"><path d="M12 6H0l6-6z"/></svg>
<span class="screen-reader-text">Back to top</span>
</a>
.css
body {
height: 2000px;
position: relative;
}
.intro-copy {
padding: 1em;
margin: 50vh auto;
max-width: 15em;
font-family: Helvetica;
font-weight: lighter;
font-size: 2em;
line-height: 1.2;
text-align: center;
}
.top-link {
transition: all .25s ease-in-out;
position: fixed;
bottom: 0;
right: 0;
display: inline-flex;
cursor: pointer;
align-items: center;
justify-content: center;
margin: 0 3em 3em 0;
border-radius: 50%;
padding: .25em;
width: 80px;
height: 80px;
background-color: #F8F8F8;
&.show {
visibility: visible;
opacity: 1;
}
&.hide {
visibility: hidden;
opacity: 0;
}
svg {
fill: #000;
width: 24px;
height: 12px;
}
&:hover {
background-color: #E8E8E8;
svg {
fill: #000000;
}
}
}
// Text meant only for screen readers.
.screen-reader-text {
position: absolute;
clip-path: inset(50%);
margin: -1px;
border: 0;
padding: 0;
width: 1px;
height: 1px;
overflow: hidden;
word-wrap: normal !important;
clip: rect(1px, 1px, 1px, 1px);
&:focus {
display: block;
top: 5px;
left: 5px;
z-index: 100000; // Above WP toolbar
clip-path: none;
background-color: #eee;
padding: 15px 23px 14px;
width: auto;
height: auto;
text-decoration: none;
line-height: normal;
color: #444;
font-size: 1em;
clip: auto !important;
}
}
JS:
// Set a variable for our button element.
const scrollToTopButton = document.getElementById('js-top');
// Let's set up a function that shows our scroll-to-top button if we scroll beyond the height of the initial window.
const scrollFunc = () => {
// Get the current scroll value
let y = window.scrollY;
// If the scroll value is greater than the window height, let's add a class to the scroll-to-top button to show it!
if (y > 0) {
scrollToTopButton.className = "top-link show";
} else {
scrollToTopButton.className = "top-link hide";
}
};
window.addEventListener("scroll", scrollFunc);
const scrollToTop = () => {
// Let's set a variable for the number of pixels we are from the top of the document.
const c = document.documentElement.scrollTop || document.body.scrollTop;
// If that number is greater than 0, we'll scroll back to 0, or the top of the document.
// We'll also animate that scroll with requestAnimationFrame:
// https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
if (c > 0) {
window.requestAnimationFrame(scrollToTop);
// ScrollTo takes an x and a y coordinate.
// Increase the '10' value to get a smoother/slower scroll!
window.scrollTo(0, c - c / 10);
}
};
// When the button is clicked, run our ScrolltoTop function above!
scrollToTopButton.onclick = function(e) {
e.preventDefault();
scrollToTop();
}
First of all, you can find a simplified demo of my code in this JSFiddle and also below the question. I found that my problem happens the way I describe it in Google Chrome, so if you plan to try and fix the bug, please use that browser. I apologize if the code is not very well simplified; please consider that this is a snippet from a bigger project.
I'm working on a webapp that uses JQuery and GreenSock's TweenLite for animations.
This app consists on some menus that control everything, that are transitioned between using the bodyChange() function. This function has two parameters:
nextOrPrev, that runs one animation or another based on the value
provided ("next" or "prev"). Only the "next" animation is done yet, but that is not important for now. The "prev" animation, not yet used, just emits an alert("prev").
bodyFunction. The function provided will fill the body with the elements necessary for that menu, and the wrap them in a #bodyWrap.
In the demo I provide you with there are only two menus: The first one, mainMenu, with only a #playButton. When you click it, the bodyChange() function is called with the following parameters: ("next", playSettingsBody), playSettings being the second menu.
This is the problem: when you click the playButton, the button goes up a on the screen and then executes the TweenLite animation. I can't see, however, why does the button "jump up", instead of staying in the same place and execute the animation. This is probably due to a small mistake. What is it?
Thanks for any help.
mainMenuBody();
function mainMenuBody() {
$("body").append(
//BUTTONS
"<div id='playButton' class='mainButton'><div class='buttonText mainButtonText text'>PLAY</div></div>"
);
//WRAP
$("body").wrapInner("<div id='bodyWrap'></div>");
//BINDS
$("#playButton").bind("click", function() {
bodyChange("next", playSettingsBody);
});
}
function bodyChange(nextOrPrev, bodyFunction) {
switch (nextOrPrev) {
case "next":
//ANIMATION AND BODY CHANGE
TweenLite.to($("#bodyWrap"), .4, {
ease: Power2.easeIn,
transform: "rotateY(90deg)",
onComplete: function(){
$("body").empty();
//NEW STUFF
bodyFunction();
TweenLite.from($("#bodyWrap"), .4, {
ease: Power2.easeOut,
transform: "rotateY(90deg)"
});
}
});
//END OF ANIMATION AND BODY CHANGE
break;
case "prev":
alert("prev");
}
}
function playSettingsBody() {
$("body").append(
"<p class='text' id='CYTText'>This is the second menu!</p>"
);
}
body{
background-image: url("../resources/pics/Vignette2.png");
background-repeat: no-repeat;
background-position: center center;
background-attachment: fixed;
background-color: #02BFC1;
overflow:hidden;
margin: 0;
}
.text {
color: #FFFFFF;
font-family:Bebas Neue;
-webkit-user-select: none;
cursor: default;
text-shadow: 3px 3px 2px rgba(0,0,0,0.2);
}
.mainButton {
-webkit-transform:scale(1);
width: 200px;
height: 200px;
border: 10px solid #F1F2F0;
text-align:center;
background-color: #F37C2B;
/*background:#5F4A21;*/
display: table;
position: absolute;
margin: auto;
top: 150px;
bottom: 0;
-webkit-transition: all 0.5s ease;
cursor: pointer;
box-shadow: 0px 0px 30px rgba(0,0,0,0.4);
}
.mainButtonText {
position: relative;
display:table-cell;
vertical-align:middle;
-webkit-transform:scale(1);
font-size: 90px;
text-shadow: 4px 4px 2px rgba(0,0,0,0.2);
-webkit-transition: all 0.5s ease;
}
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>
This problem is caused in your .mainButton class. Your code looks a little like this.
.mainButton {
position: absolute;
top: 150px;
bottom: 0;
//rest
}
By removing the line bottom: 0; your JSFiddle now works as expected. However, if you remove the line top: 150px; instead and leave in the bottom: 0 the problem still occurs. Unfortunately, I cannot provide an explanation for this. It might be worth posting a question on the GSAP forums inquiring about why this occurs works when positioning using bottom but not when using top
Edit
Since you need bottom: 0 and I wasn't able to fix your code I wrote an example which works using Timeline, a GSAP plugin. You can see this JSFiddle or the code example below.
var tl = new TimelineMax();
tl.pause();
tl.fromTo($("#click"), 1, {rotationY: 0, ease: Power2.easeOut}, {rotationY: 90, transformOrigin:"right", ease: Power2.easeOut})
.set($("#click2"), {css:{display: "table"}}, "-=0.6")
.fromTo($("#click2"), 1, {rotationY: -90, ease: Power2.easeOut}, {rotationY: 0, transformOrigin:"left", ease: Power2.easeOut}, "-=0.6");
$("#click").click(function() {
tl.play();
});
$("#click2").click(function() {
tl.reverse();
});
* {
margin: 0;
padding: 0;
}
body {
background-image: url("../resources/pics/Vignette2.png");
background-repeat: no-repeat;
background-position: center center;
background-attachment: fixed;
background-color: #02BFC1;
overflow: hidden;
}
div.one, div.two {
position: absolute;
bottom: 0;
height: 200px;
width: 200px;
background: #F37C2B;
text-align: center;
display: table;
cursor: pointer;
border: 10px solid #F1F2F0;
}
div.one .text, div.two .text {
position: relative;
display: table-cell;
vertical-align: middle;
color: #FFFFFF;
font-family: Bebas Neue;
font-size: 90px;
}
div.two {
display: none;
border-color: transparent;
background: none;
}
div.two .text {
font-size: 40px;
}
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>
<div id="click" class="one">
<div class="text">
Play
</div>
</div>
<div id="click2" class="two">
<div class="text">
Second Menu
</div>
</div>
I am making a Ruler scale using html, css, js, whose length is supposed to be fixed always. On clicking the scale, between any two bars, a prompt will be generated and the user will then input a number which signifies the no. of sections by which the scale length (between any two bars) will be divided in equal parts and get displayed on it.
e.g. if initially the scale is |_____|_____|_____| , then on clicking 2nd bar and entering divide by 2, the scale should look like|_____|__|__|_____|
I referred to the following link for making the ruler:
How to make a ruler scale in HTML and CSS
But in the answer given in the above link, the user has to manually change the value of the "data-items" attribute, to make different no. of sections every different time, and also, on changing its value, the overall size of the scale also increases, which contradicts my case.
This is what I have coded so far and I really don't know how to split any bar on user input without changing the overall length.
https://jsfiddle.net/yoshi2095/pvjhLggz/9/
HTML:
<div>
<ul class="ruler" data-items="10"></ul>
</div>
CSS:
.ruler, .ruler li {
margin: 0;
padding: 0;
list-style: none;
display: inline-block;
}
/* IE6-7 Fix */
.ruler, .ruler li {
*display: inline;
}
.ruler {
background: lightYellow;
box-shadow: 0 -1px 1em hsl(60, 60%, 84%) inset;
border-radius: 2px;
border: 1px solid #ccc;
color: #ccc;
margin: 0;
height: 3em;
padding-right: 1cm;
white-space: nowrap;
}
.ruler li {
padding-left: 1cm;
width: 2em;
margin: .64em -1em -.64em;
text-align: center;
position: relative;
text-shadow: 1px 1px hsl(60, 60%, 84%);
}
.ruler li:before {
content: '';
position: absolute;
border-left: 1px solid #ccc;
height: .64em;
top: -.64em;
right: 1em;
}
/* Make me pretty! */
body {
font: 12px Ubuntu, Arial, sans-serif;
margin: 20px;
}
div {
margin-top: 2em;
}
JS:
function inputNumber() {
var inputNum = prompt("Divide by");
$("a").attr("data-items",inputNum);
}
$(function() {
// Build "dynamic" rulers by adding items
$(".ruler[data-items]").each(function() {
var ruler = $(this).empty(),
len = Number(ruler.attr("data-items")) || 0,
item = $(document.createElement("li")),
i;
for (i = 0; i < len; i++) {
ruler.append(item.clone().text(i + 1));
}
});
});
Any help would be greatly appreciated. Thanks.
I'am serching solution in google. And saw some solutions to this but noone help me. When i asking in chrome about height(). It returns me true value, it's 1627. But when i write in script where it will be changed to this. It returns me 1290. And i don't know why. How can i return true height from document (because window can't help me). I'am trying with height(), innerHeight() and outerHeight().
Here is a screen with my problem: http://www.speedyshare.com/hTUDt/1.png
$(document).ready(function(){
var menu = $("#menu").height();
var content = $("body").outerHeight(true);
if(menu != content)
{
menu = content;
$("#menu").css({'height':menu+'px'});
}
});
or like this
$(document).ready(function () {
var menu = $('#menu');
$(window).resize(function () {
var height = $('#body').height();
menu.css({
'height': height + 'px',
});
}).trigger('resize');
});
It's doesn't work.
In css i have :
#menu {
width: 15%;
/*height: 100%;*/
background: #F5F5F5;
padding-top: 1%;
/* padding-bottom: 1%; */
font-size: 1.6rem;
font-family: 'Lato';
font-weight: 300;
color: #969696;
position: absolute;
border-right: 1px solid #c5c5c5;
box-shadow: 0px -1px 0px 1px #fff;
}
In firebug i see what's happend. He takes a height value 1290 (I don't know why) instead real height of body or 1626
$('element').css('height', 'auto !important')
Note: auto can be 100% or a fixed number (i.e '1626px')
I have a little problem with a jQuery animation.
I have the following HTML:
<div id="menu">
<a id="menu-about" href="/">A riguardo...</a><br />
<a id="menu-ask" href="/">Fammi una domanda</a><br />
<a id="menu-archive" href="/">Sfoglia l'archivio</a><br />
<a id="menu-vcard" href="/">La mia vCard</a><br />
<a id="menu-lifestream" href="/">Il mio lifestream</a><br />
</div>
Styled as:
div#menu {
position: fixed;
bottom: 0;
left: 100%;
padding: 0;
}
div#menu a {
display: inline-block;
height: 20px;
margin: 0 0 10px -42px;
padding: 6px 0 6px 42px;
line-height: 20px;
font: bold 20px "Arial", Helvetica, sans-serif;
color: #263F51;
text-shadow: 0 -1px 0 #213441, 0 1px 1px #668EAA;
text-align: left;
text-transform: uppercase;
}
div#menu a:hover {
text-decoration: none;
}
div#menu a#menu-about { background: url(../img/layout/bg-menu-about.png) no-repeat left center; }
div#menu a#menu-ask { background: url(../img/layout/bg-menu-ask.png) no-repeat left center; }
div#menu a#menu-archive { background: url(../img/layout/bg-menu-archive.png) no-repeat left center; }
div#menu a#menu-vcard { background: url(../img/layout/bg-menu-vcard.png) no-repeat left center; }
div#menu a#menu-lifestream { background: url(../img/layout/bg-menu-lifestream.png) no-repeat left center; }
The animation is the following:
$(function start_menu_effect() {
$("div#menu a").hover(function (){
$(this).stop().animate({'marginLeft': '-' + ($(this).width() + 52) + 'px'}, 400);
},
function (){
$(this).stop().animate({'marginLeft': '-42px'}, 400);
});
});
The problem is that the animation ends prematurely. The animate function stops before reaching the full margin. Furthermore, the animation can be completed de-hovering and re-hovering the mouse before the menu returns to the original position...
EDIT - the problem seems to be related to the width, that isn't correct. I create a fiddle to demonstrate the problem: http://jsfiddle.net/cyrusza/fJCyn/
Any hints?
Fond a solution.
The container div, when placed outside of the document (left: 100%), doesn't expand itself as it would in a normal placement, because it hasn't the rightmost margin as reference. Therefore is necessary to set a fixed width to let the inner elements expand normally and get a correct width. Obviously the div width must be bigger than the inner elements, then we need to use an adequate value.
This is the working fiddle with a div width of 500px: http://jsfiddle.net/cyrusza/fJCyn/2/