I have a page containing a header and three other divs of irrelevant content, like this.
+-----------+
| header |
+-----------+
| 1 | 2 |
+-----+-----+
| 3 |
+-----------+
What I need is for the tables to take up the remaining space on the page, but not extend beyond the viewport (there should be no vertical scrollbar on the page).
In other words, the height of 1, 2, and 3 should be exactly 50% of the remaining space (after the header). How can I accomplish this without JS and also without fixing the height of the header?
It can be done using CSS tables and quite a few nested div elements.
body, html {
margin: 0;
height: 100%;
}
.wrapper {
height: 100%;
background-color: tan;
display: table;
width: 100%; /* optional, depends on layout */
}
.header-row {
display: table-row;
}
.header-row img {
display: block;
width: 100%;
}
.content-row {
height: 100%;
display: table-row;
}
.content-row {
border: 1px dotted blue;
box-sizing: border-box;
height: 100%;
display: table-cell;
}
.content {
display: table;
width: 100%;
height: 100%;
}
.row {
display: table-row;
}
.row .cell {
display: table-cell;
height: 50%;
width: 100%;
border: 1px dotted blue;
}
.row .split {
width: 50%;
height: 100%;
float: left;
border: 1px dotted blue;
box-sizing: border-box;
}
<div class="wrapper">
<div class="header-row">
<div class="header">
<img src="http://placehold.it/1000x200">
</div>
</div>
<div class="content-row">
<div class="content">
<div class="row">
<div class="cell">
<div class="split">split</div>
<div class="split">split</div>
</div>
</div>
<div class="row">
<div class="cell">stuff</div>
</div>
</div>
</div>
</div>
Related
This question already has answers here:
How to remove the space between inline/inline-block elements?
(41 answers)
Closed 3 years ago.
I use display: inline-block for div.left - div.right and div.red - div.yellow but none of them are in the same line. I set the width exactly. But it does not work at all.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
margin: 0 auto;
width: 800px;
}
.left, .right, .red, .yellow {
display: inline-block;
vertical-align: top;
}
.left {
width: 250px;
height: 500px;
background: gray
}
.right {
width: 550px;
height: 550px;
background: blue;
}
.red {
background: red;
width: 275px;
height: 200px;
}
.yellow {
background: yellow;
width: 275px;
height: 200px;
}
<div class="container">
<div class="left"></div>
<div class="right">
<div class="red-yellow">
<div class="red"></div>
<div class="yellow"></div>
</div>
</div>
</div>
Update
If you need to keep inline-block styles, you need the .left and .right divs to add up to 800px. The thing with inline-block is that it will include white space and add it to the width. This is why the wrapping is still occurring. The following image shows the white space that is causing the wrapping.
There are many ways to remove white space and make this fit. One way is to add an HTML comment between the .left and right div, which removes all white space.
<div class="container">
<div class="left"></div><!--
--><div class="right">
<div class="red-yellow">
<div class="red"></div>
<div class="yellow"></div>
</div>
</div>
</div>
Demo
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
margin: 0 auto;
width: 800px;
}
.left, .right, .red, .yellow {
display: inline-block;
vertical-align: top;
}
.left {
width: 250px;
height: 500px;
background: gray
}
.right {
width: 550px;
height: 550px;
background: blue;
}
.red {
background: red;
width: 275px;
height: 200px;
}
.yellow {
background: yellow;
width: 275px;
height: 200px;
}
<div class="container">
<div class="left"></div><!--
--><div class="right">
<div class="red-yellow">
<div class="red"></div>
<div class="yellow"></div>
</div>
</div>
</div>
If you add display: flex to the .container, the immediate children (.left and .right) will align in the same row. The .right div is 50px taller than the .left div because of the explicit width being set (550px for .right, 500px for .left).
Also, you can remove this, as it will no longer have any effect due to the flexbox container.
.left, .right, .red, .yellow {
display: inline-block;
vertical-align: top;
}
Demo
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
margin: 0 auto;
width: 800px;
display: flex;
}
.left {
width: 250px;
height: 500px;
background: gray
}
.right {
width: 550px;
height: 550px;
background: blue;
}
.red {
background: red;
width: 275px;
height: 200px;
}
.yellow {
background: yellow;
width: 275px;
height: 200px;
}
<div class="container">
<div class="left"></div>
<div class="right">
<div class="red-yellow">
<div class="red"></div>
<div class="yellow"></div>
</div>
</div>
</div>
if use display: inline-block , there will be some space between the elements. In order to overcome that u can use float property so that every element will be aligned in the same line.
If u want to go with display: inline-block property, you have to reduce the width of .red and .yellow,say for example
.red,.yellow{ width: 270px}
I have a wrapper, which needs to be horizontally centered. I know of no other way to do it, except using position absolute.
#wrapper {
width: 721px;
height: 720px;
position: absolute;
margin: auto;
top: 136px;
left: 0;
right: 0;
background: white;
clear: both;
}
It contains three other divs, which are floated. If I change position of the wrapper to relative, those divs mess up.
____________________________________________
header
____________________________________________
__wrapper____________
| | |
| | |
| div1 | div2 |
| | |
| | |
| | |
|_________|__________|
| div3 |
|____________________|
__________________________________________
footer
__________________________________________
But I want to have a sticky footer, which will be always at the bottom of the site. No matter how much content I have, it will stay at the bottom of it. I could achieve it if my wrapper wasn't position:absolute, but since it can't push the footer bottom, I want to know is there any other way to do it?
.footer {
border-top: 1px solid #dcdcdc;
max-width: 100vw;
font-weight: bold;
text-align: center;
background: #f0f0f0;
width: 100%;
height: 80px;
}
As you can see in JS-FIDDLE the footer is hiding behind header.
Are you using bootstrap?
With bootstrap, your layout would be as simple as this code:
<div class="navbar navbar-fixed-top">
you header
</div>
<div class="row">
<div class="col-md-3 col-md-offset-3">
your div1
</div>
<div class="col-md-3 col-md-offset-6">
your div2
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">
your div3
</div>
</div>
<div class="navbar navbar-fixed-bottom">
your footer
</div>
And give to the CSS:
html, body {
padding-bottom: 55px;
padding-top: 55px;
}
As this should fit the navbar well in both top and bottom sides.
EDIT: Because you do not use frameworks, then:
Add this the css footer.
position: fixed;
bottom: 0;
This will show you the footer, because it is hidden behind the header.
This is a rough throw together, but in modern web development we get the joys of the wonderful flexbox. Here is a quick example
<div class="wrapper">
<div class="flex-wrapper">
<div class="flex-container">
<div class="div1">Box1</div>
<div class="div2">Box2</div>
</div>
<div class="div3">Box3</div>
</div>
</div>
.wrapper {
display:flex;
justify-content: center;
align-content: center;
height: 500px;
}
.flex-wrapper {
display:flex;
flex-direction: column;
align-self: center
}
.flex-container{
display: flex;
position: relative;
}
.div1,.div2 {
height:100px;
width:100px;
}
.div1 {
background-color:blue;
}
.div2 {
background-color:red;
}
.div3 {
background-color:green;
width:200px;
height:100px;
}
Just use that type of layout, but make another container around the 'wrapper' so that the footer isnt affected.
https://jsfiddle.net/wxokadrx/
Also, in case you are unfamiliar with flexbox: https://philipwalton.github.io/solved-by-flexbox/demos/vertical-centering/
If u don't want to use flex, this may help
First, it is not necessary to use position absolute to horizontally align a div.
<div id="outer">
<div id="inner">
</div>
</div>
<style>
#outer {
background-color: green;
}
#inner {
left: 0;
right: 0;
margin: auto;
height: 300px;
width: 400px;
background-color: red;
}
</style>
Here is the fiddle https://jsfiddle.net/x2j325n4/
Floating inner div's drops the height of wrapper to 0px. So replacing floats with display:inline-blocks may help.
<style>
#header {
width: 100%;
height: 50px;
background-color: pink;
}
#wrapper {
left: 0;
right: 0;
margin: auto;
width: 60%;
}
#div1 {
width: 30%;
height: 400px;
display: inline-block;
background-color: grey;
}
#div2 {
display: inline-block;
width: 60%;
height: 400px;
background-color: red;
}
#div3 {
width: 100%;
height: 400px;
display: inline-block;
background-color: blue;
}
#footer {
width: 100%;
height: 50px;
background-color: green;
}
</style>
<div id="header">
Hey i'm header
</div>
<div id="wrapper">
<div id="div1">
first div
</div>
<div id="div2">
second div
</div>
<div id="div3">
third div
</div>
</div>
<div id="footer">
Hey i'm footer
</div>
Fiddle : https://jsfiddle.net/rjhwxdL5/
or if u want the footer to stay at the bottom of your viewport, just use position: fixed; bottom: 0; in your footer
You should try clear property of CSS (in my case I've used a div class called clearfix), put this after .box2 like:
.clearfix:after {
content: '';
display: table;
clear: both;
}
.clearfix:before {
content: '';
display: table;
}
Have a look at the snippet below (use fullscreen mode):
.header {
min-width: 720px;
top: 0;
left: 0;
right: 0;
max-width: 100vw;
line-height: 80px;
font-weight: bold;
text-align: center;
margin: 0 auto;
border-bottom: 1px solid #dcdcdc;
background: #f0f0f0;
position: fixed;
width: 100%;
height: 80px;
z-index: 1;
}
#wrapper {
border: 1px solid blue;
width: 721px;
background: white;
margin: 120px auto 40px;
}
.box1 {
clear:both;
display: inline-block;
float:left;
height:300px;
width:360px;
border: 1px solid black;
}
.box2 {
clear:both;
display: inline-block;
float:right;
height:300px;
width:350px;
border: 1px solid black;
}
.footer {
border-top: 1px solid #dcdcdc;
max-width: 100vw;
font-weight: bold;
text-align: center;
background: #f0f0f0;
width: 100%;
height: 80px;
}
.clearfix:after {
content: '';
display: table;
clear: both;
}
.clearfix:before {
content: '';
display: table;
}
<div class=header>
Asdf
</div>
<div id="wrapper">
<div class="box1"> asdf</div>
<div class="box2"> asdf</div>
<div class="clearfix"></div>
</div>
<footer class="footer">
ASDAFASFAFASFSAF
</footer>
Hope this helps!
I have a container with a fixed height, inside is an <article> with display: table; property. I want this <article> to fill his parent, both in height and width (height: 100%;width: 100%;).
The tricky part is this table has 3 children : a header and a footer, both with variable heights, and a third, main element, that should fill the remaining space.
The problem is, in that main element, I have an <img> bigger in height than the main container, stretching the table, despite the height: 100%; (illustration here :
Is there a way to limit the img's height so that it doesn't stretch the table ? I tried height/max-height: 100% with no luck.
As the code needs to be IE9 compatible, I can't use a flexbox layout, hence the display: table-* approach.
Here's the full code and a codepen, notice how the table is bigger than its parent container (<section> with red border), due to the img : http://codepen.io/anon/pen/xGJLLa
HTML
<section>
<article class="table">
<header class="row">
<h2>My header</h2>
</header>
<div class="mainrow row">
<div class="vmiddle">
<img src="http://lorempixel.com/200/300/abstract/" alt="Myimg" />
</div>
<div>
<p>Lorem ipsum [...]</p>
</div>
</div>
<footer class="row">
My Footer
</footer>
</article>
</section>
CSS
section {
border: 3px solid red;
height: 15em;
}
.table {
display: table;
height: 100%;
width: 100%;
}
.row {
display: table-row;
vertical-align: middle;
}
header { background-color: lightgrey; }
h2 {
display: table-cell;
padding: 0.5em 0;
vertical-align: middle;
}
.mainrow { background-color: lightyellow; }
.mainrow>div {
float: left;
height: 100%;
width: 50%;
}
.vmiddle {
font-size: 0;
text-align: center;
}
.vmiddle:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
img {
max-height: 100%;
max-width: 100%;
vertical-align: middle;
}
footer { background-color: lightblue; }
Thanks
I am a bit newbie with CSS and i am pretty obfuscated trying to center a group of divs inside a div. What i want:
divs 2,3 and 4 should be centered inside div1.
My approach:
.div1 {
display: inline-block;
margin: 0 auto;
text-align: center;
}
.restofdivs {
width: 470px;
margin: 20px;
min-height: 1px;
float:center
}
the result is: the 3 divs (2,3 and 4) one on top of another...
Regards,
This can easily be done with table display:
.table-display {
display: table;
width: 100%;
}
.cell-display {
display: table-cell;
}
.div1, .div2, .div3, .div4 {
padding: 40px;
}
.div1 {
background: #ABC;
}
.div2 {
background: #DEF;
}
.div3 {
background: #CAD;
}
.div4 {
background: #FAD;
}
<div class="div1">
<div class="table-display">
<div class="cell-display div2"></div>
<div class="cell-display">
<div class="div3"></div>
<div class="div4"></div>
</div>
</div>
</div>
Maybe set a width on .div1 and remove inline-block from .div1
.div1 {
width: 960px;
margin: 0 auto;
text-align: center;
}
.restofdivs {
width: 470px;
margin: 20px;
min-height: 1px;
}
The most common way to center a block element if you know it's width is to define the width and use "margin: 0 auto". This tells the browser to give a top and bottom margin of 0, and to automatically determine equal margins on the left and right.
Using floats, you can create the layout you described as follows:
http://jsfiddle.net/ynt4suee/
Markup:
<div>
<div id="one" class="border clearfix">one
<div id="wrapper">
<div id="two" class="border">two</div>
<div class="subcontainer">
<div id="three" class="border">three</div>
<div id="four" class="border">four</div>
</div>
</div>
</div>
CSS:
div.border{
border: 1px solid red;
}
div#wrapper{
width: 400px;
margin: 0 auto;
}
div#two{
width: 250px;
float: left;
}
div.subcontainer{
float: right;
width: 130px;
}
.clearfix:after {
content: " "; /* Older browser do not support empty content */
visibility: hidden;
display: block;
height: 0;
clear: both;
}
Here's another approach, using inline-block elements for the inner divs instead:
http://jsfiddle.net/xojqq4v5/
Markup:
<div id="one" class="border">
div 1
<div id="wrapper">
<div id="two" class="border">div 2</div>
<div id="subcontainer">
<div id="three" class="border">div 3</div>
<div id="four" class="border">div 4</div>
</div>
</div>
</div>
CSS:
div.border{
border: 1px solid red;
margin-bottom: 5px;
}
div#wrapper{
width: 450px;
margin: 0 auto;
}
div#two, div#subcontainer{
display: inline-block;
vertical-align: top;
}
div#two{
width: 300px;
}
div#three, div#four{
width: 140px;
}
Still, so long as you know the total width of the inner divs, you can center the wrapper using "margin: 0 auto", which has the advantage of not centering text on all child elements unless otherwise specified.
The difference here is that to lay out the inner divs in columns, div 2 and the container div containing divs 3 and 4 are defined as inline-block elements.
http://jsfiddle.net/hqu8N/
<div id="container">
<div id="one"><p>one</p></div>
<div id="two"><p>two</p></div>
<div id="footer"><p>footer</p></div>
</div>
#container {
display: table;
width: 200px;
height: 200px;
background-color: red;
border-spacing: 5px;
}
#one {
display: table-cell;
background-color: yellow;
}
#two {
display: table-cell;
background-color: blue;
}
#footer {
display: table-footer-group;
background-color: green;
}
Basically i want the green footer to extend over to the end of the blue ID. And also between the green footer and the yellow ID it's 10 px of space instead of 5px. What am i doing wrong ?
I used grid for your case, and a grid-gap for a 5px distance:
#container {
display: grid;
grid-gap: 5px;
width: 200px;
height: 200px;
background-color: red;
}
#one {
background-color: yellow;
}
#two {
background-color: blue;
}
#footer {
background-color: green;
grid-column: 1 / 3;
}
<div id="container">
<div id="one">
<p>one</p>
</div>
<div id="two">
<p>two</p>
</div>
<div id="footer">
<p>footer</p>
</div>
</div>
https://jsfiddle.net/arman1373/4xkgd5Lj/
I had the same issue with both the header-group and footer-group.
I solved this by putting a container around my table which specified the basic width. Inside that I put a div with display: table properties as below
#tContainer {
width: 80%;
margin; 0% auto;
}
#tData {
display: table;
width: 100%
}
.tDataRow {
display: table-row;
}
.tDataRow span{
display: table-cell;
}
I didn't use table-header or table-footer but defined them separately:
.tDataFooter {
display: block;
width: auto;
}
And the element structure as follows:
<div id="tContainer">
<div id="tData">
<div class="tDataRow"><span class="dHeader"> xyz </span></div>
<div class="tDataRow"><span> data sets repeat </span></div>
</div>
<div class="tDataFooter"> Footer data </div>
</div>
I am hoping someone else has a neater solution but I couldn't get the header and footer to fit at all, not even the header columns to align with the data
Result:
Resulting table sample