Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wrap a div vertically and then horizontally

Tags:

jquery

css

I need to show the search result data in my site horizontally. I follow a metro UI approach for my website, so I want the data to flow horizontally instead of vertically.

What I require is demonstrated in the below image:

Desired OutPut

The resulted data is dynamic. I want to draw the divs vertically first based on the parent div height and then horizontally. Something similar to WPF wrap panel, but I haven't been able to achieve it yet.

This is what I have tried, drawing horizontally and then vertically:

Fiddle: http://jsfiddle.net/4wuJz/2/

HTML:

<div id="wrap">
   <div id="wrap1">
       <div class="result">
           <div class="title">1</div>
           <div class="postcontent">  
              <p>Test</p>
           </div>
       </div>

       <div class="result">
           <div class="title">2</div>
           <div class="postcontent">
              <p>Test</p>
           </div>
       </div>
   </div>
</div>

CSS

#wrap {
   width:100%;
   height: 500px;
   background-color: rgba(0,0,0,0.5);
   overflow:scroll;
   overflow-y:hidden;
}

#wrap1 {
   width:2500px;
   height:500px;
   text-align: center;
}


.result {
   width: 300px;
   vertical-align: middle;
   float:left;
   background: rgba(120,30,20,0.5);
   padding: 10px;
   margin: 30px 0px 30px 30px; 
}

How can I change my code so that I meet the desired output? Any jQuery plugins available for this?

like image 757
Monie corleone Avatar asked Dec 23 '13 12:12

Monie corleone


People also ask

How do I align a div vertically and horizontally?

You can do this by setting the display property to "flex." Then define the align-items and justify-content property to “center.” This will tell the browser to center the flex item (the div within the div) vertically and horizontally.

How do I move a div horizontally?

Answer: Use the CSS margin property If you would like to center align a <div> element horizontally with respect to the parent element you can use the CSS margin property with the value auto for the left and right side, i.e. set the style rule margin: 0 auto; for the div element.

How do I horizontally align a div in CSS?

To horizontally center a block element (like <div>), use margin: auto; Setting the width of the element will prevent it from stretching out to the edges of its container.


2 Answers

Add clear: left to the .result class so your boxes are stacked vertically.

Then wrap results in blocks of 3 and float these blocks horizontally. You can do that logic with whichever back-end language you may be using to output the results markup or with jQuery:

$('.result:nth-child(3n+1)').each(function() {
    $(this).add( $(this).next().next().addBack() ).wrapAll('<div style="float:left"></div>');
});

Fiddle


Here's a more responsive solution which re-calculates on window resize: Demo.

Note: it assumes all boxes have the same height. You can hardcode a max-height in the resultHeight variable if that's not the case.

$(window).resize(function() {
    var resultHeight = $('.result:first').outerHeight(true),
        nRows = Math.floor( $('#wrap1').height() / resultHeight );

    $('.results-column').contents().unwrap();
    $('.result:nth-child('+nRows+'n+1)').each(function() {
        $(this).nextAll().slice(0, nRows-1).add(this).wrapAll('<div class="results-column"></div>');
    });
}).resize();

Added CSS:

#wrap1 {
    white-space: nowrap;
}
.results-column {
    display: inline-block;
    vertical-align: top;
}

Also check out Isotope with its cellsByColumn/fitColumns layouts.


And lastly, your use case is a prime example for the use of the Flexible Box Layout. I haven't mentioned this yet because there are already other answers showing this solution, and also because it is rather hard to make cross-browser at the moment:

  • Firefox <= 27, IE10 and Safari <= 6 support an old version of the spec
  • Newer Chrome, Safari and IE11 support the new syntax
  • Can't forget all the browser prefixes!

Reference: http://caniuse.com/flexbox

Though, all is not lost yet. If you want to use Flexbox today, there's a very useful Flexbox generator.

CSS-only solution using Flexbox: Demo

#wrap1 {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
    -webkit-box-direction: normal;
    -moz-box-direction: normal;
    -webkit-box-orient: vertical;
    -moz-box-orient: vertical;
    -webkit-flex-direction: column;
    -ms-flex-direction: column;
    flex-direction: column;
    -webkit-flex-wrap: wrap;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
    -webkit-box-pack: start;
    -moz-box-pack: start;
    -webkit-justify-content: flex-start;
    -ms-flex-pack: start;
    justify-content: flex-start;
    -webkit-align-content: flex-start;
    -ms-flex-line-pack: start;
    align-content: flex-start;
    -webkit-box-align: start;
    -moz-box-align: start;
    -webkit-align-items: flex-start;
    -ms-flex-align: start;
    align-items: flex-start;
}

I've tested this solution and it works correctly in IE10, IE11, Chrome 31, Opera 18 and Firefox 29 Nightly.

Note: Firefox <= 27 does not support Flexbox with more than one row/column (it does not support flex-wrap: wrap). I've tested this on Firefox 29 (nightly) and it works correctly, so I believe it should land on stable soon enough.

like image 152
Fabrício Matté Avatar answered Oct 25 '22 08:10

Fabrício Matté


Flexbox will be a JavaScript-less solution:

#wrap1 {
    display: flex;
    flex-wrap: wrap;
    flex-direction: column;
}

Demo: http://jsfiddle.net/4wuJz/5/

like image 42
Pavlo Avatar answered Oct 25 '22 09:10

Pavlo