Expandable lists without cloning or tweening

by khrome

HTML

<!-- <ul>
<li class="item-container">
    <div class="item">
        Name
    </div>
</li>
<li class="detail-container">
    <div class="details">
        description
    </div>
</li>
</ul> -->

CSS

body{
    margin:0px;
}
ul{
    padding:0px;
    margin:0px;
}
li{
   -webkit-transition: margin-bottom 0.2s;
    z-index : 0;
}


.recommendation span{
    display : inline-block;
    color:#444444;
    padding:5px;
    font-family: helvetica;
    font-size : 1.2em;
}

icon{
    font-size : 1.1em;
    float:left;
}

.header{
    background : grey;
    border: 1px solid grey;
    height :2em;
}

.terminal{
    background : grey;
    border: 1px solid grey;
    height :1.5em;
}

.terminal a{
    text-decoration : none;
}

.recommendation{
    position : absolute;
    height: 50px;
    border: 1px solid grey;
    border-width : 1px 0px 0px 0px; 
    background: #ffffff;
    width : 100%;
background: -webkit-linear-gradient(#ffffff 0%, #e5e5e5 100%);
}
.recommendation-details{
    width : 100%;
    position : absolute;
    background-color : grey;
background: -webkit-linear-gradient(top, rgba(0,0,0,0.65) 0px,rgba(247,245,242,1) 5px);
    border: 1px solid lightgrey;
    font-family: helvetica;
}
.recommendation-container{
    height :50px;
    width :100%;
}

.header-container{
    height :2em;
    width :100%;
}

.terminal-container{
    height :1.5em;
    width : 100%;
}
.recommendation-details-container{
    width : 200px;
}
.recommendation-details-container div{
    -webkit-animation-name: slideup;
    -webkit-animation-duration: 0.2s;
}
ul {
	list-style: none;
}

.contracted div{
    -webkit-animation-name: slideup;
    -webkit-animation-duration: 0.2s;
}

.expanded div{
    -webkit-animation-name: slidedown;
    -webkit-animation-duration: 0.2s;
}

.item:hover {
  background-color : red;
}

@-webkit-keyframes slidedown {
  from {
    margin-top: -200px; /* MAX HEIGHT */
  }
  to {
    margin-top: 0px;
  }
}

@-webkit-keyframes slideup {
  from {
    margin-top: 0px;
  }
  to {
    margin-top: -200px;
  }
}

JavaScript

function Recommendation(data, options){
    this.data = data || {};
    this.options = options || {};
    this.state = {};
};

Recommendation.prototype.build = function(){
    if(!this.element){
        var el = $(
            '<li class="recommendation-container">'+
                '<div class="recommendation">'+
                    this.data.name+
                '</div>'+
            '</li>'
        ).trigger('create');
        var ob = this;
        $(el).on('click', function(){
            console.log('tog');
            ob.toggle();
        });
        this.element = el;   
    }
    return this.element[0];
};

Recommendation.prototype.details = function(){
    if(!this.state.container){
        this.state.container = $(
            '<li class="recommendation-detail-container">'+
                '<div class="recommendation-details">'+
                    this.data.description+
                '</div>'+
            '</li>'
        ).trigger('create');
        this.state.fragment = document.createDocumentFragment();
        this.state.fragment.appendChild(this.state.container[0]);
        this.state.jcontainer = $(this.state.container);
        this.state.details = this.state.jcontainer.children('.recommendation-details')[0];
        this.state.jdetails = $(this.state.details);
        this.state.jdetails.css('z-index', '-1');
        this.state.jcontainer.append(this);
        var ob = this;
        this.state.details.addEventListener('webkitAnimationStart', function(){
            ob.state.jdetails.css('z-index', '-1');
        }, true);
        this.state.details.addEventListener('webkitAnimationEnd', function(){
            if(!ob.state.open){
                ob.state.jdetails.hide();
            }else ob.state.jdetails.css('z-index', '0');
        }, false);
        try{
            $(this.state.container).insertAfter(this.element);
            this.state.item_height = this.state.jdetails.height();
        }catch(ex){}
    }
    return...