There are definitely various methods to have a div cover an entire screen with a full screen image in its background, but mostly all of them would adopt min-height:100% and background-size: cover property, what this would do is, if some other section, like footer/header is placed, it generally "floats"above" that full screen div.
Like this
Left image is what presently most solutions do. Right one is what should ideally be good.
One solution is to use vh units.
Any other CSS-only method which can support most browsers?
Thanks.
PS - Pardon me I cant elegantly put this to you.
What is the problem with using 90% instead of 100% min-height? Have a look at my code:
body, html {
height:100%;
padding: 0;
margin: 0;
text-align: center;
color:#FFF
}
.fullsection {
height:90%;
background:red;
}
.b { background:blue; }
.extra { height: 10%; }
footer {
height:10%;
background:black;
position: fixed;
width:100%;
bottom: 0;
}
<div class="fullsection">A</div>
<div class="fullsection b">B</div>
<div class="extra"></div>
<footer>footer</footer>
Each fullscreen section is 90% of page height and the footer is fixed at the bottom with 10% height. I have also added an empty "extra" div for the footer to rest at when you reach the bottom of page.
display: flex
#viewport {
display: flex;
flex-direction: column;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.content {
flex: 1;
background: #ddd;
}
.footer {
flex-basis: 10%;
background: #f00;
}
<div id="viewport">
<div class="content">
</div>
<div class="footer">
</div>
</div>
height: 90%/10%
#viewport {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.content {
height: 90%;
background: #ddd;
}
.footer {
height: 10%;
background: #f00;
}
<div id="viewport">
<div class="content">
</div>
<div class="footer">
</div>
</div>
Related
I am trying to keep an element from scrolling past left: 0 using position: sticky. This works fine in some cases, but I have noticed that if the element width increases it stops working. For example, the following works:
#header {
position: sticky;
left: 0;
width: 50%;
background-color: #888;
}
#page {
height: 80vh;
width: 120vw;
background-color: #000;
}
<div>
<div id="header">
Where is my mind?
</div>
<div id="page">
</div>
</div>
But if I increase the witdth of header element to 100% it stops working.
#header {
position: sticky;
left: 0;
width: 100%;
background-color: #888;
}
#page {
height: 80vh;
width: 120vw;
background-color: #000;
}
<div>
<div id="header">
Where is my mind?
</div>
<div id="page">
</div>
</div>
Why does this happen? And is there any way to use position: sticky to prevent the header element from scrolling when it's width is 100%? I prefer not to use position: fixed in this case.
I now understand what is happening. The issue is the different way the browser treats the width and height of a <div>. The default values of auto mean that the width of the <div> is 100% while the height is set by the content. If the content is wider than 100%, then on horizontal scroll the sticky element hits the end of the container <div> and, since it cannot leave the confines of the container, begins to scroll. This doesn't happen in the same situation for vertical scrolling since the container <div> is as tall as the content by default.
To prevent this happening, we have to ensure that the container <div> is as wide as its content. This can be done in most browsers (not Edge or Explorer) by including width: max-content in the container style. Alternatively, as proposed in mfluehr's answer, putting overflow: auto creates a new block formatting context that is as wide as the content. Another option is to use display: inline-block or inline-flex etc. to cause the container <div> to base its width on the content.
For example, using two of these techniques, you can create headers, sidebars and footers that stick for a page that can scroll vertically and horizontally:
body {
padding: 0;
margin: 0;
}
#app {
overflow: auto;
height: 100vh;
}
#header {
background: blue;
width: 100%;
height: 40px;
position: sticky;
top: 0;
left: 0;
z-index: 10;
color: white;
}
#sidebar {
position: sticky;
background: green;
width: 200px;
height: calc(100vh - 40px);
top: 40px;
left: 0;
color: white;
flex-grow: 0;
flex-shrink: 0;
}
#container {
display: inline-flex;
}
#content {
background: #555;
height: 200vh;
width: 200vw;
background: linear-gradient(135deg, #cc2, #a37);
flex-grow: 0;
flex-shrink: 0;
}
#footer {
background: #000;
height: 100px;
z-index: 100;
left: 0;
position: sticky;
color: white;
}
<div id="app">
<div id="header" ref="header">
Header content
</div>
<div id="container">
<div id="sidebar" ref="sidebar">
Sidebar content
</div>
<div id="content" ref="content">
Page content
</div>
</div>
<div id="footer" ref="footer">
Footer content
</div>
</div>
This is an interesting problem. I don't know why, but putting overflow: auto on the container around the <div>s seems to fix the issue.
You can add height: 100vh to the container to let the content inside overflow with scrollbars.
body {
margin: 0;
}
#container {
overflow: auto;
height: 100vh;
}
#header {
position: sticky;
left: 0;
width: 100%;
background-color: #888;
}
#page {
height: 200vh;
width: 120vw;
background: linear-gradient(135deg, #cc2, #a37);
}
<body>
<div id="container">
<div id="header">
This is the header.
</div>
<div id="page">
Page content goes here.
</div>
</div>
</body>
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>
I want to build a flexible structure with `CSS like this
TOP and BOTTOM divs have fixed height, while central box have responsive height. And all of them should cover the whole container div.
Can anyone tell me please how to do this?
body{position: relative;padding: 0px; margin: 0px;}
.top-sec{ background: #30a7fc none repeat scroll 0 0;
height: 40px;
left: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 100;}
.middle-sec{
bottom: 0;
clear: both;
left: 0;
overflow-x: auto;
overflow-y: initial;
position: fixed;
top: 40px;
width: 100%;
background: #000; color: #fff;
}
.bottom-sec{
background: #0000ff none repeat scroll 0 0;
bottom: 0;
height: 24px;
left: 0;
min-width: 100%;
padding: 0;
position: fixed;
right: 0;
z-index: 1000;
}
<div class="top-sec"></div>
<div class="middle-sec">Please put here big data</div>
<div class="bottom-sec"></div>
Quite easy.
Basic html:
<div class="header"></div>
<div class="main"></div>
<div class="footer"></div>
and basic css:
body, html {
height:100%;
margin:0;
}
.header, .footer {
height:30px;
background-color:black;
width:100%;
}
.main {
height:calc(100% - 30px - 30px);
background-color:red;
width:100%;
}
Just don't forget that when using "height" in % you need to include a fixed height in all parents of the element to make it work (in this case bodyand html)
JSFIDDLE
Given this markup:
<div class="container">
<div class="header"></div>
<div class="main"></div>
<div class="footer"></div>
</div>
These are the styles you need to use:
.container {
height: 100vh;
display: flex;
}
.header, .footer {
/* don't grow, don't shrink, be 50px */
flex: 0 0 50px;
background: black;
}
.main {
/* grow and shrink with the ratio of one */
flex: 1 1;
background: red;
}
Demo: http://jsbin.com/horarivopo/1/edit?html,css,output
Although be aware of browser support (IE10+ w/ prefixes): http://caniuse.com/#feat=viewport-units,flexbox
Here you have an example with CSS split for better understanding
Don't forget to vote and close the question, a lot of people tend to forget this, thanks.
/* flexbox */
main, header, footer, article { display: flex }
main { justify-content: space-between; flex-direction: column }
article { flex: 1 } /* fill available space */
/* flexbox optional rule */
header, footer, article { justify-content: center; align-items: center }
/* sizing */
html, body, main { height: 100% } /* CSS needs to know how to fill */
main, header, footer, article { width: 100%; max-width: 100% } /* max- for cross-browser quirks */
header, footer { height: 50px; line-height: 50px } /* same line-height centers text vertically */
/* styling */
body { color: white; margin: 0; padding: 0 }
header, footer { background-color: black }
article { background-color: red }
<main>
<header>some header</header>
<article>some article</article>
<footer>some footer</footer>
</main>
You can also try like this-
*{margin: 0;padding:0;}
html, body {height: 100%;color:#fff;}
header{height:50px;background: #000;position: absolute;top:0;width: 100%;}
section {min-height: calc(100% - 50px);margin-bottom: -50px;background:red;padding-top:50px;}
section:after {content: "";display: block;}
footer, section:after {height: 50px; }
footer{background: #000;}
<header>
Header
</header>
<section>
Here is Content and all.
</section>
<footer>
Footer
</footer>
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.
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 */
}