Responsive 2-column CSS layout including sidebar with fixed width?
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.
Two column layout, fixed right column
Not a very elegant solution, but its working. They key is to wrap the contents of the left column and add a margin-right equal to the width of the right column / sidebar. On the right column, set the width and a negative margin-left equal to its width.
.left {
float:left;
width:100%;
background-color: green;
}
.left-content {
margin-right:120px;
}
.right {
float:right;
width: 120px;
margin-left: -120px;
background-color: red;
}
Here's a working fiddle
http://jsfiddle.net/heyapo/9Z363/
2 column div layout: right column with fixed width, left fluid
Remove the float on the left column.
At the HTML code, the right column needs to come before the left one.
If the right has a float (and a width), and if the left column doesn't have a width and no float, it will be flexible :)
Also apply an overflow: hidden
and some height (can be auto) to the outer div, so that it surrounds both inner divs.
Finally, at the left column, add a width: auto
and overflow: hidden
, this makes the left column independent from the right one (for example, if you resized the browser window, and the right column touched the left one, without these properties, the left column would run arround the right one, with this properties it remains in its space).
Example HTML:
<div class="container">
<div class="right">
right content fixed width
</div>
<div class="left">
left content flexible width
</div>
</div>
CSS:
.container {
height: auto;
overflow: hidden;
}
.right {
width: 180px;
float: right;
background: #aafed6;
}
.left {
float: none; /* not needed, just for clarification */
background: #e8f6fe;
/* the next props are meant to keep this block independent from the other floated one */
width: auto;
overflow: hidden;
}
Example here: http://jsfiddle.net/jackJoe/fxWg7/
Responsive 2-column layout trouble
The simple answer to your question is no. You can't make your sidebar move beneath the content in your breakpoint if the sidebar falls before the content area in your HTML. At least... Not without javascript and a bunch of craziness.
That said... Just move your sidebar below your main-content div. Semantically there is no reason for you not to.
<section class="container">
<div class="main-area">main content</div>
<div class="sidebar">sidebar</div>
</section>
Some CSS changes are required to achieve this however. It's not quite as simply done as you had it previously, but not especially difficult either.
.container {
position: relative;
}
.sidebar {
position: absolute;
top: 0;
right: 0;
width: 250px;
}
.main-area {
background: red;
margin-right: 250px;
}
Here is a JSFiddle demonstrating it working.
Feel free to add varying amounts of content to either the main-content area or the sidebar and you'll see that both still have varying heights that don't interfere with each other.
2 column layout (Left column fixed width, right fluid + clear:both)
Here's your altered CSS:
html, body {
background: #ccc;
}
.wrap {
margin: 20px;
padding: 20px;
padding-right:240px;
background: #fff;
overflow:hidden;
}
.main {
margin: 0 -220px 0 auto;
width: 100%;
float:right;
}
.sidebar {
width: 200px;
float: left;
height: 200px;
}
.main, .sidebar {
background: #eee; min-height: 100px;
}
.clear { clear:both; }
span { background: yellow }
Basically what I've done is change the way your layout is done, so that .main
div is floated on the right. To do this, we had to add 2 things:
- A padding of 240px on the
.wrap
div, and - A right margin on the
.main
div of -220px to properly align the fluid part of the page.
Because we've floated the .main
div on the right, the clear: both;
now only affects content inside the .main
div, as you want.
You can see a demonstration here: http://jsfiddle.net/6d2qF/1/
Creating a fixed width sidebar with a responsive container for content next to it in CSS
You can accomplish this using the CSS calc
function. For example:
.parent {
width: -webkit-calc(100% - 200px);
width: calc(100% - 200px);
}
See updated fiddle.
calc support.
If you don't want to use calc
it can be accomplished with padding, although there are some considerations if you want to use this method. See fiddle.
Twitter Bootstrap Two Column Responsive Layout - Sidebar 100% height with fixed width
Check this out.
<div class="row">
<div class="span3" style="position:fixed;background-color:#46a546;height:100%;top:0px;" id="leftmargin">
position fixed navbar (out of .container)
</div>
</div>
<div class="container">
<div class="row">
<div class="span9 offset3" style="background-color:#049cdb;">
bla bla bla<br>bla bla bla<br>bla bla bla<br>bla bla bla<br>bla bla bla<br>
bla bla bla<br>bla bla bla<br>bla bla bla<br>bla bla bla<br>bla bla bla<br>
bla bla bla<br>bla bla bla<br>bla bla bla<br>bla bla bla<br>bla bla bla<br>
bla bla bla<br>bla bla bla<br>bla bla bla<br>bla bla bla<br>bla bla bla<br>
bla bla bla<br>bla bla bla<br>bla bla bla<br>bla bla bla<br>bla bla bla<br>
bla bla bla<br>bla bla bla<br>bla bla bla<br>bla bla bla<br>bla bla bla<br>
</div>
</div>
</div>
And a bit of jQuery
function sizing() {
var windowwidth=$(window).width();
var containerwidth=$('.container').width();
if(windowwidth<1200) {
var diff=windowwidth-containerwidth+40;
}
else {
var diff=windowwidth-containerwidth+60;
}
$('#leftmargin').text("window="+ windowwidth+",container="+containerwidth);
if(windowwidth<=767) {
$('#leftmargin').css('margin-left', '0px');
$('#leftmargin').css('position', 'relative');
}
else {
$('#leftmargin').css('position', 'fixed');
if(diff>0) {
$('#leftmargin').css('margin-left', (diff/2) +'px');
} else {
$('#leftmargin').css('margin-left', '20px');
}
}
}
$(document).ready(sizing);
$(window).resize(sizing);
http://jsfiddle.net/NzqfL/3/
inspired by my previous post https://stackoverflow.com/a/10972425/1416911
How to build a 2 Column (Fixed - Fluid) Layout with Twitter Bootstrap?
- Another Update -
Since Twitter Bootstrap version 2.0 - which saw the removal of the .container-fluid
class - it has not been possible to implement a two column fixed-fluid layout using just the bootstrap classes - however I have updated my answer to include some small CSS changes that can be made in your own CSS code that will make this possible
It is possible to implement a fixed-fluid structure using the CSS found below and slightly modified HTML code taken from the Twitter Bootstrap Scaffolding : layouts documentation page:
HTML
<div class="container-fluid fill">
<div class="row-fluid">
<div class="fixed"> <!-- we want this div to be fixed width -->
...
</div>
<div class="hero-unit filler"> <!-- we have removed spanX class -->
...
</div>
</div>
</div>
CSS
/* CSS for fixed-fluid layout */
.fixed {
width: 150px; /* the fixed width required */
float: left;
}
.fixed + div {
margin-left: 150px; /* must match the fixed width in the .fixed class */
overflow: hidden;
}
/* CSS to ensure sidebar and content are same height (optional) */
html, body {
height: 100%;
}
.fill {
min-height: 100%;
position: relative;
}
.filler:after{
background-color:inherit;
bottom: 0;
content: "";
height: auto;
min-height: 100%;
left: 0;
margin:inherit;
right: 0;
position: absolute;
top: 0;
width: inherit;
z-index: -1;
}
I have kept the answer below - even though the edit to support 2.0 made it a fluid-fluid solution - as it explains the concepts behind making the sidebar and content the same height (a significant part of the askers question as identified in the comments)
Important
Answer below is fluid-fluid
Update
As pointed out by @JasonCapriotti in the comments, the original answer to this question (created for v1.0) did not work in Bootstrap 2.0. For this reason, I have updated the answer to support Bootstrap 2.0
To ensure that the main content fills at least 100% of the screen height, we need to set the height of the html
and body
to 100% and create a new css class called .fill
which has a minimum-height of 100%:
html, body {
height: 100%;
}
.fill {
min-height: 100%;
}
We can then add the .fill
class to any element that we need to take up 100% of the sceen height. In this case we add it to the first div:
<div class="container-fluid fill">
...
</div>
To ensure that the Sidebar and the Content columns have the same height is very difficult and unnecessary. Instead we can use the ::after
pseudo selector to add a filler
element that will give the illusion that the two columns have the same height:
.filler::after {
background-color: inherit;
bottom: 0;
content: "";
right: 0;
position: absolute;
top: 0;
width: inherit;
z-index: -1;
}
To make sure that the .filler
element is positioned relatively to the .fill
element we need to add position: relative
to .fill
:
.fill {
min-height: 100%;
position: relative;
}
And finally add the .filler
style to the HTML:
HTML
<div class="container-fluid fill">
<div class="row-fluid">
<div class="span3">
...
</div>
<div class="span9 hero-unit filler">
...
</div>
</div>
</div>
Notes
- If you need the element on the left of the page to be the filler then you need to change
right: 0
toleft: 0
.
Related Topics
Generate Scroll Bar for Overflow to the Left
How to Add a Background Image on Top of a Previous Background Image
When Does Whitespace Matter in HTML
How to Add Border to a Container with Transparent Gaps in Between
Responsive Image Align Center Bootstrap 3
How to Tidy Up an HTML File's Indentation in Vi
Add Outward Curving Border to Elements Like This: ◝◟_◞◜
How to Change the Inner White Color of Font Awesome's Exclamation Triangle Icon
Adding Http Request Header to a a Href Link
Remove Host Component Tag from HTML in Angular 4
Open a Direct File on the Hard Drive from Firefox (File:///)
When I Try to Shift the Image Upwards Using Negative Margin the Whole Container Is Moved Upwards
Display:Inline with Margin, Padding, Width, Height
How Remove Border Around Image in CSS