Scrolling DIV between fixed header/footer - html

i would like to use a website with fixed header/footer and a scrollable div in between.
Only the div in the middle should scroll, no scrollbar for the whole site (that's why body overflow is hidden).
My attempt so far:
#container1 {display:block;padding-top:60px;overflow-y:scroll}
#container2 {display:none;padding-top:60px;overflow-y:scroll}
body{overflow:hidden}
The scrollbars are shown but too much on the right, also they are not scrollable?
PS: Unfortunately the switching between the DIVs don't work at JSFiddle, don't know why...

If the header and footer have explicit heights, it could be achieved simply by positioning the middle DIV absolutely and using top/bottom offsets with the respect to the height of the header/footer.
Then we can add overflow-y: auto to the middle DIV — Example:
#divLinks {
overflow-y: auto;
position: fixed;
top: 25px;
bottom: 40px;
width: 460px;
}
html, body {
height: 100%;
width: 100%;
margin: 0;
}
#divLinks {
overflow-y: auto;
position: absolute;
top: 25px;
bottom: 40px;
left: 0; right: 0;
}
#page{height: 100%;width:480px;margin: 0 auto; position: relative;}
#header{position:absolute;top:0;left: 0;right: 0;z-index:998;height:25px;background:#5f5f5f}
#bottom{position:absolute;bottom:0;left: 0;right: 0;z-index:999;height:40px;background:#5f5f5f}
<div id="page">
<div id="header">Header</div>
<div id="divLinks">
<div id="container1">First<br><br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br></div>
<div id="container2"> second<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1</div>
</div>
<div id="bottom">First Page - Second Page</div>
</div>

The easiest way, in my opinion, is to use fixed elements, like this:
<header>Header</header>
<main>Content</main>
<footer>Footer</footer>
and
body {
margin: 0;
overflow: hidden;
}
header {
position: fixed;
top: 0;
left: 0;
background-color: red;
width: 100vw;
height: 2em;
}
main {
position: fixed;
top: 2em;
left: 0;
width: 100vw;
height: calc(100vh - 4em);
background-color: green;
y-overflow: auto;
}
footer {
position: fixed;
bottom: 0;
left: 0;
background-color: blue;
width: 100vw;
height: 2em;
}

Related

Center fixed div over content area

I have a page with a collapsable sidebar (black area). On the right we have the content area. In my example I have a grey square which represents a table. Now I have a div to float on top of this table (red on the picture) and make it fixed to the screen. So it scrolls with the page, but is centered to the content area. See example 1.
Right now it is centered to the viewport, meaning that the sidebar is also taken in account. Which makes the red square look like example 2.
Example 1:
Example 2: (current state)
Does anyone know any CSS tricks to center the fixed div to the content area, and not to the viewport. Maybe using calc or more margin on the left?
Code Pen
Here the code pen which demonstrates example 2
<div class="sidebar"></div>
<div class="content">
<div class="content-body">
<p>Content in here</p>
</div>
</div>
<div class="popup">
<p>This should be centered on content instead of the viewport</p>
</div>
.sidebar {
position: fixed;
left: 0;
top: 0;
bottom: 0;
width: 250px;
background-color: #000;
}
.content {
width: calc(100% - 250px);
position: absolute;
top: 0;
right: 0;
background-color: #efefef;
}
.content-body {
width: 100%;
height: 2000px; /* to create some scrollable page*/
max-width: 1200px;
margin: 1em auto;
background-color: #afafaf;
}
.popup {
position: fixed;
width: 100%;
max-width: 1200px;
top: auto;
bottom: 0;
left: 0;
right: 0;
background-color: red;
margin: 1em auto;
}
https://codepen.io/finiox/pen/mdmJVwK
If I understood your question correctly, you can just change left: 0 to left: 250px for .popup
If the sidebar has a static width. Which is has in this case. You need to use the transform property and transform it to half the width of the sidebar.
transform: translate(125px, 0);
Optionally you can store the sidebar width in a root variable and use calc to get half the width.
:root {
--sidebar-width: 250px;
}
.popup {
transform: translate(calc(var(--sidebar-width)/2), 0);
}
if the sidebar is not always visible, then add a class (ex: is-sidebar-active) then you can select popup using something like .is-sidebar-active + nextSibling + nextSibling. Then just add left: SIDEBAR_WIDTH into popup.
Example:
:root {
--sidebarWidth: 250px;
}
.sidebar {
position: fixed;
left: 0;
top: 0;
bottom: 0;
width: var(--sidebarWidth);
background-color: #000;
}
.content {
width: calc(100% - 250px);
position: absolute;
top: 0;
right: 0;
background-color: #efefef;
}
.content-body {
width: 100%;
height: 2000px; /* to create some scrollable page*/
max-width: 1200px;
margin: 1em auto;
background-color: #afafaf;
}
.popup {
position: fixed;
width: 100%;
max-width: 1200px;
top: auto;
bottom: 0;
left: 0;
right: 0;
background-color: red;
margin: 1em auto;
z-index: 9;
}
.is-sidebar-active + .popup {
width: calc(100% - var(--sidebarWidth));
left: var(--sidebarWidth);
}
<div class="sidebar is-sidebar-active"></div>
<div class="popup">
<p>This should be centered on content instead of the viewport</p>
</div>
<div class="content">
<div class="content-body">
<p>Content in here</p>
</div>
</div>

Forcing footer to be at bottom and Safari height inheritance

