Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS Reverse inline flow

Tags:

html

css

So, I have a line of inline elements that adjusts based on the width of the window, like so for example:

[a][b][c][d][e] -- 1000px

[a][b][c]
[d][e]          -- 600px

This makes sense, and is what is expected of inline elements. However, I want to know if it's possible to make it do this:

[d][e]  
[a][b][c]

or even

[a][b]
[c][d][e]

The reason I want this is because I have content below the row of inline elements, and when it breaks into two rows, having the top row be wider than the bottom row looks really bad.
Thanks.

Here's a fiddle: http://jsfiddle.net/6Hm4C/1/

Notes:
Window width, element width and number of elements are all dynamic. It has to work in IE9+ and FF24+, if this isn't possible FF has priority.

like image 519
Surgery Avatar asked Mar 26 '14 14:03

Surgery


2 Answers

How about using a "breaker" container like this?

<div id="container">
    <div class="breaker">
        <div class="box">Box 1 Bigger</div>
        <div class="box">Box 2</div>
    </div>
    <div class="breaker">
        <div class="box">Box 3 Random</div>
        <div class="box">Box 4</div>
        <div class="box">Box 5 Stuff</div>
    </div>
</div>

And this CSS:

.breaker { display: inline-block; }
.box { 
    display: inline-block;
    vertical-align: top;
}

This will break [a][b][c][d][e] into

[a][b]
[c][d][e]

Now, in order to account for a dynamic number of boxes and widths, you need to use Javascript. With jQuery, you could do it like this:

function betterBreak(container) {
    var boxes = $(container).children(),
        sum = 0, max = 0;
    boxes.map(function(x, box) { max += $(box).outerWidth(); });
    boxes.each(function(x, box) {  
        sum += $(box).outerWidth();
        if(sum > max/2) {
            var breakerBig = $('<div class="breaker"></div>'),
                breakerSmall = $('<div class="breaker"></div>');
            boxes.slice(x).appendTo(breakerBig);
            boxes.slice(0,x).appendTo(breakerSmall);
            $(container).append(breakerSmall).append(breakerBig);
           return false;
        }
    });
}

Calling betterBreak('#container') on a Container element that has an unknown number of child element "boxes" will dynamically wrap the children in 2 breaker divs that split the line into the desired layout when going to 2 rows.

Adjusted Demo: http://jsfiddle.net/pyU67/8/

like image 176
S.B. Avatar answered Oct 10 '22 01:10

S.B.


You could use writing-mode as i commented , but for younger browser, Firefox seems out :http://codepen.io/gc-nomade/pen/DCqLb/

body {
  counter-reset: boxe;/* demo purpose */
/* reverse flow from bottom to top */
  writing-mode:lr-bt;
  -webkit-writing-mode: horizontal-bt;
  -moz-writing-mode: horizontal-bt;/* fails */
  -o-writing-mode: horizontal-bt;
  writing-mode: horizontal-bt;
}
/* demo purpsose */
b {
  display:inline-block;
  line-height:3em;
  width:8em;
  text-align:center;
  background:lime;
  border-radius:1em;
  margin:1em;
}
b:before {  
  counter-increment:boxe;
  content:counter(boxe) ' ';
}

HTML use in body

<b> inline-box </b>
<b> inline-box </b> <!-- and so many more -->

From your fiddle , it does : http://jsfiddle.net/6Hm4C/3/ or just the spans http://jsfiddle.net/6Hm4C/4/

To test in IE, Safari, Opera, Chrome, and fails in FF :(

like image 40
G-Cyrillus Avatar answered Oct 10 '22 01:10

G-Cyrillus