Setting as many horizontal divs as possible in HTML and filling in the line width

I have a group of elements with a fixed width div , styled for streaming printing using the inline-block display type. This leaves blank space at the end of the line (where the next div cannot be set and wrapped on the next line).

What I would like to do is to expand all the divs on the line evenly to fill the line , similar to the "alignment" alignment for the text .

In other words, I want to have a minimum width on the div elements and put as many of them as possible on one line and fill the entire line.

Here is my HTML example:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <style> #container { margin: 100px; padding: 10px; border: 1px solid blue; } .item { margin: 10px; width: 300px; min-width: 300px; display: inline-block; border: 1px solid red; } </style> </head> <body> <div id="container"> <div class="item">Item One</div> <div class="item">Item Two</div> <div class="item">Item Three</div> <div class="item">Item Four</div> </div> </body> </html> 

Is this possible with pure CSS + HTML? Or do I need to write a script to achieve this result?


UPDATE: as people continue to propose using percent width to match elements on the same line, I should note that this is NOT the intention of this question. I want to have something like "Justified" text, but with blocks. The number of elements is variable and may be too large.

Blocks should be of the same size, have a minimum width (default), which will lead to their transfer to the next line, if necessary, and the width of the container must be filled with children, expanding their width.


UPDATE 2:

The current selection produces something like this:

 |--------------------------- Container -----------------------------| | |------ 1 ------| |------ 2 ------| |------ 3 ------| | | |------ 4 ------| |------ 5 ------| |------ 6 ------| | | |------ 7 ------| | 

I want to see something like this:

 |---------------------------- Container ----------------------------| | |-------- 1 --------| |-------- 2 --------| |-------- 3 --------| | | |-------- 4 --------| |-------- 5 --------| |-------- 6 --------| | | |-------- 7 --------| | 

Or that:

 |---------------------------- Container ----------------------------| | |-------- 1 --------| |-------- 2 --------| |-------- 3 --------| | | |-------- 4 --------| |-------- 5 --------| |-------- 6 --------| | | |------------------------------ 7 ------------------------------| | 

Each element has a minimum size, therefore, in the above example, elements # 4 and # 7 will not correspond to the remaining space in the line and will be transferred to the next line. I want those that have already been installed on the line to fill the space.

Please note that the container may change as the browser may be changed. So, if it gets smaller, since only two elements fit into the string, I would like to see something like this:

 |----------------- Container -----------------| | |-------- 1 --------| |-------- 2 --------| | | |-------- 3 --------| |-------- 4 --------| | | |-------- 5 --------| |-------- 6 --------| | | |------------------- 7 -------------------| | 

Hope this clears up the intent of the question.

+6
source share
3 answers

You can do this with the flexbox model , however there are some problems.

There is an old and new flexbox model that makes things complicated. Currently, only Chrome and Opera support the new model, while other browsers have "partial support", which means that they can support:

With what is available today, I managed to put something together that works in Chrome 26 , Safari 5.1.7 , IE10 , IE10 in IE9 mode and IE10 in IE8 mode . Unfortunately, my current version of Firefox 20 is not on this list. I'm not sure if it will work in older versions of Firefox (I added the necessary CSS to jsFiddle at the bottom of the message, but I don't have old versions installed on my PC).

This link explains why it does not work in Firefox 20 . If you scroll down to the bottom of the page, it will report a flex-wrap property:

Firefox (Gecko) - not supported. Firefox only supports single line flexbox.

I am not 100% sure about this, but it seems to me that they never supported the flex-wrap property even in older versions. Correct me if I am mistaken, anyone who has version of Firefox 19 - but I think that if they had, Firefox 20 , at least, would come back to it for they had not yet fully implemented the new flexbox model.

This flex-wrap property is what does multi-line magic in most other browsers. Firefox is expected to fully support the new flexbox model in version 22 , which is scheduled to be released on June 25, 2013. UPDATE: Firefox now supports the flex-wrap property from version 28 up. / UPDATE

After all this, jsFiddle , which, as in my recent research, makes the job as possible as possible. This is apparently the best you can do in pure CSS + HTML with current browser support.

If you need something better right now , you have to come up with a JS solution. Perhaps look at the source of flexieJS and change the browser detection code so that it treats Firefox 20 as Well. box-pack and box-orient are on the list of supported FlexieJS properties, these are the properties that make this work older iOS and Safari .

