Position: fixed disappearing in Safari/IOS. - html

Running into an odd issue in Safari/iOS. I have the following code.
HTML:
<div class="content">
<p>Hello World</p>
<div class="footer">
<p>This is the footer</p>
</div>
</div>
CSS:
.content {
border: 1px solid orange;
overflow-x: hidden;
position: relative;
z-index: 0;
}
.footer {
background: pink;
width: 100%;
position: fixed;
bottom: 0;
}
Working example:
http://run.plnkr.co/ZgGFJgMf0atvbiyC/
The scenario:
I have a footer div positioned to the bottom of the viewport with position: fixed. This is child element of a wrapper div for the entire page content.
The problem:
The above works just fine in Chrome. In Safari (and iOS), however, notice that the footer can't be seen. It's there...but the parent div isn't as tall as the viewport, so the footer can't be seen.
Removing any one of the following from the .content div fixes things: overflow-x, position, z-index.
Why?
For this example, the easy fix, of course, is to simply remove of of those attributes, but the issue is that I'm debugging an existing site with about a 1000 lines of HTML and 30k+ lines of CSS. Yes, a bit of a mess. But it's what I have. I'm a bit hesitant to just remove one of those styles without first understanding the issue fully.

Related

Overflow hidden issue with double scrolling on iOS

The problem is that I have a body (which it can't be positioned fixed because it causing bugs to the current project) with a lot of content and a modal with scrollable content inside, the problem is that on iOS if I turn the overflow to hidden nothing happens.
In my case, setting height: 100vh and overflow: hidden to class="parent" is not working.
I tried different things and tried different hacks to solve this issue but nothing fixed yet I saw here also different methods but for different situations.
I looked also for overflow hidden alternatives but nothing found yet...
If you guys have some ideas/refs/a way to solve it post it here I appreciate, thank you.
Here is the snippet https://codepen.io/anon/pen/zJQoJR
<body class="modal-open">
<div class="parent">
<p>Body scrollable content</p>
<div class="container-child">
<div class="child">
<p>Modal scrollable content</p>
</div>
</div>
</div>
</body>
Putting the overflow hidden on your html tag might help:
html, body {
height: 100%;
width: 100%;
overflow: hidden;
}
I got pretty good results by adding this to your css:
body.modal-open > .parent {
position: fixed;
overflow: hidden;
height: 100%;
}
And to make the modal 'bouncy' on your iOS device, change your .container-child css to:
.container-child {
position: fixed;
background-color: rgba(0,0,0,0.4);
top: 0;
left: 0;
width: 100%;
height: 100%;
-webkit-overflow-scrolling: touch; /* <-- added */
}
Here's a demo on codepen: https://codepen.io/anon/pen/mzJXPJ

Margin-top for absolute positioned div with bottom property

I'm creating a div as a footer as such:
<div class="content">blah blah blah</div>
<div class="content">more content</div>
<div class="content">even more content</div>
<div id="footer">blah blah blah</div>
The CSS for the footer is as follows:
#footer{
height: 50px;
display: block;
position: absolute;
right: 0;
left: 0;
bottom: 0;
}
So how do I leave a 50px space between content and footer? I've tried adding a spacer div between the two but yielded no success. The spacer div needs to be more than the height of content for it to have any effect. I've tried margin-top to #footer, which didn't work, but I do not want a margin-bottom for content because the content containers are multiple. Setting a bottom margin for the content would ruin how they render. Thanks for any help.
P.S. this is not a duplicate to Set position absolute and margin.
Okay, let give this a spin.
Maybe this helps you a bit on your way:
http://codepen.io/bbredewold/pen/avgZmj
It would help if you describe the behaviour you want to achieve, including how the page should respond at different sizes. Maybe you can fork (copy) the pen, and make some additions to help us understand your problem.
Good luck!
.outside {
position: absolute;
overflow: scroll;
background: #ccc;
bottom: 100px;
left: 0;
right: 0;
top: 0;
}
.content {
outline: 1px solid blue;
}
#footer {
outline: 1px solid red;
background: #ccc;
height: 50px;
display: block;
position: absolute;
right: 0;
left: 0;
bottom: 0;
}
<div class="outside">
<div class="content">blah blah blah</div>
<div class="content">more content</div>
<div class="content">even more content</div>
</div>
<div id="footer">blah blah blah</div>
Ya, it won't work like that. Because you've given #footer an absolute position, its position bears no relation to the position of the other elements in the document.
No amount of margin or padding will show between 2 things that aren't in relation to each other.
EDIT: From your comments below, what you are looking for is a static footer
#footer{
height: 50px;
display: block;
margin-top: 50px;
}
I'm such a SO noob I can't comment for more info :| . I assume you may be trying to achieve a fixed / sticky footer where the footer always appears at the bottom of the page? If you could provide an example of the effect you are trying to achieve I would be happy to edit my answer with more specific information.
Anyway because you are using absolute positioning the element is taken out of the document flow and it wont affect any other elements on the page. This means margins wont work. The same is true for fixed positioning, which is what you actually want if you are making a basic sticky footer.
If you want margin to have any effect on an element you need to set the elements display property to be a block level element (block, table, inline-block etc etc) and its positioning to either static (default) or relative.
The cleanest method for robust sticky footers is using flex box. Note the use of semantic html tags and classes instead of id's
<style>
/**
* 1. Avoid the IE 10-11 `min-height` bug.
* 2. Set `flex-shrink` to `0` to prevent Chrome, Opera, and Safari from
* letting these items shrink to smaller than their content's default
* minimum size.
*/
.site {
display: flex;
flex-direction: column;
height: 100vh; /* 1 */
}
.header,
.footer {
margin-top: 50px;
flex-shrink: 0; /* 2 */
}
.content {
flex: 1 0 auto; /* 2 */
}
</style>
<body class="site">
<header class="header">…</header>
<main class="content">…</main>
<footer class="footer">…</footer>
</body>
Courtesy of Phillip Walton http://philipwalton.com/articles/normalizing-cross-browser-flexbox-bugs/
Note that this only works for newer browsers so if you are supporting old versions of IE you will need to use a fixed positioning based sticky footer, or forget sticky footers all together.

