Responsive two-line CSS layout, including fixed-width sidebar?

It is impossible to find a solution for this (what I suppose should be a fairly common problem) anywhere.

I am creating a responsive design with a sidebar where the sidebar should have a fixed width of 200 pixels and have an unknown height. How can I make the main content area occupy the entire remaining width without any errors.

The closest I came to is the following, but the problem is that the sidebar may overlap the footer. Can someone suggest a fix for my code or share code with me 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> 
+4
source share
5 answers

I think the approach with all these position: absolute not the best.

  • You want to have a container element with max-width and margin: 0 auto . Not sure why you might need min-width ; you can of course.

  • Any element of the block that you put automatically takes all the width parent element. Therefore, there is no problem with the header and footer , just place them in the right place and they will display correctly.

  • How you did it right, use the container element for your main section. Since the elements are displayed from left to right, you can write aside to #primary .

  • Apply float: left to aside with the desired fixed width.

  • The #primary main content #primary will automatically accept the remaining space (or just apply width: auto . Note: the remaining space is the remaining space of the parent element, if you set min-width in the parent element, do not expect your #primary be already!

  • Now you have a problem: the #main container element #main not get the correct height. This is due to a problem with float . To force the parent to get the height of its floating children, use overflow: hidden .

You must be ready to go. Here is a slightly modified version of your code .

+4
source

1 = With flexbox: http://jsfiddle.net/rudiedirkx/CjWbv/2/

 #main { display: flex; } #primary { background: #bbb; flex: 1; } aside { background: #ddd; flex: 0 0 200px; } 

2 = with calc() : http://jsfiddle.net/rudiedirkx/CjWbv/

 #main:after { clearfix here } #primary { float: left; background: #bbb; width: calc(100% - 200px); } aside { background: #ddd; float: right; width: 200px; } 

Both will require delay for older browsers (and vendor prefixes). Choose from other answers.

+8
source

Until we get flexbox, I believe that the best way to do what you are looking for is to simply use css display: table; . You will need to install the container display: table; and then each of the columns, just set to display: table-cell; . This eliminates the need to use floats or any other JS magic. It also works in IE8. I know this seems sketchy using anything with the word β€œtable” for the layout, but just give it a try.

See this link for more information.

Below is an updated version of your code.

EDIT: Code Example

html: Assuming this markup

 <div id="main"> <div id="sidebar"></div> <div id="content"></div> </div> 

CSS

 #main { display: table; width: 100%; } #sidebar { display: table-cell; width: 200px; } #content { display: table-cell; /* no need to specify width. * width will auto fill remaining width of parent `table` #main. * so 100% - 200px */ } 
+4
source
 #main { position: relative; overflow:hidden;} 

This stops the sidebar from working properly.

0
source

You can fix this by adding margin-bottom: FOOTER_HEIGHT to aside or use the following method instead:

 <div id="container"> <div id="header"> YOUR_HEADER </div> <div id="body> <div id="sidebar"> YOUR_SIDE_BAR_CONTENT </div> <div id="main"> YOUR_CONTENT </div> <br /> </div> <div id="footer"> YOUR_FOOTER </div> </div> 

And CSS:

 #sidebar { width: ...; height: ...; float: right; } #main { margin-right: WIDTH_OF_SIDE_BAR; } #body > br { clear: both; } 
0
source

All Articles