How can I have two fixed width columns with one flexible column in the center?
Asked Answered
H

4

370

I'm trying to set up a flexbox layout with three columns where the left and right columns have a fixed width, and the center column flexes to fill the available space.

Despite setting up dimensions for the columns, they still seem to shrink as the window shrinks.

Anyone know how to accomplish this?

An additional thing I will need to do is hide the right column based on user interaction, in which case the left column would still keep its fixed width, but the center column would fill the rest of the space.

#container {
    display: flex;
    justify-content: space-around;
    align-items: stretch;
    max-width: 1200px;
}

.column.left {
    width: 230px;
}

.column.right {
    width: 230px;
    border-left: 1px solid #eee;
}

.column.center {
    border-left: 1px solid #eee;
}
<div id="container">
    <div class="column left">
        <p>Anxiety was a blog series that ran in the New York Times Opinion section from January 2012 to July 2013. It featured essays, fiction, and art by a wide range of contributors that explored anxiety from scientific, literary, and artistic perspectives.</p>
    </div>
    <div class="column center">
        <img src="http://i.imgur.com/60PVLis.png" width="100" height="100" alt="">
    </div>
    <div class="column right">
        Balint Zsako
        <br/> Someone’s Knocking at My Door
        <br/> 01.12.13
    </div>
</div>

Here's a JSFiddle: http://jsfiddle.net/zDd2g/185/

Hebdomadary answered 21/5, 2014 at 22:10 Comment(1)
jsfiddle.net/5aor2b0x/11Orosco
A
724

Instead of using width (which is a suggestion when using flexbox), you could use flex: 0 0 230px; which means:

  • 0 = don't grow (shorthand for flex-grow)
  • 0 = don't shrink (shorthand for flex-shrink)
  • 230px = start at 230px (shorthand for flex-basis)

which means: always be 230px.

See fiddle, thanks @TylerH

Oh, and you don't need the justify-content and align-items here.

img {
    max-width: 100%;
}
#container {
    display: flex;
    x-justify-content: space-around;
    x-align-items: stretch;
    max-width: 1200px;
}
.column.left {
    width: 230px;
    flex: 0 0 230px;
}
.column.right {
    width: 230px;
    flex: 0 0 230px;
    border-left: 1px solid #eee;
}
.column.center {
    border-left: 1px solid #eee;
}
Andraandrade answered 21/5, 2014 at 22:17 Comment(11)
Thanks - what does the 0 0 230px represent? And how would I adjust this if the right column gets hidden (so that the center column fills the width - 230px?Hebdomadary
Hiding the right column shouldn't be a problem. I explained in the answer what the 0 0 230px means.Andraandrade
In the current implementation (at least in Chrome), you also need to ensure that the middle column has flex-grow defined (as say 1). Updated fiddle.Talbott
@Talbott Not necessary in my Chrome 45 stable or Chrome 47 Canary on Windows. Why do you think it's necessary? Doesn't work for you? Spec change? Engine change?Andraandrade
@Andraandrade I also needed the flex-grow defined on the middle column for ti to work - not sure why though (Chrome 46) :/Insubstantial
why just width doesn't work? and I do need the flex: 0 0 230px;?Linea
flex-grow: 1 is still needed for fluid column in Chrome 53. Otherwise, it wouldn't take the rest of width. I suppose the answer should consider this fact.Sandhog
For anyone still confused, flex: 0 0 200px acts the same as width: 200px; flex-shrink: 0.Honduras
supplying a width: 200px and flex: 0 0 200px was enough for meStoddard
I have copied the Fiddle here in case Rudie lost it: jsfiddle.net/133rr51uQuirites
You have to use width: 230px because if the content contains non-breakable items it will still grow.Permutation
N
64

Despite setting up dimensions for the columns, they still seem to shrink as the window shrinks.

An initial setting of a flex container is flex-shrink: 1. That's why your columns are shrinking.

It doesn't matter what width you specify (it could be width: 10000px), with flex-shrink the specified width can be ignored and flex items are prevented from overflowing the container.

I'm trying to set up a flexbox with 3 columns where the left and right columns have a fixed width...

You will need to disable shrinking. Here are some options:

.left, .right {
     width: 230px;
     flex-shrink: 0;
 }  

OR

.left, .right {
     flex-basis: 230px;
     flex-shrink: 0;
}

OR, as recommended by the spec:

.left, .right {
    flex: 0 0 230px;    /* don't grow, don't shrink, stay fixed at 230px */
}

7.2. Components of Flexibility

Authors are encouraged to control flexibility using the flex shorthand rather than with its longhand properties directly, as the shorthand correctly resets any unspecified components to accommodate common uses.

More details here: What are the differences between flex-basis and width?

An additional thing I need to do is hide the right column based on user interaction, in which case the left column would still keep its fixed width, but the center column would fill the rest of the space.

Try this:

.center { flex: 1; }

This will allow the center column to consume available space, including the space of its siblings when they are removed.

Revised Fiddle

Newsman answered 25/6, 2016 at 13:20 Comment(1)
Adding flex: 1; to the center div was enough, thanks.Dehydrogenase
P
9

Compatibility with older browsers can be a drag, so be adviced.

If that is not a problem then go ahead. Run the snippet. Go to full page view and resize. Center will resize itself with no changes to the left or right divs.

Change left and right values to meet your requirement.

Thank you.

Hope this helps.

#container {
  display: flex;
}

.column.left {
  width: 100px;
  flex: 0 0 100px;
}

.column.right {
  width: 100px;
  flex: 0 0 100px;
}

.column.center {
  flex: 1;
  text-align: center;
}

.column.left,
.column.right {
  background: orange;
  text-align: center;
}
<div id="container">
  <div class="column left">this is left</div>
  <div class="column center">this is center</div>
  <div class="column right">this is right</div>
</div>
Paintbrush answered 31/7, 2018 at 7:54 Comment(0)
P
0
.column.left {
    width: 230px;
    flex: 0 0 230px;
}

.column.right {
    width: 230px;
    flex: 0 0 230px;
    border-left: 1px solid #eee;
}

.column.center {
    border-left: 1px solid #eee;
}
Pansypant answered 13/5, 2022 at 2:24 Comment(1)
Please don't post code-only answers but actually describe how this fixes the issue.Odontology

© 2022 - 2024 — McMap. All rights reserved.