How do I lock a sidebar to the height of a window even when a user scrolls?

I'm running into a minor issue with one of the elements on my page. I have a sidebar which I am attempting to have span the height of the page by using the following CSS:
#sidebar {
width: 180px;
padding: 10px;
position: absolute;
top: 50px;
bottom: 0;
float: left;
background: #eee;
color: #666;
}
The corresponding CSS is pretty much what you'd expect:
<div id="header">
The header which takes up 50px in height
</div>
<div id="main-container">
<div id="sidebar">
The sidebar in question
</div>
<div id="main-content">
The rest of my page
</div>
</div>
The code works as expected for the most part. When the page renders it spans 100% of the height (minus the 50px from the top). The problem is that it essentially assigns the box to the exact height of the window so as I scroll down the box scrolls away instead of staying locked to the bottom of the window. Any ideas how to resolve this?
You have to use position:fixed if you want for the sidebar to be fixed on some position:
#sidebar {
width: 180px;
padding: 10px;
position: fixed;
top: 50px;
bottom: 0;
background: #eee;
color: #666;
}
JSFiddle
Another way would be to give to the parent container position:relative, and on his child position:absolute - but then the parent must have some height so the child element takes its height.
html,body{
position:relative;
height:100%; /* some height */
}
#sidebar{
width: 180px;
padding: 10px;
position: absolute;
top: 50px;
bottom: 0;
background: #eee;
color: #666;
}
JSFiddle
Check learnlayout to read more about positioning.
use css position:fixed to make the sidebar fixed.
in order to lock the height according to screen height i would use javascript/jquery:
$(function(){
// assign to resize
$(window).resize(set_height);
});
function set_height() {
$('#sidebar_id').height($(window).height());
}
hope that helps
First of all, I don't understand how it's spanning 100% of the height when no height has been defined.
Secondly use position: fixed instead of absolute.
On a second note, I'd like to recommend what seems a more proper way of going about positioning this. At the end of the main-container div, before it's closing tag, put this
<div style="clear: both;"></div>
and make the main container also float left, or float right if that doesnt give you what you want. It's suprising how such a common layout can feel tricky to do properly. (at least for newbies like us). I might be wrong, this might not be a better way, but it's the way I'd do it. The extra div you add is so that floated divs take up space, apart from that if it doesn't work, give the sidebar a height of 100%, or if you think it will overflow, tell me I'll add to my answer.

