I would like to add left margin and right margin to the body to hide the width change when I hide the vertical scrollbar.
I have this code that finds the width of the vertical scrollbar:
var $outer = $('<div>').css({visibility: 'hidden', width: 100, overflow: 'scroll'}).appendTo('body'),
widthWithScroll = $('<div>').css({width: '100%'}).appendTo($outer).outerWidth();
$outer.remove();
var scrollbarwidth = 100 - widthWithScroll;
It gives the value "17" (in pixels) for IE11, Chrome 45, and Firefox 39 (desktop).
When I hide the vertical scrollbar, all elements, such as images, jump exactly 17 pixels to the right, which I want to hide.
I have tried:
document.body.style.marginRight = scrollbarwidth + "px";
$('body').css('margin-right', scrollbarwidth);
$(body).css("marginRight", scrollbarwidth + "px");
The last one might be faulty in some way, since other parts of the function stops working when it's enabled. The two others don't seem to work either, as I don't see any margin changes.
EDIT 1: For easier understanding of how I am going to use it, I wanted to mention that it's supposed to trigger on a on scroll function, like this:
var check1 = false;
$(document).bind('scroll', function() {
if(check1 === false && $(window).scrollTop() >= $('#divscrolltester').offset().top + $('#divscrolltester').outerHeight() - window.innerHeight) {
check1 = true;
unloadScrollBars();
disableScroll();
var $outer = $('<div>').css({visibility: 'hidden', width: 100, overflow: 'scroll'}).appendTo('body'),
widthWithScroll = $('<div>').css({width: '100%'}).appendTo($outer).outerWidth();
$outer.remove();
var scrollbarwidth = 100 - widthWithScroll;
//document.body.style.paddingRight = scrollbarwidth + "px"; Temporary disabled.
//$('body').css('padding-right', scrollbarwidth); Temporary disabled.
//$(body).css("marginRight", scrollbarwidth + "px"); Temporary disabled.
setTimeout(function() {
enableScroll();
reloadScrollBars();
//document.body.style.paddingLeft = scrollbarwidth + "px"; Temporary disabled.
//$('body').css('padding-left', scrollbarwidth); Temporary disabled.
//$(body).css("marginLeft", scrollbarwidth + "px"); Temporary disabled.
}, 500);
}
});
EDIT 2:
Here is a Fiddle to show most of the js, html and css: https://jsfiddle.net/tfnwj7dj/10/.
I haven't added the change of css through code yet, as I'm still trying to solve the issue. Also, the scrolling and scrollbar are supposed to be re-enabled in a second, but there seems to be an error in there somewhere, sorry.
EDIT 3:
For your information at this moment, these lines work:
document.body.style.paddingLeft = (scrollbarwidth) + "px";
$('body').css('padding-left', scrollbarwidth);
document.body.style.paddingRight = (scrollbarwidth) + "px";
$('body').css('padding-right', scrollbarwidth);
document.body.style.marginLeft = (scrollbarwidth) + "px";
$('body').css('margin-left', scrollbarwidth);
document.body.style.marginRight = (scrollbarwidth) + "px";
$('body').css('margin-right', scrollbarwidth);
Maybe you have enough information to solve it, if you have the same issue, but unfortunately, this wasn't enough for me. It might be important info to know that I have my content centered with a width / max-width of just 500px, and that I don't actually have a body class. Maybe on designs with width="100%", or elements with absolute positioning, the lines might be enough.
Both javascript and jquery solutions are welcomed.
EDIT 4:
I finally solved it for my own circumstances - feel free to read the answer below. It works for preventing elements to jump when hiding the vertical scrollbar, and with some tinkering, it could probably do for a body class, or other situations.
Is your scrollbarwidth integer? Try this
var scrollbarwidth = 100;
$('body').css('margin-right', scrollbarwidth);
Maybe you have wrong value at scrollbarwidth ? In my ff this code works.
I managed to solve it - I'd like to clarify that my css actually don't contain a body class, and that I just centered all elements with a width / max-width of 500px and margin-left/right auto.
For my and other, similar cases, here is the answer:
/* First 5 lines for finding the scrollbar width. */
var $outer = $('<div>').css({visibility: 'hidden', width: 100, overflow: 'scroll'}).appendTo('body'),
widthWithScroll = $('<div>').css({width: '100%'}).appendTo($outer).outerWidth();
$outer.remove();
var scrollbarwidth = 100 - widthWithScroll;
var scrollbarwidthadjustment = scrollbarwidth / 2; /* For centered elements, divide the scrollbar width by 2. */
var element = document.getElementById('element');
element.style.right = (scrollbarwidthadjustment) + "px";
And when you re-enable the vertical scrollbar, simply add:
element.style.right = "0px";
Also, the element must have a css position stated, otherwise it won't trigger. Here is an example of a css style that works:
.examplestyle {
color: white;
position: relative;
margin-left: auto;
margin-right: auto;
max-width: 100%;
display: block;
}
EDIT 1:
To prevent some unsightly css errors on mobile devices, add these lines:
/* ... */
var scrollbarwidthadjustment = scrollbarwidth / 2;
var windowWidth = $(window).width(); /* Get current window width on click/scroll etc. */
var window1 = windowWidth + scrollbarwidth; /* Window width + scrollbar width. */
var element = document.getElementById('element');
if(window1 >= widthofelement) {element.style.right = (scrollbarwidthadjustment) + "px";}
else {}
EDIT 2:
Fix for image resized smaller than its original size:
var offsetwidth = element.offsetWidth;
var widthadjustment = offsetwidth - scrollbarwidth; /* Get full width of image when scrollbar hidden, and then remove the scrollbar width. */
if(window1 < widthofelement && scrollbarwidth > 0) {
element.style.width = widthadjustment + "px";
element.style.right = (scrollbarwidthadjustment) + "px";
}
And then this code when showing the Y-scrollbar again:
if(window1 < widthofelement && scrollbarwidth > 0) {
element.style.width = "OriginalSizepx";
element.style.right = "0px";
}
If you want to use every edit that I have added, here is the full code:
/* First 5 lines for finding the scrollbar width. */
var $outer = $('<div>').css({visibility: 'hidden', width: 100, overflow: 'scroll'}).appendTo('body'),
widthWithScroll = $('<div>').css({width: '100%'}).appendTo($outer).outerWidth();
$outer.remove();
var scrollbarwidth = 100 - widthWithScroll;
var scrollbarwidthadjustment = scrollbarwidth / 2; /* For centered elements, divide the scrollbar width by 2. */
var element = document.getElementById('element'); /* Put element ID into a variable for easier use, and consecutive uses without re-identifying it. */
var window1 = windowWidth + scrollbarwidth; /* Window width + scrollbar width. */
var offsetwidth = element.offsetWidth; /* Get exact element size in current window. Shows shown dimensions when the window is resized. */
var widthadjustment = offsetwidth - scrollbarwidth; /* Get full width of image when scrollbar hidden, and then remove the scrollbar width. */
if(window1 >= widthofelement) {element.style.right = (scrollbarwidthadjustment) + "px";} /* If current window is equal to or greater than element width... */
if(window1 < widthofelement && scrollbarwidth > 0) { /* If current windows is smaller than the element width, and the window has a scrollbar greater than 0 pixels in width. */
element.style.width = widthadjustment + "px";
element.style.right = (scrollbarwidthadjustment) + "px";
}
/* When re-enabling the Y-scrollbar again; */
if(window1 >= widthofelement) {element.style.right = "0px";}
if(window1 < widthofelement && scrollbarwidth > 0) {
element.style.width = "OriginalSizepx";
element.style.right = "0px";
}
For further clarification, this code will prevent elements from jumping to the right when you hide the vertical scrollbar.
padding is your answer, as Shikkediel said. Just change margin to that and it'll work.
The items move because you change the default margin body has, so the whole body moves to the left (in case we are modifying margin-right).
If you remove the scroll bar, the default margin will go right behind it, and then you need to "buffer" the rest, left of the margin, and that's what padding does.
I really enjoy working with the Inspecting tool Chrome supplies (Ctrl + Shift + I) and then in the Styles tab on the right scorll down until you see the measurements. It really helps understand the CSS box model.
Did you add 'px' here..
$('body').css('margin-right', scrollbarwidth+'px')??
Just nowI tried in w3schools. If you add 'px' to above syntax, it is working for me.
I have a page with a simple div. If the div is at the top of the page, the background image (a very long vertical wallpaper) should also only be displaying the top section. If we scroll all the way down, then at the last area way at the bottom, the bottom of the background will show. The effect is that it's like a parallax where the scrolling of the content and background image occur in tandem and are scaled to each other.
How would I do this?
Update: My attempt is something like this:
function setupMainContent(){
$("#programming").delay(1000).fadeIn(1000, function(){
$(window).scroll(function(){
var current = $(window).scrollTop();
var bottom = $(document).height() - $(window).height();
var scale = 100*(current/bottom);
$('body').css({
'background-position':scale+'%'
});
});
}
I don't really know how to work with variables within quotes however.
Update: I got it to work using this:
function setupMainContent(){
$("#programming").delay(1000).fadeIn(1000, function(){
$(window).scroll(function(){
var current = $(window).scrollTop();
var bottom = $(document).height() - $(window).height();
var scale = 100*(current/bottom) + "%";
document.body.style.backgroundPosition = "center " + scale;
});
});
}
But there seems to be very bad impact on performance. Is there any way to make it more responsive and faster?
CSS:
background-attachment: fixed;
https://developer.mozilla.org/en-US/docs/Web/CSS/background-attachment
This worked for me:
function setupMainContent(){
$("#programming").delay(1000).fadeIn(1000, function(){
$(window).scroll(function(){
var current = $(window).scrollTop();
var bottom = $(document).height() - $(window).height();
var scale = 100*(current/bottom) + "%";
document.body.style.backgroundPosition = "center " + scale;
});
*/
});
}
I have a problem with a JavaScript I'm developing for my website. I have images which opens on hovering over them.
First my script calculates if the image should be displayed on the right or on the left of my window:
$("html,body").live("mousemove", function (e) {
//console.log("mousemove: "+e.pageX)
var width_window = $(window).width();
var center = width_window / 2;
if (e.pageX < center) {
side = 'left';
} else {
side = 'right';
}
});
Then, once we know on which side of the window the image will be displayed, I have another script to resize the image, depending of the height & width of my window, including the margins:
this.resizeImg = function (img, offset) {
var d = new Date();
//console.log(d, side);
var window_height = $(window).height();
var img_height = $(img).height();
var img_top = $(img).offset().top;
var window_width = $(window).width();
var img_width = $(img).width();
var img_left;
side == 'left' ? img_left = offset.left : img_left = window_width - offset.left;
console.log(window_width, img_left)
var image_resize_height = window_height - img_top - 20;
var image_resize_width = window_width - img_left - 20;
if (img_height + img_top > window_height && img_width + img_left > window_width) {
console.log("h w")
if (image_resize_width > image_resize_height) {
$(img).css('height', image_resize_height + 'px').css("width", "auto");
} else {
$(img).css('width', image_resize_width + 'px').css("height", "auto");
}
} else if (img_height + img_top > window_height) {
//console.log("h")
$(img).css('height', image_resize_height + 'px').css("width", "auto");
} else if (img_width + img_left > window_width) {
//console.log("w")
$(img).css('width', image_resize_width + 'px').css("height", "auto");
} else {
//console.log("non")
}
};
It almost works, but sometimes my images exceed the window width or height. I can't find the solution...
Here is my CSS:
.vignette {
max-height: 800px;
max-width : 800px;
z-index : 2;
top : 25px;
}
.info{
position : relative;
}
.info img {
position : absolute;
display : none;
cursor : pointer;
}
My full script in jsFiddle: http://jsfiddle.net/CrnNZ/
Here is the link to my website : http://olivierlellouche.com/
Thanks a lot for your help !
Are you taking care of the fact that you are moving the image down 25px in:
.vignette {
top : 25px;
}
The only height adjustment I see is 20px:
var image_resize_height = window_height - img_top - 20;
You may just need to subtract few more pixels to your calculations?
Or better yet:
var img_top = $(img).offset().top;
May be top of the offset area and not the raw top of the image. In which case, you still need to subtract 25px for that.
(From your website) The other thing that may be useful is to always enable, or always disable the vertical scroll-bar on the right. Or re-size the text area to be smaller than the available area when their isn't a scroll-bar. (Unfortunately, I could not get your jsfiddle to work at all and the only error from their I could view was vertical calculation errors. I could not see any horizontal errors.)
Does the problem continue if you subtract a few more pixels off the height?
I can't tell from your code but, does it place the image then re-size it? It may be better idea to calculate the size available before trying to place the image, that way it never changes sizes once it is placed.
EDIT:
After looking at your webpage with much smaller sized window I thought of something else. $(window).height() is not the same as $(document).height(). See: $(window).height() vs $(document).height You may need to calculate the remaining page differently if they are not the same.
I am trying to set my gridview (asp.net) position to absolute when the gridview stretches further than the standard 960 pixels.
However I have run across the issue where left: 0 has the effect I desire, however anything other than that does nothing.
Here is my code. The section where it's less than the screen doesnt work because i am trying to center it to the screen. However as it's greater than 0 the absolute position of Left: x doesn't work. Any help would be appreciated!
var gridview = document.getElementsByTagName("table");
var fieldset = document.getElementsByTagName("fieldset");
fieldset[0].style.position = "relative";
for (var i = 0; i < gridview.length; i++) {
var width = gridview[i].offsetWidth;
var screenWidth = window.screen.width - 2;
if (width > 940) {
gridview[i].style.position = "absolute";
if (width > screenWidth) {
gridview[i].style.left = 0;
alert('> screen');
}
else {
gridview[i].style.left = 50;
alert('< screen');
}
}
}
EDIT: The fix was to concat 'px' after the value
Not really go enough to go on, but it might be the case that the container of gridview hasn't had its position set your css.
To use the postion:absolute the above container should be set to position:relative or it just wont render the css.
Also try adding px to the end of your size, setting the css to left:XXpx; rather than just a number.
The code: http://jsfiddle.net/LPF85/6/
In FF, IE7, and IE9 (the only browsers I've tested that don't run WebKit), it seems that the left attribute is either always set to 0, or, in IE's case, negative.
My positioning code is all based off the dimensions of the document.
function open_img_in_face_box(id, width){
max_width = $j(document).width();
max_height = $j(document).height();
padding = 150;
passed_width = width || (max_width - (2 * padding));
var img = $j('#' + id);
dom_img = document.getElementById(id);
$j(document).bind('reveal.facebox', function() {
$j("#facebox .image img").width(passed_width);
})
// display
jQuery.facebox({
image: img.attr('src')
});
// center and adjust size
var aspect_ratio = img.width() / img.height();
var img_width = passed_width;
var img_height = passed_width / aspect_ratio;
window_center_y = max_height / 2;
window_center_x = max_width / 2;
offset_y = window_center_y - (img_height / 2);
offset_x = window_center_x - (img_width / 2);
var fbx = $j('#facebox');
fbx.css('position', 'absolute');
fbx.css('left', offset_x + 'px !important');
fbx.css('top', offset_y + 'px !important');
fbx.css('margin-left', 'auto');
fbx.css('margin-right', 'auto');
}
margin-left and margin-right don't appear to do anything here, which I'm fine with, because the left math should work across all browsers, right? (It is just math)
The goal of the facebox / lightbox, is to be centered both horizontally and vertically.
Why would you even programatically calculate the position in the first place? What if the user resizes the page? This can easily be done in pure CSS.
I don't really understand your jsFiddle (or am I not seeing the same thing?) so I'll just give you this script: http://jsfiddle.net/minitech/8U4Ke/ that can be modified however you like. It's commented. ;)
Now it's easy to hide and show - to hide, fade out .overlay. To show, fade it in. To change the contents, replace the HTML in .popup. Add close boxes and whatnot liberally.