Preventing relayout due to scrollbar - css

How can I prevent the body of the page being "pushed" to the left when a scrollbar appears due to ajax content?
I can of course set overflow:scroll to the body, but it wouldn't look nice.
I am using bootstrap, but I guess it is a general question.

overflow: overlay
Building on avrahamcool's answer, you can use the property overflow: overlay.
Behaves the same as auto, but with the scrollbars drawn on top of content instead of taking up space. Only supported in WebKit-based (e.g., Safari) and Blink-based (e.g., Chrome or Opera) browsers.
Source: MDN
This is great for when you need horizontally-scrolling content and don't want it to change size when scrollbars appear on hover.
Caveat: it is deprecated. Support is pretty much limited to Chromium, but that might go away in the future. See https://caniuse.com/css-overflow-overlay.
However, you can do a fallback of auto:
.container:hover {
overflow: auto; /* fallback */
overflow: overlay;
}
Demo: jsfiddle.net/NKJRZ/385/
Can I Use also has an interesting note:
This value is deprecated and related functionality being standardized as the scrollbar-gutter property.
However, you should check their link because browser support for this experimental feature is no better than overflow: overlay as of November 2021.

You can create a container that have a fixed width, and give the content the same width (same static width - not 100%).
that way, when the content overflows the parent, the scroll will not push the content but will flow above it.
using that, you can apply a cool way to scroll without pushing anything. by showing the scroll only when you hover the container.
Check out this simple Demo
EDIT:
Here I show the difference between setting static width, and %.

Well, the scrollbar will always push your content aside, there is really nothing you can do about that. What you can do is to always show to scrollbar for example:
html,body {
height:101%;
}
or
html {
overflow-y: scroll;
}

The best way to do this is assign value 'overlay' to overflow property. This works fine.
overflow-y: overlay;

In my case, I was getting an annoying pop event on my navbar whenever the scrollbar appears, but applying position fixed on my nav solved it for me.

Related

-webkit-overflow: touch; stops working when tapping on element outside of scroll container

I have a really big bug on the iphone, that makes a page unusable and I just can't solve it. I can't find any topic about this issue as well.
I have the following screen:
In the middle, there is a div, which is set on -webkit-overflow: auto; to have smooth scrolling inside this div. The scrolling is working absolutely fine and smooth.
BUT only until I do a touchmove on another element outside of this div. If I do this and try to scroll the scrollcontainer again, it's frozen and not moving at all. After I tap around a few times on the scroll container it's scrolling again.
It's losing the scroll focus of the scroll container and trying to scroll a parent.
So, if I do a movement like this:
This looks like this :
Note: I'm just doing one touchmove from the bottom container into the overflow div. After releasing the finger and then trying to scroll again, it still scrolls the parent div.
I made a short example, so you can have a look with your iphone/phone here.
This issue only appears when using -webkit-overflow: auto With normal overflow: scroll it's always working but yes... you know how laggy this scrolling feels.
Is there any way to force the scroll focus in the desired container, when you're clicking/tapping a container with -overflow-scrolling: touch;?
The iOS Safari Browser never really gives you full control over the scrolling.
However there is a "hack" you can use, it requires JS tho:
set position: fixed on body,html
As soon as a touchmove occurs, set the body.scrollTop = 0
So in your case add:
CSS
body, html {
margin: 0;
position: fixed;
}
JS
document.addEventListener('touchmove',function (){
document.body.scrollTop = 0
})
Example page for testing on device
Btw, a better way for handling this would be to make the headline/controls fixed and add a padding to the scrollcontainer. This wouldnt require any JS.
try it
I too had this issue, my website worked fine on android phones, but on ios, i had to tap few times, to activate scroll.
I tried disabling body scroll, even tried this
-webkit-overflow-scrolling: touch; /* Lets it scroll lazy */
-webkit-overflow-scrolling: auto; /* Stops scrolling immediately */
I had to use custom scrollbar plugin mCustomScrollbar
This plugin completely overrides the system scroll. Here javascript controls the positioning of the scroll content. It makes the content position:relative and uses top to scroll the content.
If this plugin doesn't work for you, you can try any other scroll plugin. They all work the same way.

CSS Challenge: INPUT going outside of DIV