Fill remaining height in fixed-height css table

I've trying to get a layout where a a fixed-height table with two rows, the first scaling to the its content, and the second being the remaining height, and keeping its contents inside it. The height of the bottom part needs to be 'real' (not clipped by a parent or anything), such that it could have overflow: scroll, or children of height: 100%, etc.
This is what it should look like:
I got it working in Chrome, using an absolutely positioned div inside a relative table-cell:
http://jsfiddle.net/9FPqx/
The core of it:
html:
<div class="row">
<div class="cell">
<div class="absolute-fill">
Stuff
</div>
</div>
</div>
css:
.row
{
display: table-row;
}
.cell
{
display: table-cell;
position: relative;
}
.absolute-fill
{
position: absolute
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
overflow: hidden;
}
With another intermediary relative div between the table-cell and the content (rather than setting relative on the table-cell itself), it works in Firefox:
http://jsfiddle.net/sXHry/
It does not work in IE. I need IE >= 9.
It seems like IE thinks the relative element with absolute child has no content height, and so gives it 0 height.
I feel like I'm so close but so far. Is there a way of solving this with just html and css? Am I on the wrong track using display: table? Or should I give up and just throw some javascript at it?
Why does it need to be a table? Can't you just let the container hide the overflow?
html
<div class="container">
<div class="top">
Top, green area
</div>
<div class="bottom">
Bottom, blue area
</div>
</div>
css
.container {
width: 250px;
height: 162px;
overflow: hidden;
background: lightblue;
}
.top {
background: lightgreen;
}
http://jsfiddle.net/sXHry/1/ and http://jsfiddle.net/sXHry/2/ (less content)
I suspect i might be missing something, looking forward to being enlightened ;)

Unspecified content height with Automatic Overflow and header/footer always in view and no scroll wheel on the page

Okay, so I'm having rather annoying problems with what should be simple code, I've searched for duplicates but it appears to be different in a slight way. Here's my basic layout:
html:
<div id="wrapper">
<div id="header"></div>
<div id="content"></div>
<div id="footer"></div>
</div>
css:
html,body,#wrapper {
height: 100%;
margin: 0;
padding: 0;
}
#wrapper {
position: relative;
}
#header {
position: fixed;
top: 0px;
height: 40px;
width: 100%;
color: white;
background-color: #000000;
}
#content {
position: fixed;
padding-bottom: 50px; /* to match the footer height*/
top: 40px;
bottom: 50px;
height: 100%;
width: 100%;
overflow: auto;
}
#footer {
position: fixed;
bottom: 0px;
height: 49px;
width: 100%;
border-top: 1px solid #000000;
background-color: skyblue;
font-weight: bold;
}
The idea is that the 3 divs inside the wrapper take up 100% of the page - in other words: all them are always in view. Header up top, footer on the bottom and content in the middle respectively.
The footer and header can be fixed size (be it pixels or % of page height), the content I want to automatically take up the rest of the page.
The problem is that the page can be of many different resolutions(so content can't be of fixed height, unless I use javasript). Another thing is that the content div can have variable amount of elements, meaning it has to allow the scrolling of the content while keeping both header and footer in view. The main part is: the scroll-wheel must be inside the content div, not page-wide.
I almost have what I want with this css, but some of the content can't be scrolled to when they overflows content div (I'm talking vertical overflows - there will be no horizontal ones). I would really appreciate some help, but this is not as easy/simple as it seems, if possible at all as I think you need a fixed height for overflow: auto.
I want a pure css solution, if possible, so don't mention JqueryMobile to me (or ever).
Here's how it looks right now, notice the scroll-wheel problem on the content div:
I hate when this happens...I found the solution just after I posted, decided to try one more thing: I've set the #content height to 'auto' and that did it (since once I drew my own attention to the scroll-wheel, it became apparent the problem is with the div height)! Just need to test and make sure that's the case with all/most browsers!
Maybe it will be helpful to someone else though!