W3C home > Mailing lists > Public > www-style@w3.org > April 2013

Re: [css-flexbox] Width computation for flex items with margin

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Thu, 4 Apr 2013 08:56:14 -0700
Message-ID: <CAAWBYDBDWR7EB9qHD9LgRM+_+OW6XKSucKmhbpX9wk7GK6_TnQ@mail.gmail.com>
To: soenke.sothmann@oio.de
Cc: www-style list <www-style@w3.org>
On Fri, Mar 15, 2013 at 7:10 AM, Sönke Sothmann <soenke.sothmann@oio.de> wrote:
> Hello everyone,
>
> I have a question concerning the width computation of flex items with margin.
>
> What I am trying to do is a grid using flexbox.
> I want to put (e.g.) 4 divs inside a flex container, where each flex item consumes equal space and have a margin in between.
> I want to be able to span elements over two "cells".
> The grid and the grid items should grow/shrink with the size of the container element.
>
> It looks like this could be easily done with flexbox.
>
> Unfortunately, I can't get it to work when I use margins.
>
> I created a JSFiddle to illustrate the problem:
> http://jsfiddle.net/MWygB/
> The first row is a "reference" row build without flexbox using floats...
> The second row is using flexbox with 4 items, each flex:1.
> The third row is using flexbox with 3 items, where the first item is flex:2.
> The problem is in the third row - I was expecting the first item to have the same width as the first two items in the second row.
>
> Is this a browser bug, a gap in the specification, is this not possible with flexbox or am I simply doing something wrong?

This is possible, but with hacks.  This situation is better suited for
Grid, which I'll explain below.

Those margins are subtracted from the total amount of free space that
is to be distributed to the flexible items.  In the first two
examples, you've got 30px of margins, which when subtracted from the
630px of the container, leaves you 600px leftover for the items.  In
the 4-cell flexbox where everything's flex:1, that means they split
that equally, and all get 150px wide.

In the third example, though, you've only got two margins, for 20px
total, so the free space is 610px.  Split between the cells, that
means the big cell gets half of it, or 305px, while the smaller cells
get a quarter each, or 152.5px.

To fix this, you need to make the big item count that missing 10px.
This is pretty easy - just change its "flex: 2;" to "flex: 2 10px;".
This makes the big item "start at" 10px wide before free-space
distribution happens, which means that 10px gets subtracted from the
container width just like the margins.  Now you've got 600px of free
space, split 300px, 150px, 150px, and the wide item is 310px wide,
exactly what you wanted.

In general, if you want a flexible grid in flexbox with gutters,
you'll need to use this technique to include the "missing" gutters in
cell-spanning items.

With Grid, once we add the gutter properties that we plan on, this'll
be no effort at all - you'll just tell the big item to span 2 columns,
and the gutter size will automatically be taken into account.

~TJ
Received on Thursday, 4 April 2013 15:57:08 UTC

This archive was generated by hypermail 2.3.1 : Monday, 2 May 2016 14:39:10 UTC