pedropeixoto
pedropeixoto

Reputation: 1633

DIV's reorder by themselves upon expand - how do I keep the same order?

I've got a grid of items that upon click expand to show a table below it. It works fine, but it reorders the DIV's positions as per my illustration below.

I need them to keep their respective position in their "columns".

Here's the illustration to make it clear:

enter image description here

And here is my HTML code:

<div 
class="item-component" 
ng-controller="CollapseCtrl"
ng-repeat="component in components.components | filter : components.filterByFilter | filter : searchText"
>

<div class="component-wrapper" ng-click="isCollapsed = !isCollapsed">
    Item - click to expand
</div>

<div class="codes-wrapper" collapse="isCollapsed">    
    <table class="table table-striped table-condensed">
        Expanded content here
    </table>    
</div>
</div>

And here is the .item-component class:

.item-component {
  width: 33.33333333333333%;
  float: left;
  padding-left: 15px;
}

How would I achieve the "expected result" in my illustration?

Upvotes: 3

Views: 328

Answers (3)

Michal B.
Michal B.

Reputation: 5719

You can do it in the following way.

HTML:

<div class="container">
    <div class="col">1</div>
    <div class="col">2</div>
    <div class="col">3</div>
    <br class="clear" />
    <div class="col">4</div>
    <div class="col">5</div>
    <div class="col">6</div>
    <br class="clear" />
    <div class="col">7</div>
    <div class="col">8</div>
    <div class="col">9</div>
<div>

CSS:

.col {
    float: left;
    width: 100px;
    min-height: 100px;
    background: #ccc;
    padding: 20px;
    margin: 10px;
    cursor: pointer;
}

.col:hover {
    background: yellow;
}

JS:

$('.col').click(function() {
    if ($(this).is('.clicked')) {
        $(this).removeClass('clicked');
    } else {
        $(this).addClass('clicked')
    }
});

Live demo: http://jsfiddle.net/S7r3D/1/

ETA: the problem with this solution is that it moves entire row down. I don't really see how to nicely achieve what you want...You could try to overflow the other divs, but it depends on your needs. Is such solution acceptable?

ETA2: actually I made it perfect I think! Have a look here: http://jsfiddle.net/S7r3D/3/ The crucial change was rearranging divs and putting them in columns instead.

HTML:

<div class="container">
    <div class="fleft">
        <div class="col">1</div>
        <div class="col">4</div>
        <div class="col">7</div>
    </div>
    <div class="fleft">
        <div class="col">2</div>
        <div class="col">5</div>
        <div class="col">8</div>
    </div>
    <div class="fleft">
        <div class="col">3</div>
        <div class="col">6</div>
        <div class="col">9</div>
    </div>
<div>    

CSS:

.col {
    clear: both;
    width: 100px;
    min-height: 100px;
    background: #ccc;
    padding: 20px;
    margin: 10px;
    cursor: pointer;
}

.col:hover {
    background: yellow;
}

.col.clicked {
    height: 300px;
    background-color: red;
}

.fleft
{    
    float: left;
}

JS: /* same as above */

Upvotes: 2

Alvaro
Alvaro

Reputation: 41595

Use display:inline-block instead of float:left on your .item-component

Living Demo

.item-component {
  width: 33.33333333333333%;
  display: inline-block;
  padding-left: 15px;
}

Or, you can take a look at BootStrap and do it by using the :before element maintaning the float:left as you had it before. You would also need to wrap each row:

.col{
    float:left;
    width: 32.33%;
    min-height: 50px;
    background: #ccc;
    padding: 20px;
    box-sizing: border-box;
}
.row{
    display:block;
}
/* This do the trick */
.row:before{
    content: " ";
    display: table;
    box-sizing: border-box;
    clear: both;
}

Living example


Update If you don't want the gap you will have to look for another HTML markup. You will have to print first each column with each rows.

This is the needed html markup:

<div class="col">
    <div class="row" id="demo">1</div>
    <div class="row">4</div>
    <div class="row">7</div>
</div>

<div class="col">
    <div class="row">2</div>
    <div class="row">5</div>
    <div class="row">8</div>
</div>

<div class="col">
    <div class="row">3</div>
    <div class="row">6</div>
    <div class="row">9</div>
</div>

And the needed css:

.col{
    float:left;
    width: 32.33%;
}
.row{
   display:block;
   padding: 20px;
   box-sizing: border-box;
   background: #ccc;
   min-height: 50px;
}
#demo{
    height: 150px;   
    background: red;
}

Living demo

Upvotes: 3

Bolt Thunder
Bolt Thunder

Reputation: 747

Create three container divs, and afterwards, put {1, 4, 7} into div1, {2, 5, 8} into div2, and {3, 6, 9} into div3.

Otherwise you will have it very difficult to control their positioning.

Upvotes: 0

Related Questions