In order to force an element to the bottom of its container I need css and html like
#container {
position: relative;
width: 100%;
min-height: 100%;
}
#content {
width: 800px;
min-height: 100%;
margin: 0 auto;
padding-bottom: 100px;
}
#footer {
position: absolute;
width: 100%;
height: 100px;
bottom: 0;
}
<div id="container">
<div id="content"></div>
<div id="footer"></div>
</div>
But in order to fix the height of the content div to a minimum of 100% in Safari I need to have css like this
#content {
position: absolute;
left: 0;
right: 0;
width: 700px;
min-height: 100%;
margin: 0 auto;
padding-bottom: 100px;
}
This causes the footer to not stick to the bottom of the container when the content div's height expands beyond 100%.
Is there a way to have these two affects take place simultaneously?

Why height 100% doesn't work for the content?

In this code I have a sticky footer and a content section above, but why height:100% doesn't work for content section?
html {
position: relative;
min-height: 100%;
}
body {
margin-bottom: 60px;
height: 100%;
}
.content {
background-color: #116655;
height: 100%;
}
.footer {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 60px;
background-color: #ffcc44;
}
<div class="content">
<div>content</div>
</div>
<footer class="footer">
My footer
</footer>
You need to set an actual height on the html
html {
position: relative;
height: 100%; /* not min-height */
}
JsFiddle Demo
Use position: absolute on the content as well, then use top: 0 and bottom: 60px this will make the content take up the remaining space. then use overflow: auto; to allow scrolling the content;
(Demo)
.content {
position: absolute;
top: 0;
bottom: 60px;
background-color: red;
overflow: auto;
}

Scrollable container beneath variable height

I'm trying to lay out some CSS to build a site to look like a fairly typical desktop app type layout:
I've almost got it all working, however I'm having problems getting the scrollable panel to stick to the bottom of the viewport and display with a scrollbar instead of overflowing off the page.
The HTML and CSS I have so far is:
HTML
<nav></nav> <!-- Fixed height header -->
<aside></aside> <!-- Fixed height/width sidebar -->
<main><!-- Right content area container -->
<div class="top"></div> <!-- Right side top adjustable height panel -->
<div class="toolbar"></div> <!-- Fixed height toolbar -->
<div class="content"></div> <!-- Scrollable panel -->
</main>
CSS
nav {
width 100%;
height: 40px;
}
aside {
width: 260px;
position: absolute;
top: 40px;
bottom: 0;
}
main {
position: absolute;
left: 260px;
top: 40px;
bottom: 0;
right: 0;
}
.top {
position: relative;
right: 0;
left: 0;
min-height: 200px;
}
.toolbar {
height: 30px;
position: relative;
right: 0;
left: 0;
}
.content {
position: relative;
top: 0;
bottom: 0;
overflow: auto;
right: 0;
}
With the CSS above, the scrollable panel will not stay within the confines of the viewport and display a scrollbar. I'm hoping to find a javascript-less solution (it's all living in an angular app so I'd like to avoid relying on javascript for positioning if I can avoid it)
You can create this layout easily using calc.
http://jsfiddle.net/q18k57zr/
* {
box-sizing: border-box;
}
html,
body {
height: 100%;
margin: 0;
}
header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 40px;
background: #333;
}
aside {
position: fixed;
top: 40px;
left: 0;
width: 200px;
height: 100%;
background: #666;
}
main {
position: relative;
top: 40px;
width: calc(100% - 200px);
height: calc(100% - 40px);
margin: 0 0 0 200px;
background: #999;
}
.section-top {
height: 100px;
}
.section-toolbar {
height: 40px;
background: #fff;
}
.section-scrollable {
height: calc(100% - 140px);
overflow-y: scroll;
background: #ccc;
padding: 20px;
}
This is clearly just some demo code. Not intended to be used, but you'll get the idea. There are a bit of magic numbers in there, but this can easily be set up as variables with Sass/LESS and just do a bit of math.

How to create a fixed header and footer with dynamic content?

I have to make a layout with a .header and .content like with fixed height (for example 100px) and 100% width.
Then, I have to put a content with dynamical height that cover the void space.
<!-- [...] -->
<style type="text/css">
body {
margin: 0;
padding: 0;
}
.wrapper {
height: 100%;
width: 100%;
position: absolute;
}
.header {
position: absolute;
top: 0;
height: 100px;
width: 100%;
background: #0F0;
}
.footer {
position: absolute;
bottom: 0;
height: 100px;
width: 100%;
background: #0F0;
}
.content {
position: absolute;
height: 100%;
width: 100%;
background: #F00;
padding: 100px 0;
margin: -100px 0;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="header">
</div>
<div class="content">
</div>
<div class="footer">
</div>
</div>
</body>
</html>
This layout HAD to permit me to put a header and footer with fixed height, and a content with images that scale dimensions (inside a div.content).
First of all: If you have a unique element, like a page header/footer, please use an id and not a class. A class is used for elements that appear frequently or have something in common that makes it semantically correct to group them, like description texts.
Now your problem. We have to give the html and body a total height of 100% so they won't resize and we can be sure that we will use the whole page.
html, body {
height: 100%;
margin: 0;
padding: 0;
}
You then used a wrapper, but we can omit that. <body> is already a wrapper. The header and footer explain their self.
#header {
height: 100px;
position: absolute;
top: 0;
left: 0;
right: 0;
background: #0F0;
}
#footer {
height: 100px;
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: #0F0;
}
The content is a bit tricky. It needs to be expanded to 100% - 100px at the top - 100px at the bottom. Impossible? No.
#content {
position: absolute;
top: 100px;
bottom: 100px;
left: 0;
right: 0;
overflow: hidden; /* No scrollbars | Make this 'auto' if you want them */
background: #F00;
}
Finished. You can have a look at it on jsFiddle.