I'm trying to accomplish something specific around platform constraints I'm under.
I created a somewhat self-explanatory jsfiddle of the problem at http://jsfiddle.net/MrV5M/4/
The specific problem:
On Chrome, the right border of the input box is cut off.
On Safari, the width of the content class cell exceeds the container so it spills over the border.
On IE9, the label doesn't float to the left of the content div
The main reason I care about Safari is because I'm working on a JQuery Mobile/PhoneGap app which is also a web app. I'm only supporting modern browsers, but this is driving me nuts. Normally I'd just use a table for the container, but the text-overflow: ellipsis styles on the content div don't work when inside a table. (Basically, I'm trying to keep the content to a single line and have ellipsis without enforcing a fixed width or calculating a width with Javascript)
Anyone have the l33t CSS skills to make this work? I sure don't... :)
Just add this CSS to your Stylesheet, and get peace of mind on your issue :D
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
You may not like this answer. I made some adjustments in the css which fixes Chrome and IE9 issues. Take a look,
http://jsfiddle.net/MrV5M/11/
There are many ways to do what you are trying to do, but if you insist on using 'flex' stuff which is largely un-supported (even in the majors see here), you'll need to add the vendor prefixes to flex.
e.g... -webkit-flex, -moz-flex
Also, I don't think you need to be setting widths on elements that have the flex property.. not positive though.
So your browser issues:
-IE doesn't support flex at all so you're label won't float unless you use a float.
-The reason your input/content is spilling over the container and getting cut off is not really anything to do with flex.. but the way css works.. setting an element to 100% width means setting it to the width of its parent. But by default, css doesn't count the padding/border-width as part of that width. So you end up getting 100% width plus the L/R padding and border. But, since you are only supporting modern browsers.. box-sizing:border-box; to the rescue. Google it for details, but putting it on your input element should do the trick.

overflow:hidden on body is broken in ios6

I have done some testing and from what I can see there is a bug in mobile Safari on ios6.
When adding overflow:hidden on the body tag and moving an element out of the body using transform:translateX(100%); It creates an extra scrollable space for that element.
On all desktop browsers it is "hidden".
Here is a demo: http://jsfiddle.net/mUB5d/1 . Open that in Mobile safari and you will see what is wrong.
Could anyone take a look at safari 6 on Mac OS to see if the bug is present there too?
Does anybody know of any workaround besides creating another parent around my element?
Thanks for your feedback!
Nope. Safari 6 on Mac does not present with the bug. Scrollbars are not present.
I ran it on OSX Mountain Lion (10.8.2)
To further answer your question, the reason this is happening probably has more to do with Mobile Safari's zoom rendering than an overflow hidden bug. The element is in fact being hidden off screen (notice below where I have scrolled over to the right all the way, it still doesn't show me the full 100% width element - 90% of it is in fact being hidden.
It likely has something to do with iframes, and page zoom. Still looks like a bug though.
I'm assuming you're demonstrating in JSFiddle from a real life example. If you go back to your real life example (apart from iframe territory), try adding this meta tag to the head if you don't already have it, and see it this helps:
<meta name="viewport" content="width=device-width, initial-scale=1">
This is normal behaviour on iOS (and iOS only). You can work around it by declaring overflow: hidden on both html and body element. In addition, you should set the body to position: relative.
Overflow behaviour
There are several things at play here. To understand why the fix works, we first need to have a look at how the overflow of the viewport is set.
The overflow of the viewport is determined by the overflow setting of the html element.
But as long as you leave the overflow of the html element at its default (visible), the overflow setting of the body gets applied to the viewport, too. Ie, you can set either html or body to overflow: hidden when you target the viewport. The overflow behaviour of the body element itself is unaffected - so far.
Now, if you set the overflow of the htmlelement to anything other than visible, the transfer from body to viewport does no longer happen. In your particular case, if you set both overflows to hidden, the setting of the html element gets applied to the viewport, and the body element hides its overflow as well.
That's actually the case in every reasonably modern browser out there, and not specific to iOS.
iOS quirks
Now, iOS ignores overflow: hidden on the viewport. The browser reserves the right to show the content as a whole, no matter what you declare in the CSS. This is intentional and not a bug, and continues to be the case in iOS 7 and 8. There is nothing anyone can do about it, either - it can't be turned off.
But you can work around it by making the body element itself, not the viewport, hide its overflow. To make it happen, you must first set the overflow of the html element to anything other than visible, e.g. to auto or hidden (in iOS, there is no difference between the two). That way, the body overflow setting doesn't get transferred to the viewport and actually sticks to the body element when you set it to overflow: hidden.
With that in place, most content is hidden. But there still is an exception: elements which are positioned absolutely. Their ultimate offset parent is the viewport, not the body. If they are positioned somewhere off screen, to the right or to the bottom, you can still scroll to them. To guard against that, you can simply set the body element to position: relative, which makes it the offset parent of positioned content and prevents those elements from breaking out of the body box.
Answering in code
There is one final gotcha to watch out for: the body itself must not be larger than the viewport.
So the body needs to be set to 100% of the viewport width and height. (The credit for a CSS-only way to achieve it goes to this SO answer.) Margins on the html and body elements have to be 0, and the html must not have padding or a border, either.
Finally, in order to deal with body padding, and in case you ever want to set a border on the body, make the math work with box-sizing: border-box for the body.
So here goes.
html {
overflow: hidden;
height: 100%;
margin: 0;
padding: 0;
border: none;
}
body {
overflow: hidden;
position: relative;
box-sizing: border-box;
margin: 0;
height: 100%;
}
NB You can set body padding and border as you please.
After struggling with this for a while I've found that both html and body tags need overflow hidden to actually hide the overflowing contents. On elements inside body overflow hidden works fine, so our choice is an extra css rule or a wrapper element.
for me it works
I have implemented in the left side menu
if($('.left-menu-panel').is(':visible')) {$("body").addClass('left-menu-open');$("html").css('overflow-y','hidden'); $('body').click(function() {$("body").removeClass("left-menu-open") ;$("html").css('overflow-y','visible'); });$('#off-canvas-left').click(function(event){event.stopPropagation();}); }

HTML and Body Viewport issue

I have a website at filmblurb.org.
The page-container of my site extends to the bottom of the window when you scroll out to make for a 100% CSS layout style, but for some reason even when the height is 100% for both the body and tag, those two elements go about halfway down the page and then stop when the viewport is zoomed out. When I'm profiling those elements in Google Inspect Element that is. My page-container is currently min-height: 100%, but that for some reason actually does extend to the bottom of the viewport when zoomed out.
I've also taken screenshots of what I'm seeing to give you a better idea. Here they are [link]i917.photobucket.com/albums/ad16/jtarr523/… (for the body) and
(for the HTML)...Both are not extending to the bottom.
Anybody know how to fix this?
I would appreciate it.
min-height: 100% on the html element means that that element will be at least as tall as the viewport. It does not mean that it will always extend to the bottom. If you scroll down, then you may still be able to scroll below the bottom of the <html> element.
The only way to prevent this (short of JavaScript) is to ensure that all elements on the page (that is, everything that could possibly cause a scrollbar) is kept within the html element. A simple way to force this is to put overflow: hidden on your html element:
body {
overflow: hidden;
}
If the problem is being caused by a float, then that will solve it. If the problem is caused by an absolute-positioned element or a negative bottom margin on the last element, then that will replace your problem with a more serious one: the page will be cut off at the bottom of the html element. You will then have to find the problem element some other way.
(The same applies to the body element; it will need its own overflow: hidden; to ensure that nothing can extend beyond it.)
Not sure exactly if it would work with browser zoom, but in my experience (and according to this question) you need to set the html tag height to 100% if you are setting container elements to min-height: 100%.
html { height: 100%; }
body { min-height: 100%; }
Replace body with a reference to your main container and it should still work. As far as I can tell there are no adverse reactions to setting html to 100%; it doesn't cut the page off or mess up any other styles.
Like I said, I'm not 100% sure this is related to your problem, but it's probably worth a shot.

CSS Scroll Bar Problem

I have used Accordion and Slideshow on my site.
http://www.delightbranding.com/
when you click Play. For some reason the scroll bar appears shifting the page.
Guess i am missing setting height for some div. Please help.
This one seems to be the bad apple:
<div class="control-next">
When the "Play" item is selected, this div expands below the HTML content, causing your page to grow.
Remove the height from .control-next css class
.control-next {
position:absolute;
right:0;
top:201px;
bottom:201px;
/*height:432px;*/
}
this is only happening for me in IE9 (I'd wager all versions of IE) and only when my browser window is short.
I tend to add a CSS rule to my html tag of
overflow-y: scroll;
Which places the scrollbar on the page always so that longer content doesn't make the browser behave inconsistently.
Not sure if this will help you in this case, but worth a try.

Resources