7

I'm going crazy trying to get the following layout right:

  • left div with fixed width (possibly multiple divs one beside another)
  • center div with auto width (takes up remaining space)
  • right div with fixed width (possibly multiple divs one beside another)
  • a margin should exist between center div and first neighbor, be it left or right

HTML

<div class="container">
    <div class="all left">
        Left1
    </div>
    <div class="all left">
        Left2
    </div>
    <div class="all center">
        Center
    </div>
    <div class="all right">
        Right1
    </div>
    <div class="all right">
        Right2
    </div>
</div>

CSS

.container {
    display: table;
    position: relative;
    width: 100%;
    height: 100px;
    border-spacing: 5px;
}

.all {
    display: table-cell;
    border: 1px solid #333;
    margin: 5px;
}

.left {
    width: 45px;
}

.right {
    width: 45px;
}

.center {
    width: auto;
}

FIDDLE

http://jsfiddle.net/ozrentk/VdryG/3/

However, whatever I try (e.g. putting border-spacing: 0px in left or right div, margin: 0, border-collapsing) all of my margins end up the same.

To simplify it, I want this:

+--------------------------------------------------------------+
|+-----++-----+  +------------------------------++-----++-----+|
||     ||     |  |                              ||     ||     ||
||     ||     |  |                              ||     ||     ||
||     ||     |  |                              ||     ||     ||
||     ||     |  |                              ||     ||     ||
||     ||     |  |                              ||     ||     ||
||     ||     |  |                              ||     ||     ||
||     ||     |  |                              ||     ||     ||
||     ||     |  |                              ||     ||     ||
|+-----++-----+  +------------------------------++-----++-----+|
+--------------------------------------------------------------+

But currently I have this:

+--------------------------------------------------------------+
|                                                              |
| +----+  +----+  +--------------------------+  +----+  +----+ |
| |    |  |    |  |                          |  |    |  |    | |
| |    |  |    |  |                          |  |    |  |    | |
| |    |  |    |  |                          |  |    |  |    | |
| |    |  |    |  |                          |  |    |  |    | |
| |    |  |    |  |                          |  |    |  |    | |
| |    |  |    |  |                          |  |    |  |    | |
| +----+  +----+  +--------------------------+  +----+  +----+ |
|                                                              |
+--------------------------------------------------------------+

How can I control individual margins in this layout?

P.S.

  • I don't want the solution with mixing floats with non-floats, because it ends up with layout issues, see this
  • I don't want the solution with css calc because it is experimental
  • I don't want JS solution because I believe that CSS should be used for this kind of layout and can lead to flickers; also, user can have JS disabled
Community
  • 1
  • 1
OzrenTkalcecKrznaric
  • 5,535
  • 4
  • 34
  • 57

3 Answers3

2

As a quick solution that doesn't need to change the whole layout model, you can just add an invisible separator to your table structure, like in this edited fiddle:

hr {
    display: table-cell;
    width: 10px;
    visibility: hidden;
}
Ilya Streltsyn
  • 13,076
  • 2
  • 37
  • 57
  • Hm, ok, this is nice+simple. However, accepting this answer would be saying that solving this problem is not possible using simple css style modification without tempering into HTML. And that what I'm trying to avoid. However, +1 for a usable solution – OzrenTkalcecKrznaric Jul 26 '13 at 22:28
  • Another option that doesn't need markup changes is using the border of `.center` for spacing and something else (e.g. `box-shadow`) instead of border: http://jsfiddle.net/VdryG/5/. But `box-shadow` won't work in IE8 and below. – Ilya Streltsyn Jul 26 '13 at 22:46
1

A CSS only solution using the original mark-up

table-cell display types do not recognize margins, so that is why setting left and right margins are not getting you the desired result.

One work around is to specify display: block on the .center element:

.container {
    display: table;
    width: 100%;
    height: 100px;
    border-spacing: 5px;
}

.all {
    display: table-cell;
    border: 1px solid #333;
}

.left {
    width: 45px;
}

.right {
    width: 45px;
}

.center {
    width: auto;
    display: block;
    margin: 0 10px 0 10px;
    border: 1px solid red;
    height: inherit;
}

Fiddle: http://jsfiddle.net/audetwebdesign/GNVfG/

The one limitation is that the parent block .container needs an explicit height so that all the .container child elements can inherit or compute the same height.

Thanks to Ilya Streltsyn for suggesting display: block which solved the margin problem.

Community
  • 1
  • 1
Marc Audet
  • 46,011
  • 11
  • 63
  • 83
  • When I stretch the container, right border stretches too much for a public page layout. Can this be avoided? – OzrenTkalcecKrznaric Jul 27 '13 at 07:55
  • The problem with % values for the margins is that the margin widths will expand as you increase the screen size. To avoid this problem, you can set the margins to pixel widths, but this creates other problems with the width. If you could put an inner wrapper div in the `.center` container, you would have more control over the left/right spacing. – Marc Audet Jul 27 '13 at 10:42
  • 1
    I'd suggest to set to `.center` `display: block` instead of `table`, so there will be no need to set any explicit width to it: http://jsfiddle.net/GNVfG/5/ But both solutions will work only for fixed table height, because any `display` value other than `table-cell` for `.center` will create a separate box wrapped in [anonymous table cell box](http://www.w3.org/TR/CSS21/tables.html#anonymous-boxes). It will produce the same rendering as an extra `div` with the corresponding `display` nested in the `table-cell` object with default other styles. – Ilya Streltsyn Jul 27 '13 at 11:07
0

Is this what you mean?

.center{
       margin-left: 10px;
    }

By adding a left or right margin to center you will get the unique gap you want

rosscooper
  • 1,976
  • 3
  • 16
  • 29
  • This won't work since table-cell's do not recognize margin settings. See: http://www.w3.org/TR/CSS2/box.html#margin-properties – Marc Audet Jul 26 '13 at 23:13
  • Is there any reason the divs must be displayed as table-cells? Why not inline-block? – rosscooper Jul 26 '13 at 23:19
  • 2
    The OP wants the `.center` element to fill the remaining space given that the other elements have fixed widths. `inline-block`'s won't stretch to fill... – Marc Audet Jul 26 '13 at 23:22