I'm creating a site where the basic design consists of a few blocks on top of each other, something like this:
The first three divs are of set height and width, and the main area is also of a fixed width, with the whole thing centered horizontally on the screen. I want the main area to extend to the bottom of the screen, whatever the screen size and proportions, and to use a scroll bar within it if the contents extends beyond the bottom of the screen.
The problem I have found is that to use a scroll bar it seems you need an absolute height, so I haven't been able to find any method for fitting it and being able to scroll through the contents at the same time.
Any ideas?
Here's one way of doing this. I know there might be too many divs that are just for the look of the page, making it not 100% semantic. Anyway, here you go:
http://jsfiddle.net/vSt3Z/
<div class="one">One</div>
<div class="two">Two</div>
<div class="three">Three</div>
<div class="content">
<div class="inner">
<div class="scroller">
Content
</div>
</div>
</div>
And the CSS:
.one, .two, .three {
height: 40px;
margin: 0;
padding: 0;
}
.content {
background: yellowgreen;
position: absolute;
top: 0;
left: 0;
z-index: -1;
padding-top: 120px;
width: 100%;
height: 100%;
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-o-box-sizing: border-box;
}
.content .inner {
height: 100%;
overflow-y: scroll;
}
.content .inner .scroller {
height: 1200px;
}
Please ignore this:
* {
margin: 0;
padding: 0;
}
it's there just to remove an annoying default padding from jsfiddle
Use calc with min-height:
HTML:
<div class="first block"></div>
<div class="second block"></div>
<div class="third block"></div>
<div class="main"></div>
CSS:
html,body{
height:100%;
width:100%;
padding:0;
margin:0;
}
.block{
width:100%;
height:100px;
}
.first{
background:red;
}
.second{
background:blue;
}
.third{
background:yellow;
}
.main{
min-height: calc(100% - 300px);
width:100%;
background:green;
}
JSFiddle
caniuse calc
In my opinion this is the simplest method:
DEMO: http://jsfiddle.net/ZPU5Z/
This does not put a scroll bar on the main #content section only but on the whole document. Unless you have a really compelling reason to do otherwise I suggest keeping things simple (and therefore highly compatible too!).
HTML
<div id="fixed-header">
<div id="header">Header</div>
<div id="bar1">Bar 1</div>
<div id="bar2">Bar 2</div>
</div>
<div id="content">
Main area
</div>
CSS
* {
margin: 0;
padding: 0;
border: 0;
color: white;
}
body {
background-color: blue;
}
#fixed-header {
position: fixed;
top: 0;
width: 100%;
}
#header {
background-color: black;
text-transform: uppercase;
height: 50px;
}
#bar1 {
height: 25px;
background-color: red;
}
#bar2 {
height: 25px;
background-color: green;
}
#content {
padding-top: 100px; /* header + bar1 + bar2 */
}
Related
I have the following layout for my onepage site, I've never made one before so it is very much a learning curve.
The only issue I can currently see with this is when I shrink the height of the page, the div size also shrinks, even when I add min-height: 800px;. What can I do to get around this issue? (If I didn't explain this properly, use my code and shrink the height of your page so you can only just see the background-colors, then scroll, you will notice that in fact, the height is not 800px),
div.top,
div.mid,
div.bottom {
height: 100vh;
min-height: 800px;
width: 100%;
position: absolute;
left: 0;
right: 0;
}
div.top {
background-color: red;
top: 0;
}
div.mid {
background-color: blue;
top: 100vh;
}
div.bottom {
background-color: yellow;
top: 200vh;
}
<div class="top">
<h1>Top</h1>
</div>
<div class="mid">
<h1>Mid</h1>
</div>
<div class="bottom">
<h1>Bottom</h1>
</div>
EDIT: To explain why I am using position: absolute
I use position: absolute so that I am able to use top left and right so that I don't have the margin around each div.
Without absolute
With absolute
body {
margin: 0;
}
.top, .mid, .bot {
height: 100vh;
min-height: 800px;
width: 100%;
}
.top {
background: red;
}
.mid {
background: blue;
}
.bot {
background: green;
}
<div class="top">
<span>top</span>
</div>
<div class="mid">
<span>mid</span>
</div>
<div class="bot">
<span>bot</span>
</div>
Your 'margin' is coming from the H1 tag, removed that and the gap disappears from between the divs. I've removed the absolute positioning and left / right / top values because they are redundant with the removal of the margin:
div.top,
div.mid,
div.bottom {
height: 100vh;
min-height: 800px;
width: 100%;
}
h1 {
margin-top: 0;
}
div.top {
background-color: red;
}
div.mid {
background-color: blue;
}
div.bottom {
background-color: yellow;
}
<div class="top">
<h1>Top</h1>
</div>
<div class="mid">
<h1>Mid</h1>
</div>
<div class="bottom">
<h1>Bottom</h1>
</div>
Here's a simplified version of my homepage:
<div class="main">
<div class="content"> all the content of my website </div>
<div class="nav"> fixed on the screen and always visible </div>
</div>
And here's the corresponding css:
.mainĀ {
max-width: 500px;
height: 2000px;
margin: auto;
background-color: grey;
}
.nav {
width: 100px;
height: 100px;
background-color: blue;
position:fixed;
right: 0; /* that's the issue */
}
I'd like the fixed element to stay within it's parent (touching the right edge of its parent). But right now it's touching the right border of the screen.
Any idea how to fix this? Thanks!
You can add an extra item to simulate the properties of the main container, try this:
.main {
max-width: 500px;
height: 2000px;
margin: auto;
background-color: grey;
}
.nav {
position:fixed;
max-width:500px;
width:100%;
}
.nav > div{
width: 100px;
height: 100px;
background-color: blue;
float:right;
}
<div class="main">
<div class="content">all the content of my website</div>
<div class="nav"><div>fixed on the screen and always visible</div></div>
</div>
position: fixed is described as, "The element is positioned relative to the browser window". You can use Javascript to accomplish this effect, here is how you do it with jQuery, for example:
$(window).scroll(function() {
var y = $(window).scrollTop();
$(".nav").css('top', y);
});
.main {
max-width: 500px;
height: 4000px;
margin: auto;
background-color: grey;
position: relative;
}
.nav {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
right: 0; /* that's the issue */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
<div class="content"> parent </div>
<div class="nav"> fixed to parent width </div>
</div>
Trying to maintain an space between them, I'd like to position some divs in a specific form for my website, and then add content to them. I have been styling the pages responsively, so I would like to know if position those divs this way with responsiveness is posible. The result I guess it could be something like this:
Being X and Y the two div's I've already created (for the header and the menu) and Z the footer. The div's I'd like to put in those positions are those DIV 1, DIV 2 and DIV 3.
For the moment the two main parts above (header and menu) are styled like this:
* {
margin:0;
padding:0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
header {
width:90%;
height:30%;
margin: 0 auto;
background-color:darkblue;
color:white;
z-index: 105;
position:relative;
}
nav {
width:90%;
height:22%;
margin: 0 auto;
background-color:skyblue;
}
And the HTML I have for the moment for those DIV 1, DIV 2 and DIV 3 is this:
<div id="content">
<div id="leftinfo">
<ul>
<li>INFO</li>
<li>ABOUT</li>
</ul>
</div>
<div id="hcontent">
<div class="tophcontent">
</div>
</div>
<div id="hcontent2">
<p></p>
</div>
</div>
I've been struggling on how to position it like this, maintaining the web flow with the other divs. Any help or tips about it would be very appreciated.
I guess that you want something like
https://jsfiddle.net/2dxzr1mv/3/
*{
box-sizing:border-box;
white-space: nowrap;
}
div{
padding:0;
margin:0;
}
.div1{
width:20%;
height:100%;
background-color:red;
min-height:100vh;
display:inline-block;
}
.wrapper{
width:80%;
min-height:100vh;
display:inline-block;
}
.div2,.div3{
width:100%;
min-height:50vh;
background-color:yellow;
word-wrap: break-word;
overflow:hidden;
white-space: normal;
}
.div3{
background-color:blue;
}
I have tried something like your picture.
CSS
* {
margin:0;
padding:0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
#content {
table-layout: fixed;
display: table;
width: 100%;
height: 100%;
}
#content > div {
display: table-cell;
}
.tophcontent {
height: 40px;
margin: 0 10px;
border: 2px solid orange;
}
.midhcontent {
margin: 10px;
margin-bottom: 0;
height: calc(100% - 46px);
border: 2px solid green;
}
#leftinfo {
border: 3px solid gray;
width:120px;
}
HTML
<div id="content">
<div id="leftinfo">
<ul>
<li>INFO</li>
<li>ABOUT</li>
</ul>
</div>
<div id="header">
<div class="tophcontent">
</div>
<div class="midhcontent">
</div>
</div>
</div>
Here is my JSfiddle
Here is a sample using display: flex. It has today about 94% browser support, which I think one can consider very good.
A great benefit with this, it is fully dynamic regarding the content in each of the elements compared to float and inline-block versions.
html, body {
margin: 0;
height: 100%;
min-height: 100%;
}
* {
box-sizing: border-box;
}
.container {
min-height: 100%;
display: flex;
flex-direction: column;
}
.info, .about, .content-left, .content-right-top,
.content-right-bottom, .footer {
border: 1px solid;
}
.wrapper {
flex: 1;
display: flex;
min-height: 100%;
}
.content-left, .wrapper-inner {
flex: 1;
}
.wrapper-inner {
display: flex;
flex-direction: column;
min-height: 100%;
}
.content-right-top, .content-right-bottom {
flex: 1;
}
<div class="container">
<div class="info">
Info<br>
2 lines
</div>
<div class="about">
About<br>
in<br>
3 lines
</div>
<div class="wrapper">
<div class="content-left">
Left take all the rest of the space
Left take all the rest of the space
Left take all the rest of the space
Left take all the rest of the space
Left take all the rest of the space
Left take all the rest of the space
Left take all the rest of the space
Left take all the rest of the space
Left take all the rest of the space
</div>
<div class="wrapper-inner">
<div class="content-right-top">
Right - Top
Right - Top
Right - Top
Right - Top
Right - Top
Right - Top
Right - Top
Right - Top
</div>
<div class="content-right-bottom">
Right - Bottom
Right - Bottom
Right - Bottom
Right - Bottom
Right - Bottom
Right - Bottom
Right - Bottom
</div>
</div>
</div>
<div class="footer">
Footer<br>
has 2 lines
</div>
</div>
Is it something like this you mean ?
Codepen example
body, html{
height:100%;
}
#wrapper{
position:relative;
width: 90%;
height:100%;
margin:0 auto;
}
.left{
float:left;
width:30%;
height:100%;
background:green;
}
.top-right{
position:absolute;
right:0;
left:31%;
height:30%;
float:left;
background:blue;
}
.bottom-right{
position:absolute;
right:0;
left:31%;
bottom:0;
top:32%;
float:left;
background:red;
}
I'm trying to go with the css-only approach to this issue and not to use margin-left to move the <div class="fd"></div> from <div class="sb"></div>
I've ran out of the idea-fuel what to try. I've nested some wrappers and used different kinds of positionings (this is not a typo nor French, spell-checker excuse me) but nothing has worked out so far.
Issue: Making a fixed div as solid element, to accept the .fd element on it's right side.
.fd holds content which is going to exceed the height of the page.
.sb holds side-content which is going to remain as 100% in height.
See snippet for a clear example what I've been struggling with.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.sb {
height: 100%;
width: 300px;
background: blue;
position: fixed;
opacity: 0.5;
}
.fd {
min-height: 100%;
background-color: red;
display: inline; /* Won't apply to fixed? block will overlap everything */
}
<div class="sb"></div>
<div class="fd">
<p>Am I out in the open?</p>
</div>
Added an extra .wrap.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wrap{
padding-left: 300px;
}
.sb {
height: 100%;
width: 300px;
background: blue;
margin-left: -300px;
position: fixed;
opacity: 0.5;
}
.fd {
min-height: 100%;
background-color: red;
display: inline; /* Won't apply to fixed? block will overlap everything */
}
<div class="wrap" id="wrap">
<div class="sb"></div>
<div class="fd">
<p>Am I out in the open?</p>
</div>
</div>
https://jsfiddle.net/afelixj/tb3pbam9/
First off, similar but never answered questions:
vertically-scrolling-percentage-based-heights-vertical-margins-codepen-exampl
scroll-bar-on-div-with-overflowauto-and-percentage-height
I have an issue with scrolling a center part of the web page while its height needs to be auto.
Here is a fiddle
The header needs to be on top at all times, meaning I don't want the body to become larger than 100%.
However the div #messages can become larger, and that div needs to scroll on its own.
The #messages has a margin-bottom to leave room for the fixed bottom div.
I tried making the div #messages with box-sizing: border-box; and making it height:100% and padding to keep it in place but this was a really nasty looking solution and the scroll bar was the full page height instead of only the inner part.
Any help would be greatly appreciated.
You want something like This
Or maybe - his big brother..
Pure CSS solution, without fixing any height.
HTML:
<div class="Container">
<div class="First">
</div>
<div class="Second">
<div class="Content">
</div>
</div>
</div>
CSS:
*
{
margin: 0;
padding: 0;
}
html, body, .Container
{
height: 100%;
}
.Container:before
{
content: '';
height: 100%;
float: left;
}
.First
{
/*for demonstration only*/
background-color: #bf5b5b;
}
.Second
{
position: relative;
z-index: 1;
/*for demonstration only*/
background-color: #6ea364;
}
.Second:after
{
content: '';
clear: both;
display: block;
}
.Content
{
position: absolute;
width: 100%;
height: 100%;
overflow: auto;
}
You could try the following.
You HTML is:
<div id="container">
<div id="header">The header...</div>
<div id="content">
<div id="messages">
<div class="message">example</div>
...
<div class="message">example</div>
</div>
<div id="input">
<div class="spacer">
<input type="text" />
</div>
</div>
</div>
</div>
Apply the following CSS:
html, body {
height: 100%;
}
body {
margin:0;
}
#header {
background:#333;
height: 50px;
position: fixed;
top: 0;
width: 100%;
}
#content {
position: absolute;
top: 50px;
left: 0;
right: 0;
bottom: 45px;
overflow-y: scroll;
}
#messages {
overflow: auto;
}
#messages .message {
height: 79px;
background: #999;
border-bottom: 1px solid #000;
}
#input {
position:fixed;
bottom:0;
left:0;
width:100%;
height: 45px;
}
#input .spacer {
padding: 5px;
}
#input input {
width: 100%;
height: 33px;
font-size: 20px;
line-height: 33px;
border: 1px solid #333;
text-indent: 5px;
color: #222;
margin: 0;
padding: 0;
}
See demo at: http://jsfiddle.net/audetwebdesign/5Y8gq/
First, set the height of 100% to the html and body tags, which allows you to reference the view port height.
You want the #header to be fixed towards the top of the page using position: fixed, similarly for your footer #input.
The key is to use absolute positioning on #content to stretch it between the bottom edge of the header and the top edge of the footer, and then apply overflow-y: scroll to allow it to scroll the content (list of messages).
Comment
The source code for the #input block may be placed outside of the #content block.