127

I am learning how to use Bootstrap. Currently, I'm wading my way through layouts. While Bootstrap is pretty cool, everything I see seems dated. For the life of me, I have what I think is a basic layout that I can't figure out. My layout looks like the following:

---------------------------------------------------------------------------
|       |       |                                                         |
|       |       |                                                         |
| 240px | 160px | All Remaining Width of the Window                       |
|       |       |                                                         |
|       |       |                                                         |
--------------------------------------------------------------------------|

This grid needs to take up the full height of the window. From my understanding, I need to mix fixed and fluid widths. However, Bootstrap 3.0 doesn't seem to have the fluid class anymore. Even if it did, I can't seem to figure out how to mix fluid and fixed column sizes. Does anyone know how to do this in Bootstrap 3.0?

Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
Node Newbie
  • 1,951
  • 5
  • 17
  • 14

8 Answers8

153

edit: As lots of people seem to want to do this, I have written up a short guide with a more general use case here https://www.atlascode.com/bootstrap-fixed-width-sidebars/.

The bootstrap3 grid system supports row nesting which allows you to adjust the root row to allow fixed width side menus.

You need to put in a padding-left on the root row, then have a child row which contains your normal grid layout elements.

Here is how I usually do this http://jsfiddle.net/u9gjjebj/

html

<div class="container">
    <div class="row">
        <div class="col-fixed-240">Fixed 240px</div>
        <div class="col-fixed-160">Fixed 160px</div>
        <div class="col-md-12 col-offset-400">
            <div class="row">
            Standard grid system content here
            </div>
        </div>
    </div>
</div>

css

.col-fixed-240{
    width:240px;
    background:red;
    position:fixed;
    height:100%;
    z-index:1;
}

.col-fixed-160{
    margin-left:240px;
    width:160px;
    background:blue;
    position:fixed;
    height:100%;
    z-index:1;
}

.col-offset-400{
    padding-left:415px;
    z-index:0;
}
starball
  • 20,030
  • 7
  • 43
  • 238
Dean North
  • 3,741
  • 2
  • 29
  • 30
  • This one is nice but if you put inside the fixed column e.g this

    View details »

    or Bootstrap dropdown then these are not working in the fixed column. Is there any fix for this?
    – Vaclav Elias Jan 02 '15 at 14:30
  • @VaclavElias try putting a full-size diff in it with position:relative and then the dropdown? It helps if you make a jsfiddle to show the problem – w00t Mar 06 '15 at 08:59
  • I'm yet to see how this works in all browsers but otherwise, good job, well done. – Phil Cooper May 14 '15 at 16:32
  • Is there a way to do this with the fixed columns on the right hand side? – Sean May 20 '15 at 10:07
  • I had buttons in the fixed-width area and this code generated the correct visual layout, but those buttons were not clickable. If I add `z-order:-1` to the non-fixed part, then the buttons are clickable but the items on the non-fixed part are not clickable. (Have not resolved this yet) – M.M Jun 12 '15 at 06:51
  • 5
    `position: fixed` means that when scrolling the content of that column floats above the rest of the page. In my case I fixed it using `position: absolute`. – laurent Sep 07 '16 at 15:12
  • This solution seems to have a critical flaw where by the two divs (Fixed 240px and Fixed 160px) can not be clicked: http://jsfiddle.net/wybo1e8e/ – Bwyss Feb 01 '17 at 21:56
  • @Bwyss read the 4 comments above this one. They contain a fix for the issue you are having. I will update the answer to include this fix too. – Dean North Feb 02 '17 at 09:12
  • Sorry, I missed that, thx. I ended up going with a slightly different solution: http://www.bootply.com/97972 – Bwyss Feb 03 '17 at 17:26
  • Is there a variant of this for one fixed div on the left and one on the right and the middle column is 100%? – Vishal May 11 '18 at 10:09
31

There's really no easy way to mix fluid and fixed widths with Bootstrap 3. It's meant to be like this, as the grid system is designed to be a fluid, responsive thing. You could try hacking something up, but it would go against what the Responsive Grid system is trying to do, the intent of which is to make that layout flow across different device types.