Edit: As @Cimmanon points out in the comments, in order to make this work in older browsers, they will need to support box-lines: multiple , which is not the case. Thus, this will not work on older versions of iOS , Safari, and Firefox . I suppose this explains why Firefox 20 does not have the old implementation to return. Since FlexieJS does not have support for box-lines: multiple , its source will probably not be very helpful trying to fix this problem. Writing your own JS patch seems like the only solution right now . FlexieJS developer is working on a polyfill for a new specification . This would have to include some code to fix multi-line in older browsers. Actually it does not look like. If you are planning to write something, perhaps you could contact him for some reasons. Give him your code if you earn it. If you're lucky, he already has something going on that hasn’t yet reached GitHub.

CSS:

 #container { margin: 100px; padding: 10px; border: 1px solid blue; display: -webkit-box; /* iOS 6-, Safari 3.1-6 */ display: -moz-box; /* Firefox 19- */ display: -ms-flexbox; /* IE 10 */ display: -webkit-flex; /* Chrome */ display: flex; /* Opera 12.1, Firefox 20+ */ /* iOS 6-, Safari 3.1-6 */ -webkit-box-orient: horizontal; -webkit-box-pack: justify; -webkit-lines: multiple; /* Only here for informative purpose, this line is what should have made it work, it has never been implemented */ /* Firefox 19- */ -moz-flex-flow: row wrap; -moz-justify-content: space-between; -moz-box-lines: multiple; /* Only here for informative purpose, this line is what should have made it work, it has never been implemented */ /* Chrome */ -webkit-flex-flow: row wrap; -webkit-justify-content: space-between; /* IE10 */ -ms-flex-flow: row wrap; -ms-justify-content: space-between; /* Opera 12.1, Firefox 20+ */ flex-flow: row wrap; justify-content: space-between; } .item { margin: 10px; width: 300px; border: 1px solid red; -webkit-box-flex: auto; /* iOS 6-, Safari 3.1-6 */ -moz-box-flex: 1.0; /* Firefox 19- */ -webkit-flex: auto; /* Chrome */ -ms-flex: auto; /* IE10 */ flex: auto; /* Opera 12.1, Firefox 20+ */ } 
+11
source

You can do this in two ways (if you know how many there are):

Example one: Floating .items works, see fiddle http://jsfiddle.net/David_Knowles/wh5bP/

 #container { margin: 100px; overflow:hidden; border: 1px solid blue; } .item { width: 23%; /* important: (100% / numberOfItems - margin%) */ margin: 0 1%; /* important */ float:left; /* important */ -moz-box-sizing: border-box; /* only needed to compensate for the border used in your debugging */ -webkit-box-sizing: border-box; box-sizing: border-box; border: 1px solid red; 

}

Example two:

Elements of a string block are sensitive to the space between line breaks. Note the absence of spaces between the elements. http://jsfiddle.net/David_Knowles/wh5bP/1/

 <div id="container"> <div class="item">Item One</div><div class="item">Item Two</div><div class="item">Item Three</div><div class="item">Item Four</div> </div> .item { width: 23%; margin: 0 1%; display:inline-block; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; border: 1px solid red; 

}

If you never know how many .items are, then you can take a look at the flexbox model. http://css-tricks.com/using-flexbox/ http://caniuse.com/flexbox

If your target audience is using IE9 or less, you will also need to use polyfill. http://flexiejs.com/

+1
source

This is a job for Flexbox, but you need to decide how you want things to go for Flexbox browsers. Aligning things in the center may be your best bet.

http://codepen.io/cimmanon/pen/lBDwu

 ul { display: -webkit-flexbox; display: -ms-flexbox; display: -webkit-flex; -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap; list-style: none; padding: 0; text-align: center; /* text-align: justify; -moz-text-align-last: justify; text-align-last: justify;*/ } @supports (flex-wrap: wrap) { ul { display: flex; } } li { display: inline-block; -webkit-flex: 1 0; -ms-flex: 1 0; flex: 1 0; min-width: 10em; background: #CCC; border: 1px solid; margin: .5em; } 

Due to the need for wrapping, only Chrome, Opera and IE10 can do this. Everyone else will get a refund experience.

+1
source

All Articles