How do i make this layout in css, divs are collapsing - html

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;
}

Related

How to put divs on opposite sides of parent div, with parent width relative to them on scaling?

I have a container div (that cannot be floated) with two children elements. I want child elements to be on opposite sides - first on left, second on right. On 100% browser width children summary width is less than container, but on greater scales it is not, so container should be greater too. How to set container to grow when it's gloat child grow?
UPD: something like this
I need all elements to stay one line in any scale.
<div id="page">
<div id="container">
<div id="left">
<div>first</div>
<div>second</div>
<div>third</div>
</div>
<div id="right">
right
</div>
</div>
</div>
<style>
#page {
background-color: grey;
width: 100%;
height: 300px;
}
#container {
/*this styles are needed to other parts*/
position: relative;
clear: both;
/*=====================================*/
background-color:red;
height: 50px;
width: 90%;
margin: 0 5%;
}
#left {
float: left;
background-color: blue;
}
#left div {
width: 50px;
display: inline-block;
}
#right{
float: right;
background-color: green;
display: block;
max-width: 200px;
}
</style>
.container {
display: flex;
justify-content: space-between;
}
It should do that.
Google up FlexBox Introduction for good explaination.
something like this ?
I've used display:flex to let the two divs line up nicely, floats only needed for the inner boxed
https://jsfiddle.net/070rk2e1/1/

Vertical align fluid div within another fluid div

I've seen plenty of solutions if the child div has a fixed width, but not if it is fluid.
The parent div should have a fixed height (150px) and fluid width (80%).
The child div should have a fluid height (expands with content) and fluid width (always 100%).
I want to get the child div to vertically align within the parent div. All content within the child div should also be horizontally centered.
Here's what I have right now:
http://jsfiddle.net/6986r/
<div class="s1">
<div class="centereddiv">This green div should be vertically centered.</div>
</div>
-
body, html {
height: 100%;
margin: 0;
}
.s1 {
width:100%;
height: 150px;
display: block;
background-color: red;
float: left;
}
.centereddiv {
color: black;
text-align: center;
background-color: green;
}
If you do not mind older browser, you may use the display:flex property (aside the table property already proposed by #SW4)
Notice that display:table can be used as a fall back for older browser
DEMO
Basic update to your CSS:
.parent {
display:flex;
}
.childcentereddiv {
margin:auto;
}
Likely the most flexible implementation would be to leverage display:table, however you will also need to adapt your HTML slightly and add an additional parent:
Demo Fiddle
<div class="table">
<div class="cell">
<div class="childcentereddiv">This green div should be vertically centered.</div>
</div>
</div>
CSS
body, html {
height: 100%;
margin: 0;
width:100%;
padding:0;
}
.table {
height: 150px;
background-color: red;
display:table;
width:80%;
}
.cell {
display:table-cell;
vertical-align:middle;
}
.childcentereddiv {
color: black;
text-align: center;
background-color: green;
}

Relative div height

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%;
}

Create three divs such that the top and bottom ones have fixed height, and the middle one has dynamic height?

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

Div width 100% minus fixed amount of pixels