If you need to stick with this layout, I'd consider laying out your page with custom CSS and not using the grid.

Steve K.
  • 725
  • 1
  • 6
  • 8
  • 5
    I guess this kind of thing will have to wait for Flexbox to have full support, but it's still really lame. Bootstrap's model is great when the number of columns are static, but, e.g., if you can dynamically hide and show columns, having support for at least one column to be fluid starts to make a lot more sense. – Nate Bundy Nov 19 '13 at 22:41
  • 1
    Please, edit your answer to include a reference to this link with the solution. Regards: http://stackoverflow.com/questions/8740779/how-to-build-a-2-column-fixed-fluid-layout-with-twitter-bootstrap – Rick May 29 '14 at 20:07
26

or use display property with table-cell;

css

.table-layout {
    display:table;
    width:100%;
}
.table-layout .table-cell {
    display:table-cell;
    border:solid 1px #ccc;
}

.fixed-width-200 {
    width:200px;
}

html

<div class="table-layout">
    <div class="table-cell fixed-width-200">
        <p>fixed width div</p>
    </div>
    <div class="table-cell">
        <p>fluid width div</p>    
    </div>
</div>

http://jsfiddle.net/DnGDz/

Frankey
  • 3,679
  • 28
  • 25
22

I had a slightly different problem:

  • I needed to combine fixed and fluid columns as part of a table rather than as part of a full-window layout
  • I needed to have columns fixed to both the left and right
  • I was not worried about the column backgrounds using the full-height of the containing row

As a result, I resorted to float to for the left and right columns, and could then use Bootstrap's row to do the fluid columns in between.

<div>
    <div class="pull-left" style="width:240px">Fixed 240px</div>
    <div class="pull-right" style="width:120px">Fixed 120px</div>
    <div style="margin-left:240px;margin-right:120px">
        <div class="row" style="margin:0px">
            Standard grid system content here
        </div>
    </div>
</div>
Paddy Mann
  • 1,169
  • 12
  • 18
  • 4
    @Schemetrical I didn't have a question. I explained that I had a slightly different problem, and added the solution that I came to to help other people that arrive here from Google. – Paddy Mann May 28 '15 at 09:31
  • 1
    your answer is invaluable. Quite simple yet solving my problem. Thanks a lot. – Charles Oct 28 '15 at 16:57
  • Why can't you give the row div the margins that the containing div has in your answer? – GreenAsJade Mar 19 '16 at 07:43
  • This answer is seriously legit. If you need to utilize bootstrap columns but don't want them to collapse at certain screen widths, this is the what you need (use pull-left / pull-right instead of col-md-3, for example). – Sam Nov 03 '16 at 06:42
  • This seems like a great answer. I'm having some trouble with my `margin` and `padding` in my row in the middle but that should be a solveable problem. What are the unintended consequences of taking this approach? – Vishal May 12 '18 at 05:16
15

Updated 2018

IMO, the best way to approach this in Bootstrap 3 would be using media queries that align with Bootstrap's breakpoints so that you only use the fixed width columns are larger screens and then let the layout stack responsively on smaller screens. This way you keep the responsiveness...

@media (min-width:768px) {
  #sidebar {
      width: inherit;
      min-width: 240px;
      max-width: 240px;
      min-height: 100%;
      position:relative;
  }
  #sidebar2 {
      min-width: 160px;
      max-width: 160px;
      min-height: 100%;
      position:relative;
  }
  #main {
      width:calc(100% - 400px);
  }
}

Working Bootstrap Fixed-Fluid Demo

Bootstrap 4 will has flexbox so layouts like this will be much easier: http://www.codeply.com/go/eAYKvDkiGw

Carol Skelly
  • 351,302
  • 90
  • 710
  • 624
3

OK, my answer is super nice:

<style>
    #wrapper {
        display:flex;    
        width:100%;
        align-content: streach;
        justify-content: space-between;
    }    

    #wrapper div {
        height:100px;
    }

    .static240 {
        flex: 0 0 240px;
    }
    .static160 {
        flex: 0 0 160px;
    }

    .growMax {
        flex-grow: 1;
    }

