6

I have some very simple sub-navigation that I'm trying to build across the top of the content area within my web site, but CSS doesn't seem to have any simple solutions for such a common problem: I want either 3 or 4 equally spaced DIVs across the top of the page.

1) e.g. 3 Variable-Width, Equally-Spaced DIVs

[[LEFT]                [CENTER]               [RIGHT]]

2) e.g. 4 Variable-Width, Equally-Spaced DIVs

[[LEFT]    [LEFT CENTER]    [RIGHT CENTER]    [RIGHT]]

My solution for the first problem with only 3 DIVs was to float the left and right DIVs, and then assign an arbitrary size to the middle DIV and give it "margin: 0 auto". That's not really a solution, but assuming there are no changes to the navigation, it gives a rough approximation of what I want the results to be.

The solution I have for the second problem with 4 DIVs is to simply center a DIV in the same way as before, but then float two DIVs within that, e.g.

[[LEFT]    [[LEFT CENTER]    [RIGHT CENTER]]    [RIGHT]]

But again, this requires applying an arbitrary size to the middle DIV for alignment, and if any language or image changes are made to the site, alignment values will have to be recalculated. As well, it's simply an over-complicated solution that requires merging structure with presentation.

Any help is greatly appreciated.

EDIT 07/20/2012 5:00PM

Alright, I put the "table-cell" solution into place using percents, but I encountered another issue within my slightly more complex implementation: the issue at hand is that each DIV I was referring to is actually a container for two more DIVs which are icon-label pairs, inlined either by float or by display:inline-block.

e.g. http://jsfiddle.net/c3yrm/1/

As you can see, the final element in the list is displayed improperly.

Any help is again greatly appreciated!

EDIT 07/20/2012 7:16PM

Final solution with arttronics' help: http://jsfiddle.net/CuQ7r/4/

M. Herold
  • 684
  • 1
  • 7
  • 18
  • 1
    Something like this: http://jsfiddle.net/j08691/c3yrm/ ? – j08691 Jul 20 '12 at 20:59
  • possible duplicate of [For a fluid Navigation Menu, how to adjust padding dynamically for each Breadcrumb?](http://stackoverflow.com/questions/11514125/for-a-fluid-navigation-menu-how-to-adjust-padding-dynamically-for-each-breadcru) – arttronics Jul 20 '12 at 21:56
  • That is exactly what I want; does "table-cell" have any browser compatibility issues I should be aware of? As well, I'm encountering an issue with nested divs within the table-cell div, which I'll edit about above. – M. Herold Jul 20 '12 at 21:59
  • Also, I'd prefer to avoid using anything other than CSS if possible. – M. Herold Jul 20 '12 at 22:14
  • Shouldn't the width of .x be 25% not 33%? And the width of .y should be 33% not 50%? – Dom Jul 20 '12 at 22:19
  • I'd agree, but sticking those numbers in breaks the output. I'm not certain what those widths are, exactly. – M. Herold Jul 20 '12 at 22:55
  • That appears to work! I'm still having an issue with shrink-wrapping an anchor tag around the NavButton DIV, but as a quick-fix, replacing the DIV with an anchor seems to work alright. Here's my final, completed solution based on your help: http://jsfiddle.net/CuQ7r/4/ – M. Herold Jul 21 '12 at 00:15
  • 1
    I've posted an Answer with new jsFiddle that includes anchor tags for the breadcrumbs (nav buttons). The method you used incorrectly places block elements (div) inside of inline elements (anchor). – arttronics Jul 21 '12 at 02:03
  • I do think you should give @arttronics an upvote and accept his answer considering he basically solved your whole problem...? – Dom Jul 21 '12 at 17:48

4 Answers4

3

Reference: jsFiddle Pure CSS Demo

The solution was to float the individual breadcrumbs while using a simple formula to determine the percentage of breadcrumb width based on the number total breadcrumbs.

arttronics
  • 9,957
  • 2
  • 26
  • 62
1

You could use percentages, then it just comes down to simple math:

[[LEFT=22%]2% margin><2% margin[LEFT CENTER=22%]2% margin><2% margin[RIGHT CENTER=22%]2% margin><2% marginRIGHT=22%]]=100%/??px

You could then specify a width for its container and use

display:inline;

to keep them inline.

Note: If you use borders to see what the divs are doing that will add space unnaccounted for so you would need to reduce your elements width by 1% or so OR just change their background colors.

Dom
  • 2,275
  • 3
  • 24
  • 34
0
ol {
    width: 400px;
    /*width: 800px;*/

    display: table;
    table-layout: fixed; /* the magic dust that ensure equal width */
    background: #ccc
}
ol > li {
    display: table-cell;
    border: 1px dashed red;
    text-align: center
}

like here: http://jsfiddle.net/QzYAr/

Robert Niestroj
  • 15,299
  • 14
  • 76
  • 119
  • 1
    Hey, [I recognize](http://stackoverflow.com/questions/6310632/html-list-element-sharing-the-parent-width-into-equal-parts/6311029#6311029) that clumsily worded comment! – thirtydot Jul 20 '12 at 21:10
0

One way I've found to do it is using flex boxes (or inline-flex).

Here is a great explanation and example of how it can be done.

I think in the future, flex boxes will be the superior way of handling this sort of thing, but until other browsers catch up with Mozilla's way of thinking for how to use the flex-basis attribute (with min-content, max-content, fit-content, etc. as values), these flex boxes will continue to be problematic for responsive designs. For example, occasionally the inner content (a_really_really_long_word) can't fit in the allotted space when the window is squished down, and so sometimes some things might not be visible off to the right of the screen if you're not careful.

I think perhaps if you make use of the flex-wrap property, you might be able to ensure everything fits. Here is another example of how this might be done (in Mozilla browsers anyway).

I tend to use flex boxes for letterheads or tables where the width is fairly fixed (not too small) because they usually space themselves nicely; I tend to use nested float and inline-block objects for websites where the content must squish down very small (as suggested in some of the other answers here).

Damian Green
  • 633
  • 2
  • 8
  • 13