On a mobile (Safari, webviews, wherever), overflow:scroll and overflow-scrolling: touch give a pretty smooth scroll, which is cool.
But, it makes the page "bounce" (area circled below), which is not the case when you are not using it, but which makes the experience a little less "native" (and more simply, as far as I can have an opinion about it, is absolutely un-useful)
Is there a way to prevent it to happen?
There's a great blog post on this here:
http://www.kylejlarson.com/blog/2011/fixed-elements-and-scrolling-divs-in-ios-5/
Along with a demo here:
http://www.kylejlarson.com/files/iosdemo/
In summary, you can use the following on a div containing your main content:
.scrollable {
position: absolute;
top: 50px;
left: 0;
right: 0;
bottom: 0;
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
The problem I think you're describing is when you try to scroll up within a div that is already at the top - it then scrolls up the page instead of up the div and causes a bounce effect at the top of the page. I think your question is asking how to get rid of this?
In order to fix this, the author suggests that you use ScrollFix to auto increase the height of scrollable divs.
It's also worth noting that you can use the following to prevent the user from scrolling up e.g. in a navigation element:
document.addEventListener('touchmove', function(event) {
if(event.target.parentNode.className.indexOf('noBounce') != -1
|| event.target.className.indexOf('noBounce') != -1 ) {
event.preventDefault(); }
}, false);
Unfortunately there are still some issues with ScrollFix (e.g. when using form fields), but the issues list on ScrollFix is a good place to look for alternatives. Some alternative approaches are discussed in this issue.
Other alternatives, also mentioned in the blog post, are Scrollability and iScroll
I've managed to find a CSS workaround to preventing bouncing of the viewport. The key was to wrap the content in 3 divs with -webkit-touch-overflow:scroll applied to them. The final div should have a min-height of 101%. In addition, you should explicitly set fixed widths/heights on the body tag representing the size of your device. I've added a red background on the body to demonstrate that it is the content that is now bouncing and not the mobile safari viewport.
Source code below and here is a plunker (this has been tested on iOS7 GM too). http://embed.plnkr.co/NCOFoY/preview
If you intend to run this as a full-screen app on iPhone 5, modify the height to 1136px (when apple-mobile-web-app-status-bar-style is set to 'black-translucent' or 1096px when set to 'black'). 920x is the height of the viewport once the chrome of mobile safari has been taken into account).
<!doctype html>
<html>
<head>
<meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no" />
<style>
body { width: 640px; height: 920px; overflow: hidden; margin: 0; padding: 0; background: red; }
.no-bounce { width: 100%; height: 100%; overflow-y: scroll; -webkit-overflow-scrolling: touch; }
.no-bounce > div { width: 100%; height: 100%; overflow-y: scroll; -webkit-overflow-scrolling: touch; }
.no-bounce > div > div { width: 100%; min-height: 101%; font-size: 30px; }
p { display: block; height: 50px; }
</style>
</head>
<body>
<div class="no-bounce">
<div>
<div>
<h1>Some title</h1>
<p>item 1</p>
<p>item 2</p>
<p>item 3</p>
<p>item 4</p>
<p>item 5</p>
<p>item 6</p>
<p>item 7</p>
<p>item 8</p>
<p>item 9</p>
<p>item 10</p>
<p>item 11</p>
<p>item 12</p>
<p>item 13</p>
<p>item 14</p>
<p>item 15</p>
<p>item 16</p>
<p>item 17</p>
<p>item 18</p>
<p>item 19</p>
<p>item 20</p>
</div>
</div>
</div>
</body>
</html>
you could try
$('*').not('#div').bind('touchmove', false);
add this if necessary
$('#div').bind('touchmove');
note that everything is fixed except #div
This answer seems quite outdated and not adapt for nowadays single page applications. In my case I found the solution thank to this aricle
where a simple but effective solution is proposed:
html,
body {
position: fixed;
overflow: hidden;
}
This solution it's not applicable if your body is your scroll container.
body {
position: fixed;
height: 100%;
}
Related
seem to be having issues with my pure css parallax, im using the concept from this article. However this doesn't seem to be working for me at all.
Am I going about it all wrong?
You can inspect my code using a debugger here.
Edit:
Sorry I though providing the link would let you inspect the code easier rather than read and try and understand pasted code snippets.
I want to have parallax effects on sections of my website.
Here you can see my HTML, there are more parts but im currently trying to get my header working with a parallax scrolling background:
<body class="parallax">
<header class="parallax__group">
<div class="parallax__layer parallax__layer--back darken"></div>
<div class="parallax__layer parallax__layer--base flex alignvcenter">
<div id="hdr-logo">
<img src="images/logo.svg" alt="Mobile Paint Solutions" class="responsive-img">
</div>
<div id="hdr-hint">
<img src="" alt="" class="responsive-img">
</div>
<div id="hdr-nav">
<nav>
<span>Home</span>
<span>About</span>
<span>Gallery</span>
<span>Reviews</span>
<span>Pricing</span>
<span>Contact</span>
</nav>
</div>
</div>
</header>
And here are my LESS styles:
.parallax {
perspective: 1px;
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
}
.parallax__group {
position: relative;
height: 100vh;
transform-style: preserve-3d;
}
.parallax__layer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.parallax__layer--base {
transform: translateZ(0);
}
.parallax__layer--back {
transform: translateZ(-1px) scale(2);
}
.parallax__layer--deep {
transform: translateZ(-2px) scale(3);
}
However currently the background is not moving at all, can anyone explain this?
I believe the reason the effect (parallax or not) does not work is because you used <body> as the host element. Probably some of the properties it uses have no effect on <body>. I assume we're talking perspective and its vendor prefixed counterparts.
The obvious fix is to use a <div> as host, not <body>. I tried to use some styles and images from the website you linked, but it doesn't look too good. You got the idea though.
Adding
background-attachment: fixed;
to your
<div class="parallax__layer parallax__layer--back darken"></div>
or actually class named
parallax__layer--back
fixed the thing.
Edit: (http://i.imgur.com/rV1CDho.png) this works, gentleman.
UPDATE:
I rebuilt the page with all relatively-positioned elements and the thing is still stuck when I navigate via pageid. I think it's definitely a Safari-specific overlap conflict and it is super annoying. Any ideas out there?
I'm working on a microsite that uses pageid's to navigate through full-page div's, arranged vertically with the overflow hidden. It works just fine on every browser, including mobile, except desktop versions of Safari.
The div's scroll when the page is refreshed to the specific pageid, and will scroll if the text is highlighted and dragged, but if you start at page 01 and navigate to page 02 (like you're supposed to), the content will not scroll.
It seems like it might be an overflow conflict, but I tried to do this with the page div's scrolling horizontally to separate the x- and y-axis issue and I got nothing. It's acting more like there's a transparent layer in between me and the scroll...
Check out the microsite here: http://www.kevinjbeaty.com/trailtool-stackoverflow
Note that it works just fine everywhere else.
This is the basic html:
<div class = "viewbox">
<div id= "page01" class="page">
<div class="content">
**these are photos that do not scroll**
</div>
</div>
<div id= "page02" class="page">
<div class="content">
**these are photos that do not scroll**
</div>
<div class="contentscroll">
**this is text that should scroll**
</div>
<div id= "page03" class="page">
<div class="content">
**these are photos that do not scroll**
</div>
</div>
<div id= "page04" class="page">
<div class="content">
**these are photos that do not scroll**
</div>
<div class="contentscroll">
**this is text that should scroll**
</div>
</div>
and the basic css:
.viewbox {
position: relative;
height: 100%;
width: 100%;
display: block;
overflow: hidden;
background-color: black;
z-index:0;
}
.page {
position: relative;
height: 100%;
width: 100%;
display: block;
z-index:1;
overflow: scroll;
background-color: white;
z-index:10;
}
.content {
position: absolute;
padding: 2%;
background-size: contain;
background-repeat: no-repeat;
display: block;
}
.contentscroll {
position: absolute;
padding: 2%;
overflow-y: scroll;
overflow-x: hidden;
display: block;
z-index: 200;
}
Got it! Wow.
I changed the body "overflow" to "hidden" and got rid of the ".viewbox" wrapper altogether and viola! Stupid simple...
Below I have some HTML code. Everything is positioned relative apart from contentRow which is positioned absolutely. This is making the footer stick to where the browser window ends and not where the scroll bar ends.
Is there any way I can make the footer go down to the very bottom where the scroll bar ends.
<div id="s4-workspace" style="width: 1920px; height: 748px; overflow:scroll">
<div id="s4-bodyContainer" style="position:relative">
<div class="headerSection" style="position:relative">
<div class="globalHeader">
</div>
</div>
<div>
<div id="contentRow" style="position:relative">
<div class="fixedWidthMain" style="position:relative">
<div class="fixedWidthMain" style="position:absolute">
</div>
</div>
</div>
</div>
</div>
<!--PAGE FOOTER SECTION-->
<div class="pageFooterSection" style="clear: both;position:relative">
</div>
</div>
Theres a few available flavours of the solution for this but they basically go something like this.
EXAMPLE
html {
position: relative;
min-height: 100%;
}
body {
margin: 0 0 100px; /* bottom = footer height */
}
footer {
position: absolute;
left: 0;
bottom: 0;
height: 100px;
width: 100%;
}
a point to remember is that height of elements in html are always passed through the parent. so if you dont define height 100% on a parent the child won't know either. Good luck and let me know if you have any other issues :)
SOURCE
http://mystrd.at/modern-clean-css-sticky-footer/
If I'm understanding correctly, you could make s4-bodyContainer position:relative so that the contentRow is only positioned absolutely within that container. Then footer would go below the bodyContainer.
I got this CSS layout: http://www.cssdesk.com/Lgg4q
HTML
<div id="wrap">
<div class="img-wrap">
<img src="http://unikatmag.de/wp-content/uploads/2010/11/team-dummy.jpg" />
</div>
<div class="info">
<p>Lorem</p>
<p>ipsum</p>
</div>
<div class="img-wrap">
<img src="http://unikatmag.de/wp-content/uploads/2010/11/team-dummy.jpg" />
</div>
<div class="info">
<p>Lorem</p>
<p>ipsum</p>
</div>
<div class="img-wrap">
<img src="http://unikatmag.de/wp-content/uploads/2010/11/team-dummy.jpg" />
</div>
<div class="info">
<p>Lorem</p>
<p>ipsum</p>
</div>
</div>
CSS
body {
background-color: grey;
font: 18px/ Times;
color: black;
}
body, html {
height: 100%;
width: 100%;
}
p { text-align: justify; }
#wrap {
width: 80%;
margin-left: 10%;
padding-top: 2%;
position: absolute;
font-size: 14px;
background: yellow;
}
.info {
margin-right: 5%;
padding-top: 2%;
float: left;
}
.img-wrap {
position: relative;
display: inline-block;
max-width: 100%;
float: left;
margin-right: 1%;
margin-top: 1%;
}
When you resize the browser window (smaller), you can see that the behavior of the divs basically breaks the design. How to handle this problem?
My thought was to give the #wrap a height, but that won't work like it should.
Here's how I'd do it. http://jsfiddle.net/joplomacedo/TYjd5/ (I couldn't figure out how to save the changes in cssdesk so I transfered it into jsfiddle)
Basically, I added a 'wrapper', which I called block around each of the image and info blocks. I gave them a width and floated them. This way, when the browser is resized, the info and the image always go together.
Was this the behavior you were looking for. What would you want to happen on the browser resizing?
You can use min-width on #wrap and set a pixel value to prevent it from breaking.
DIV elements don't behave well when used with percentages or I can say they are not meant to be used so. You have two options in this kind of situation:
Make the design of your page in such a way that it looks like it's not responding to the browser's window resize. Take as an example this very website.
Resize your containers accordingly when the browser's window is resized. To do this you will need to use Media Css classes or maybe jQuery.
I am working on getting the layout sorted for a pretty simple gallery webapp, but when I use an HTML5 doctype declaration, the height of some of my divs (which were 100%) get shrunk right down, and I can't seem to plump them back up using CSS.
My HTML is at https://dl.dropbox.com/u/16178847/eyewitness/b/index.html and css is at https://dl.dropbox.com/u/16178847/eyewitness/b/style.css
If I remove the HTML5 doctype declaration, all is as I want it to be,
but I really want to use the proper HTML5 doctype declaration.
If I set the doctype to HTML5 and make no changes, the div with the photo and the footer divs are not visible, presumably because they are 0px high.
If I set the doctype to HTML5 and make the body { height: 100px } and .container { height: 100px } or .container { height: 100% }, it becomes visible, but what I need is it to be is full height rather than a height in pixels.
If I try to do the same as above, but with the body { height: 100% } the photo and footer divs are not visible again.
What do I need to do to get it 100% in height so that my photo and footer divs are full height?
Only if the parent element has a defined height, i..e not a value of auto. If that has 100% height, the parent's parent height must be defined, too. This could go until to the html root element.
So set the height of the html and the body element to 100%, as well as every single ancestor element of that element that you wish to have the 100% height in the first place.
See this example, to make it clearer:
html, body, .outer, .inner, .content {
height: 100%;
padding: 10px;
margin: 0;
background-color: rgba(255,0,0,.1);
box-sizing: border-box;
}
<div class="outer">
<div class="inner">
<div class="content">
Content
</div>
</div>
</div>
This wouldn't work, if I didn't give 100% height to—say html element:
body, .outer, .inner, .content {
height: 100%;
padding: 10px;
margin: 0;
background-color: rgba(255,0,0,.1);
box-sizing: border-box;
}
<div class="outer">
<div class="inner">
<div class="content">
Content
</div>
</div>
</div>
… or .inner
html, body, .outer, .content {
height: 100%;
padding: 10px;
margin: 0;
background-color: rgba(255,0,0,.1);
box-sizing: border-box;
}
<div class="outer">
<div class="inner">
<div class="content">
Content
</div>
</div>
</div>
Indeed, to make it work do as follow:
<!DOCTYPE html>
<html>
<head>
<title>Vertical Scrolling Demo</title>
<style>
html, body {
width: 100%;
height: 100%;
background: white;
margin:0;
padding:0;
}
.page {
min-height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div id="nav" class="page">
<ul>
<li>About</li>
<li>Portfolio</li>
<li>Contact</li>
</ul>
</div>
<div id="page1" class="page">
<h1><a name="about">about</a></h1>
About page content goes here.
</div>
<div id="page2" class="page">
<h1><a name="portfolio">portfolio</a></h1>
Portfolio page content goes here.
</div>
<div id="page3" class="page">
<h1><a name="contact">contact</a></h1>
Contact page content goes here.
</div>
</body>
</html>
I got stuck into a similar problema to size a canvas, so here is what i did and worked perfectly.
Besides doing the:
body{ width: 100%; height: 100%;}
Set the desired element like this:
.desired-element{ width: 100vw; height: 100vh}
In that way you are assured to have 100% of the view port in width and height.
vw stands for viewwidth
and
vh stands for viewheight
I hope this helps someone