I have two divs inside a container:
<div id="outer">
<div id="A">
Test<br/>
Test<br/>
Test<br/>
Test<br/>
Test<br/>
Test<br/>Test<br/>Test<br/>Test<br/>Test<br/>Test<br/>Test<br/>Test<br/>
</div>
<div id="B"></div>
</div>
What I need is that 'B' stays at the bottom and has a fixed size (200px). 'A' should stay at the top and fill the rest of the space available. When I now resize the parent element 'B' should stay at 200px and 'A' should shrink.
I wasn't able to get this working with pure CSS but I would really prefer to have it in CSS only.
I've made a Fiddle containing a solution with jQuery but I want to avoid JavaScript for layouting whenever it's possible.
http://jsfiddle.net/t6B2e/
As an alternative to the other answers, you could use the calc() CSS function:
#A{
height: calc( 100% - 200px );
width: 100%;
background: #cccccc;
overflow: auto;
}
#B{
height: 200px;
width: 100%;
background: blue;
}
Example Fiddle
Browser support is rather good
you can use display:flex; but keep jQuery as fallback ... or CSS as fallback. Whatever here a basic example:
body {background:black;color:white;}
#outer {
display:flex;
flex-direction:column;
}
html, body , #outer {
height:100%;
margin:0;
}
#a {
overflow:auto;
}
#b {
background:blue;
min-height: 200px; /* you can use flex:1; to size it too */
}
Important: do not use Capital letter or numbers as first character naming ID or CLASS. it is not allowed and some browser will follow W3C recommendation. CSS can not be applied.
To have one growing and the other shrink and overflow, you can tune it with flex:xx;
Example where both div have a min-height and show scrollbar if needed. The blue one has priority, the other one has a min-height too, so content can still be readable
Example Here.
body {background:black;color:white;}
#outer {
display:flex;
flex-direction:column;
}
html, body , #outer {
height:100%;
margin:0;
}
#a, #b {
min-height: 100px; /* don't give a min-height to #a and it can shrink down to zero */
overflow:auto;
}
#a {
flex:2;
}
#b {
background:blue;
}
If I am understanding you correctly, then all you need to do is change your #A css.
Complete example:
#A{
position: absolute;
bottom:200px;
top: 0;
max-height: 100%;
width: 100%;
background: #cccccc;
overflow: auto;
}
#B{
position:absolute;
bottom: 0;
height: 200px;
width: 100%;
background: blue;
}
Basically, I removed the height and added the bottom:200px which forces the bottom of the element to always be 200px from the bottom of the parent.
Here is a working example
If you want the whole outer area to scroll you can do it this way with minimal CSS http://codepen.io/2ne/pen/mvoaw/
#outer {
padding-bottom: 200px;
}
#A {
}
#B {
position: fixed;
bottom: 0;
height: 200px;
width: 100%;
background: blue;
}
Related
JsFiddle: http://jsfiddle.net/techsin/csfvb91u/
(just realized normal div is collapsing ALSO to size of content, is min height completely useless?)
I need two divs, one left, and on right. Left one is 100px wide and stays that way. While, right div expands infinitely and doesn't shrink beyond 400px. Both Divs should be the height of parent. And parent has no exact height but minimum height of 800. So if content of one of these 2 divs were to push the height of div and extend it. Then The height of parent should increase and thus also the height of other div.
I tried using floats. I managed to some extent. However left side which was on float left, its height kept collapsing and didn't follow height:100% rule. It only worked if parent had definite width.
I tried using inline block but then right div won't expand to fillin the available space..
Why in the world css doesn't have fit-content, fill-available, choose what % refers to, choose what to position against, use vector or use pngs to shape div, inset textshadow, etc.
<div class="cont">
<div class="a"></div>
<div class="b"></div>
</div>
try with display:table and display:table-cell for child you will need to give fixed with for the left div
demo - http://jsfiddle.net/z90fma6e/
html,
body {
height: 100%;
}
* {
margin: 0;
padding: 0;
}
.cont {
display: table;
height: 100%;
}
.left,
.right {
height: 100%;
}
.left {
width: 200px;
background: red;
display: block;
}
.right {
width: 100%;
display: table-cell;
background: green;
}
<div class="cont">
<div class="left">fixed
<br/>height adjusts</div>
<div class="right">expands
<br/>height adjusts</div>
</div>
Sounds like your divs are collapsing. Your going to need a clearfix you can add to divs. There are a few ways to do this; however, this option is best.
.clearfix:after {
content: ".";
visibility: hidden;
display: block;
height: 0;
clear: both;
}
Add this clearfix class and css to your divs so they wont collapse.
You can read more about them at cssTricks
perfect use case for CSS flex layout:
<style>
body {
display: flex;
flex-direction: row;
margin: 0;
padding: 0;
}
div:first-child {
width: 200px;
background: red;
}
div:last-child {
flex: 1;
background: blue;
}
</style>
<div></div>
<div></div>
If you wish to support IE8 or earlier I would suggest you to use positioning:
Here's what I came up with
Fiddle : http://jsfiddle.net/csfvb91u/4/
If the content on the right is going out of the container, you can always use margin-right:200px as the right side container is shifted 200px using left:200px. Hope you get what I'm saying... :)
HTML:
<div class="cont">
<div class="a"></div>
<div class="b"></div>
</div>
CSS:
.a {
position:absolute;
width: 200px;
background-color: green;
height: 100%;
}
.b {
width:100%;
position:absolute;
left:200px;
background-color: blue;
height: 100%;
}
.cont {
position:relative;
border:1px solid #333;
min-height:300px;
overflow:hidden;
}
Trying to stack 3 DIVs vertically, so that the top DIV is 25% of screen height, middle is 50%, and bottom is 25%, but they seem to extend the screen and I end up having a scrollbar.
body,html {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#top {
width: 100%;
height: 25%;
background: #464646;
}
#middle {
width: 100%;
padding: 15px 0 15px 0;
margin: 0 auto 0 auto;
min-width: 657px;
height: 50%;
text-align: center;
vertical-align:middle;
}
#bottom {
width: 100%;
padding: 15px 0 15px 0;
height: 25%;
background: #988056;
}
<div id="top"></div>
<div id="middle"><img src="logo.png"></div>
<div id="bottom"></div>
As Hashem mentions in a comment above, box-sizing: border-box is considered best practice nowadays. Add the following to your CSS and you should be good to go:
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
Here is a good read-up for you.
That said, if you are working on an existing product and have lots of legacy code that would be broken if you did this, you need to work around the margins and paddings on your site sections, they add height, and that makes it all add up to more than 100%.
And if you are uncomfortable with that as well, look up flex-box layout. Only works in modern browsers though, so don't do it if you need old IE support.
This is due to the padding that you have added to middle and bottom divs.
The width and height styles always specify the width/height of textual area i.e. width/height of the "div's content" and they do NOT include the padding value. The padding is an extra space added apart from the width/height.
Try the following, and it should give you the desired results:
HTML:
<div id="top"></div>
<div id="middle"><img src="logo.png"></div>
<div id="bottom"></div>
CSS:
body,html {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#top {
width: 100%;
height: 25%;
background: #464646;
}
#middle {
width: 100%;
margin: 0 auto 0 auto;
min-width: 657px;
height: 50%;
text-align: center;
vertical-align:middle;
}
#bottom {
width: 100%;
height: 25%;
background: #988056;
}
Working LIVE.
The CSS flexbox layout module is especially made to handle requirements like this.
You can use the flex-grow property:
The flex-grow property is a sub-property of the Flexible Box Layout module.
IT defines the ability for a flex item to grow if necessary. It accepts a unitless value that serves as a proportion. It dictates what amount of the available space inside the flex container the item should take up.
For example, if all items have flex-grow set to 1, every child will set to an equal size inside the container. If you were to give one of the children a value of 2, that child would take up twice as much space as the others.
*{
margin: 0;
padding: 0;
}
html,body {
height: 100%;
}
#container{
-webkit-display:flex;
-moz-display:flex;
-ms-display:flex;
display:flex;
-webkit-flex-direction:column;
-moz-flex-direction:column;
-ms-flex-direction:column;
flex-direction:column;
height:100%;
}
#top {
-webkit-flex:1;
-moz-flex:1;
-ms-flex:1;
flex:1;
background: #464646;
}
#middle {
-webkit-flex:2;
-moz-flex:2;
-ms-flex:2;
flex:2;
background:dodgerblue;
}
#bottom {
-webkit-flex:1;
-moz-flex:1;
-ms-flex:1;
flex:1;
background: #988056;
}
<div id="container">
<div id="top"></div>
<div id="middle"></div>
<div id="bottom"></div>
</div>
In this scenario, since you're concerned about screen height, you might want to investigate the 'vh' css rule.
For instance, if you wanted to stack your top, middle, and bottom evenly, you could do it with pure css:
#top, #bottom, #middle {
height: 32vh;
}
Or, as pertains to the question:
#top { height: 25vh; }
#middle { height: 50vh; }
#bottom { height 24vh; } /*24 vh so you have a little wiggle room*/
Examine here:
body { margin : 0; padding: 0}
div { border: #ccc solid 1px; }
#top { height: 25vh; }
#middle { height: 50vh; }
#bottom { height: 24vh; }
/*24 vh so you have a little wiggle room*/
<div id="top">top</div>
<div id="middle">middle</div>
<div id="bottom">bottom</div>
In android you can make 3 vertical views fill up their parent each with a different size by using weights. I have 3 divs on my html page, the two that need to always be at the bottom are both 40px tall, and then there will be one above those that need to fill in the rest of the space of the parent div. Is there any way to do this without using javascript?
Yes, you can use display:table-row for the 3 divs and set the height as 40px for the two at the bottom.
Using display:tablexxx is quite often delicate, especially in a cross browser fashion, so I'm building a demonstration on how you could have this cover the whole page :
Demonstration
HTML of the demo :
<div id=w>
<div id=a>
<div id=b>B</div>
<div id=c>C</div>
<div id=d>D</div>
</div>
</div>
CSS of the demo :
#w {
position: fixed;
top: 0; left:0; right: 0; bottom: 0;
}
#a{
display: table;
width:100%; height:100%;
}
#b {
display: table-row;
background: red;
}
#c {
display: table-row;
background: yellow;
height:40px;
}
#d {
display: table-row;
background: green;
height:40px;
}
I want to split up the view in four parts. A header at the top, using full page width and fixed height.
The remaining page is split up in two blocks of the same height, the upper of them contains two same-sized blocks next to each other.
What I tried is (without the header):
#wrap {
width: 100%;
height: 100%;
}
#block12 {
width: 100%;
max-height: 49%;
}
#block1,
#block2 {
width: 50%;
height: 100%;
float: left;
overflow-y: scroll;
}
#block3 {
width: 100%;
height: 49%;
overflow: auto;
/*background: blue;*/
}
.clear {
clear: both;
}
<div id="wrap">
<div id="block12">
<div id="block1"></div>
<div id="block2"></div>
<div class="clear"></div>
</div>
<div id="block3"></div>
</div>
Apparently, using a percentage value for the height won't work that way. Why is that so?
add this to you CSS:
html, body
{
height: 100%;
}
working Fiddle
when you say to wrap to be 100%, 100% of what? of its parent (body), so his parent has to have some height.
and the same goes for body, his parent his html. html parent his the viewport..
so, by setting them both to 100%, wrap can also have a percentage height.
also:
the elements have some default padding/margin, that causes them to span a little more then the height you applied to them. (causing a scroll bar)
you can use
*
{
padding: 0;
margin: 0;
}
to disable that.
Look at That Fiddle
When you set a percentage height on an element who's parent elements don't have heights set, the parent elements have a default
height: auto;
You are asking the browser to calculate a height from an undefined value. Since that would equal a null-value, the result is that the browser does nothing with the height of child elements.
Besides using a JavaScript solution you could use this deadly easy table method:
#parent3 {
display: table;
width: 100%;
}
#parent3 .between {
display: table-row;
}
#parent3 .child {
display: table-cell;
}
Preview on http://jsbin.com/IkEqAfi/1
Example 1: Not working
Example 2: Fix height
Example 3: Table method
But: Bare in mind, that the table method only works properly in all modern Browsers and the Internet Explorer 8 and higher. As Fallback you could use JavaScript.
add this to your css:
html, body{height: 100%}
and change the max-height of #block12 to height
Explanation:
Basically #wrap was 100% height (relative measure) but when you use relative measures it looks for its parent element's measure, and it's normally undefined because it's also relative. The only element(s) being able to use a relative heights are body and or html themselves depending on the browser, the rest of the elements need a parent element with absolute height.
But be careful, it's tricky playing around with relative heights, you have to calculate properly your header's height so you can substract it from the other element's percentages.
Percentage in width works but percentage in height will not work unless you specify a specific height for any parent in the dependent loop...
See this :
percentage in height doesn’t work?
The div take the height of its parent, but since it has no content (expecpt for your divs) it will only be as height as its content.
You need to set the height of the body and html:
HTML:
<div class="block12">
<div class="block1">1</div>
<div class="block2">2</div>
</div>
<div class="block3">3</div>
CSS:
body, html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.block12 {
width: 100%;
height: 50%;
background: yellow;
overflow: auto;
}
.block1, .block2 {
width: 50%;
height: 100%;
display: inline-block;
margin-right: -4px;
background: lightgreen;
}
.block2 { background: lightgray }
.block3 {
width: 100%;
height: 50%;
background: lightblue;
}
And a JSFiddle
Basically, the problem lies in block12. for the block1/2 to take up the total height of the block12, it must have a defined height. This stack overflow post explains that in really good detail.
So setting a defined height for block12 will allow you to set a proper height. I have created an example on JSfiddle that will show you the the blocks can be floated next to one another if the block12 div is set to a standard height through out the page.
Here is an example including a header and block3 div with some content in for examples.
#header{
position:absolute;
top:0;
left:0;
width:100%;
height:20%;
}
#block12{
position:absolute;
top:20%;
width:100%;
left:0;
height:40%;
}
#block1,#block2{
float:left;
overflow-y: scroll;
text-align:center;
color:red;
width:50%;
height:100%;
}
#clear{clear:both;}
#block3{
position:absolute;
bottom:0;
color:blue;
height:40%;
}
I want to create three, stacked divs. The top and the bottom ones will be of fixed height, whereas the one in the middle will have a dynamic height that expands to fill the remaining space:
I've tried numerous things, such as setting the height to auto. I do have a solution, but it involves JavaScript (i.e., calculating the remaining height) but I was wondering if there was a pure CSS solution.
There's a CSS solution, but it won't work in older browsers. You need to use the calc "function" that is new to CSS, combined with height: 100%. If you've never used height: 100% before, you know that every parent element of the one you want to be 100% tall must also be set to height:100%. calc can take a percentage value and subtract pixels from it, so you just need to set it to be 100% minus however tall the top and bottom divs are.
Supported by: IE9+, Firefox 4+, Chrome 19+, Safari 6+
http://caniuse.com/calc
HTML
<div id='top'></div>
<div id='mid'></div>
<div id='bot'></div>
CSS
html, body
{
height: 100%;
}
#top, #bot
{
height: 50px;
background: red;
}
#mid
{
height: calc(100% - 100px);
}
FIDDLE: http://jsfiddle.net/jakelauer/9cYUB/
One solution is to do it with position absolute.
The downside of this approach is that if the total height of surrounding is smaller then the sum of the fixed heights the container will not be visible anymore.
Another thing to be noted is that this is probably a bad solution if you want to target mobile devices. It always depends on the exact situation if this solution is suitable.
If i remember right you will only have problems with IE 6 (on desktop) which does not support the top bottom combination for the position absolute.
HTML
<div class="header"></div>
<div class="container"></div>
<div class="footer"></div>
CSS
.header, .container, .footer{
position: absolute;
outline: 1px solid black;
}
.header {
left: 0px;
top: 0px;
right : 0px;
height: 50px;
}
.container {
left: 0px;
top: 50px;
right : 0px;
bottom: 50px;
}
.footer {
left: 0px;
bottom: 0px;
right : 0px;
height: 50px;
}
JSFiddle
You can do it with a HTML table if you need older browser support, or if you need to support IE8+ or higher you could use the CSS table layout.
Here's a jsFiddle using CSS table layout.
HTML
<div>
<div>
<div>Fixed Height</div>
</div>
<div>
<div>
<div>Variable Height</div>
</div>
</div>
<div>
<div>Fixed Height</div>
</div>
</div>
CSS
html, body {
height:100%;
width: 100%;
margin: 0px;
padding: 0px;
text-align: center;
font-size: 20pt;
font-family: Verdana;
}
body > div {
display:table;
width: 100%;
height:100%;
}
body > div > div {
display: table-row;
}
body > div > div > div {
display: table-cell;
vertical-align: middle;
}
body > div > div:nth-child(odd) {
background: grey;
color: #FFF;
height: 100px;
}
body > div > div:nth-child(even) {
height:100%;
width:100%;
}
body > div > div:nth-child(even) >div {
height:100%;
width:100%;
overflow:hidden;
}
If i understand you request you need to use wrap div: http://www.cssstickyfooter.com/using-sticky-footer-code.html