Cannot find a solution for this (what I'm guessing must be a pretty common problem) anywhere.
I am creating a responsive design with a sidebar, where the sidebar needs to have a fixed width of 200px and has unknown height. How can I make it so the main content area takes up all the remaining width, without anything misbehaving.
The closest I've come to it is the following, but the problem with it is that the sidebar can overlap the footer. Can anyone suggest a fix for my code, or share with me some code that works?
* {
padding: 0;
margin: 0;
outline: 0;
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box;
box-sizing: content-box;
}
body {
background: orange;
}
#container {
max-width: 1000px;
min-width: 768px;
margin: 0 auto;
background: yellow;
position: relative;
height: 100%;
}
#header {
background: purple;
color: white;
text-align: center;
padding: 10px;
}
#main {
position: relative;
}
aside {
background: blue;
width: 200px;
color: white;
position: absolute;
top: 0;
/* change this to "right: 0;" if you want the aside on the right. Also, change the "margin-left" code, below. */
left: 0;
padding-top: 20px;
padding-bottom: 20px;
padding-left: 10px; /* If you change this value, remember to change the margin-left value of #primary */
padding-right: 10px; /* ditto */
}
#primary {
background: red;
/* change this to margin-right if you want the aside on the right. Also change the "left" code, above. */
margin-left: 220px; /* aside_width + aside_left_padding + aside_right_padding = 200px + 10px + 10px */
padding: 1em; /* whatever */
}
#footer {
background: green;
color: white;
padding: 10px;
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
<div id="container">
<div id="header">
<h1>LAYOUT TEST #2</h1>
</div>
<div id="main">
<div id="primary">
<h2>THIS IS THE MAIN CONTENT ** THIS IS THE MAIN CONTENT ** THIS IS THE MAIN CONTENT</h2>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<h2>sub heading</h2>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<h2>sub heading</h2>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
</div>
<aside>
<h3>navigation (left)</h3>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
<p>lorem ipsum</p>
</aside>
</div>
<div id="footer">
<h1>LAYOUT TEST #2</h1>
</div>
</div>
Until we get flexbox, I believe the best way to do what you are looking for is to simply use the css
display: table;
. You will need to set the container todisplay: table;
, and then each of the columns, just set todisplay: table-cell;
. This will eliminate the need for using floats or any other JS magic. Also, this works back to IE8. I know it feels sketchy using anything with the word "table" for layout, but just give it a try.Check out this link for more info.
Here is an updated version of your code.
EDIT: example code
html: Assuming this markup
css:
I think the approach with all those
position: absolute
is not the best one.You want to have a container element with a
max-width
andmargin: 0 auto
. Not sure why you might want amin-width
as well; you can of course.Any block element that you put automatically takes all the
width
of the parent element. Hence, there's no problem with the header and footer, just position them in the right spot and they will render properly.As you correctly did, use a container element for your main section. Since the elements are rendered left to right, you might want to write the
aside
before the#primary
.Apply
float: left
to theaside
with your desired fixed-width.The main content
#primary
element will take the remaining space automatically (or just applywidth: auto
. Note: the remaining space is the remaining space of the parent element, so, if you set themin-width
on the parent element, don't expect your#primary
to be narrower!Now you will have a problem: the container element
#main
will not get the proper height. That's because of an issue withfloat
. To force a parent element to get to the height of its floated children, useoverflow: hidden
.You should be ready to go. Here is a slightly modified version of your code.
You can fix it with adding
margin-bottom: FOOTER_HEIGHT
to theaside
or use the following method instead:And the CSS:
This stops the sidebar misbehaving.
1 = With flexbox: http://jsfiddle.net/rudiedirkx/CjWbv/2/
2 = with
calc()
: http://jsfiddle.net/rudiedirkx/CjWbv/Both will require a fallback for older browsers (and vendor prefixing). Take your pick from the other answers.