How can I achieve the following structure without using tables or JavaScript? The white borders represent edges of divs and aren't relevant to the question.
The size of the area in the middle is going to vary, but it will have exact pixel values and the whole structure should scale according to those values. To simplify it, I'd need a way to set "100% - n px" width to the top-middle and bottom-middle divs.
I'd appreciate a clean cross-browser solution, but in case it's not possible, CSS hacks will do.
Here's a bonus. Another structure I've been struggling with and end up using tables or JavaScript. It's slightly different, but introduces new problems. I've been mainly using it in jQuery-based windowing system, but I'd like to keep the layout out of the script and only control the size of one element (the middle one).
New way I've just stumbled upon: css calc():
.calculated-width {
width: -webkit-calc(100% - 100px);
width: -moz-calc(100% - 100px);
width: calc(100% - 100px);
}​
Source: css width 100% minus 100px
You can use nested elements and padding to get a left and right edge on the toolbar. The default width of a div element is auto, which means that it uses the available width. You can then add padding to the element and it still keeps within the available width.
Here is an example that you can use for putting images as left and right rounded corners, and a center image that repeats between them.
The HTML:
<div class="Header">
<div>
<div>This is the dynamic center area</div>
</div>
</div>
The CSS:
.Header {
background: url(left.gif) no-repeat;
padding-left: 30px;
}
.Header div {
background: url(right.gif) top right no-repeat;
padding-right: 30px;
}
.Header div div {
background: url(center.gif) repeat-x;
padding: 0;
height: 30px;
}
While Guffa's answer works in many situations, in some cases you may not want the left and/or right pieces of padding to be the parent of the center div. In these cases, you can use a block formatting context on the center and float the padding divs left and right. Here's the code
The HTML:
<div class="container">
<div class="left"></div>
<div class="right"></div>
<div class="center"></div>
</div>
The CSS:
.container {
width: 100px;
height: 20px;
}
.left, .right {
width: 20px;
height: 100%;
float: left;
background: black;
}
.right {
float: right;
}
.center {
overflow: auto;
height: 100%;
background: blue;
}
I feel that this element hierarchy is more natural when compared to nested nested divs, and better represents what's on the page. Because of this, borders, padding, and margin can be applied normally to all elements (ie: this 'naturality' goes beyond style and has ramifications).
Note that this only works on divs and other elements that share its 'fill 100% of the width by default' property. Inputs, tables, and possibly others will require you to wrap them in a container div and add a little more css to restore this quality. If you're unlucky enough to be in that situation, contact me and I'll dig up the css.
jsfiddle here: jsfiddle.net/RgdeQ
Enjoy!
You can make use of Flexbox layout. You need to set flex: 1 on the element that needs to have dynamic width or height for flex-direction: row and column respectively.
Dynamic width:
HTML
<div class="container">
<div class="fixed-width">
1
</div>
<div class="flexible-width">
2
</div>
<div class="fixed-width">
3
</div>
</div>
CSS
.container {
display: flex;
}
.fixed-width {
width: 200px; /* Fixed width or flex-basis: 200px */
}
.flexible-width {
flex: 1; /* Stretch to occupy remaining width i.e. flex-grow: 1 and flex-shrink: 1*/
}
Output:
.container {
display: flex;
width: 100%;
color: #fff;
font-family: Roboto;
}
.fixed-width {
background: #9BCB3C;
width: 200px; /* Fixed width */
text-align: center;
}
.flexible-width {
background: #88BEF5;
flex: 1; /* Stretch to occupy remaining width */
text-align: center;
}
<div class="container">
<div class="fixed-width">
1
</div>
<div class="flexible-width">
2
</div>
<div class="fixed-width">
3
</div>
</div>
Dynamic height:
HTML
<div class="container">
<div class="fixed-height">
1
</div>
<div class="flexible-height">
2
</div>
<div class="fixed-height">
3
</div>
</div>
CSS
.container {
display: flex;
}
.fixed-height {
height: 200px; /* Fixed height or flex-basis: 200px */
}
.flexible-height {
flex: 1; /* Stretch to occupy remaining height i.e. flex-grow: 1 and flex-shrink: 1*/
}
Output:
.container {
display: flex;
flex-direction: column;
height: 100vh;
color: #fff;
font-family: Roboto;
}
.fixed-height {
background: #9BCB3C;
height: 50px; /* Fixed height or flex-basis: 100px */
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
}
.flexible-height {
background: #88BEF5;
flex: 1; /* Stretch to occupy remaining width */
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
}
<div class="container">
<div class="fixed-height">
1
</div>
<div class="flexible-height">
2
</div>
<div class="fixed-height">
3
</div>
</div>
The usual way to do it is as outlined by Guffa, nested elements. It's a bit sad having to add extra markup to get the hooks you need for this, but in practice a wrapper div here or there isn't going to hurt anyone.
If you must do it without extra elements (eg. when you don't have control of the page markup), you can use box-sizing, which has pretty decent but not complete or simple browser support. Likely more fun than having to rely on scripting though.
Maybe I'm being dumb, but isn't table the obvious solution here?
<div class="parent">
<div class="fixed">
<div class="stretchToFit">
</div>
.parent{ display: table; width 100%; }
.fixed { display: table-cell; width: 150px; }
.stretchToFit{ display: table-cell; vertical-align: top}
Another way that I've figured out in chrome is even simpler, but man is it a hack!
.fixed{
float: left
}
.stretchToFit{
display: table-cell;
width: 1%;
}
This alone should fill the rest of the line horizontally, as table-cells do. However, you get some strange issues with it going over 100% of its parent, setting the width to a percent value fixes it though.
We can achieve this using flex-box very easily.
If we have three elements like Header, MiddleContainer and Footer. And we want to give some fixed height to Header and Footer. then we can write like this:
For React/RN(defaults are 'display' as flex and 'flexDirection' as column), in web css we'll have to specify the body container or container containing these as display: 'flex', flex-direction: 'column' like below:
container-containing-these-elements: {
display: flex,
flex-direction: column
}
header: {
height: 40,
},
middle-container: {
flex: 1, // this will take the rest of the space available.
},
footer: {
height: 100,
}
what if your wrapping div was 100% and you used padding for a pixel amount, then if the padding # needs to be dynamic, you can easily use jQuery to modify your padding amount when your events fire.
I had a similar issue where I wanted a banner across the top of the screen that had one image on the left and a repeating image on the right to the edge of the screen. I ended up resolving it like so:
CSS:
.banner_left {
position: absolute;
top: 0px;
left: 0px;
width: 131px;
height: 150px;
background-image: url("left_image.jpg");
background-repeat: no-repeat;
}
.banner_right {
position: absolute;
top: 0px;
left: 131px;
right: 0px;
height: 150px;
background-image: url("right_repeating_image.jpg");
background-repeat: repeat-x;
background-position: top left;
}
The key was the right tag. I'm basically specifying that I want it to repeat from 131px in from the left to 0px from the right.
In some contexts, you can leverage margin settings to effectively specify "100% width minus N pixels". See the accepted answer to this question.