</style>

<div id="wrapper">
  <div class="static240" style="background:red;" > </div>
  <div class="static160"  style="background: green;" > </div> 
  <div class="growMax"  style="background:yellow;"  ></div>
</div>

jsfiddle playground

if you wanna support for all browser, use https://github.com/10up/flexibility

Dariusz Filipiak
  • 2,858
  • 5
  • 28
  • 39
1

UPDATE 2014-11-14: The solution below is too old, I recommend using flex box layout method. Here is a overview: http://learnlayout.com/flexbox.html


My solution

html

<li class="grid-list-header row-cw row-cw-msg-list ...">
  <div class="col-md-1 col-cw col-cw-name">
  <div class="col-md-1 col-cw col-cw-keyword">
  <div class="col-md-1 col-cw col-cw-reply">
  <div class="col-md-1 col-cw col-cw-action">
</li>

<li class="grid-list-item row-cw row-cw-msg-list ...">
  <div class="col-md-1 col-cw col-cw-name">
  <div class="col-md-1 col-cw col-cw-keyword">
  <div class="col-md-1 col-cw col-cw-reply">
  <div class="col-md-1 col-cw col-cw-action">
</li>

scss

.row-cw {
  position: relative;
}

.col-cw {
  position: absolute;
  top: 0;
}


.ir-msg-list {

  $col-reply-width: 140px;
  $col-action-width: 130px;

  .row-cw-msg-list {
    padding-right: $col-reply-width + $col-action-width;
  }

  .col-cw-name {
    width: 50%;
  }

  .col-cw-keyword {
    width: 50%;
  }

  .col-cw-reply {
    width: $col-reply-width;
    right: $col-action-width;
  }

  .col-cw-action {
    width: $col-action-width;
    right: 0;
  }
}

Without modify too much bootstrap layout code.


Update (not from OP): adding code snippet below to facilitate understanding of this answer. But it doesn't seem to work as expected.

ul {
  list-style: none;
}
.row-cw {
  position: relative;
  height: 20px;
}
.col-cw {
  position: absolute;
  top: 0;
  background-color: rgba(150, 150, 150, .5);
}
.row-cw-msg-list {
  padding-right: 270px;
}
.col-cw-name {
  width: 50%;
  background-color: rgba(150, 0, 0, .5);
}
.col-cw-keyword {
  width: 50%;
  background-color: rgba(0, 150, 0, .5);
}
.col-cw-reply {
  width: 140px;
  right: 130px;
  background-color: rgba(0, 0, 150, .5);
}
.col-cw-action {
  width: 130px;
  right: 0;
  background-color: rgba(150, 150, 0, .5);
}
<ul class="ir-msg-list">
  <li class="grid-list-header row-cw row-cw-msg-list">
    <div class="col-md-1 col-cw col-cw-name">name</div>
    <div class="col-md-1 col-cw col-cw-keyword">keyword</div>
    <div class="col-md-1 col-cw col-cw-reply">reply</div>
    <div class="col-md-1 col-cw col-cw-action">action</div>
  </li>

  <li class="grid-list-item row-cw row-cw-msg-list">
    <div class="col-md-1 col-cw col-cw-name">name</div>
    <div class="col-md-1 col-cw col-cw-keyword">keyword</div>
    <div class="col-md-1 col-cw col-cw-reply">reply</div>
    <div class="col-md-1 col-cw col-cw-action">action</div>
  </li>
</ul>
John Xiao
  • 1,680
  • 2
  • 18
  • 24
  • -1 This answer doesn't make any sense to me. Columns doesn't sum up to 12. Name and keyboard columns overlap. I don't understand how it has +2 votes. – Mariano Desanze Nov 13 '14 at 21:58
-3

Why not just set the left two columns to a fixed with in your own css and then make a new grid layout of the full 12 columns for the rest of the content?

<div class="row">
    <div class="fixed-1">Left 1</div>
    <div class="fixed-2">Left 2</div>
    <div class="row">
        <div class="col-md-1"></div>
        <div class="col-md-11"></div>
    </div>
</div>
mikeschuld
  • 943
  • 1
  • 11
  • 25