2D List Item Flip FINAL w/ edit
I think I finally have a good solution for 2D list item flipping.
by chucknelson
HTML
<div id="main-container">
<p class="title">List of Link Items</p>
<ul id="my-list">
<li>
<div class="view">
<a href="#" class="item-link">Item 1</a>
<a href="#" class="item-action">(action)</a>
</div>
<div class="edit">
<input type="text" value="Item 1" />
<a href="#">Done</a>
</div>
</li>
<li>
<a href="#" class="item-link">Item 2</a>
<a href="#" class="item-action">(action)</a>
</li>
<li>
<a href="#" class="item-link">Item 3</a>
<a href="#" class="item-action">(action)</a>
</li>
<li>
<a href="#" class="item-link">Item 4 is a really long item because you never know when you'll have to paste some crazy thing from a website and then you just need to deal with it! The list item should expand to handle this.</a>
<a href="#" class="item-action">(action)</a>
</li>
<li>
<a href="#" class="item-link">Item 5</a>
<a href="#" class="item-action">(action)</a>
</li>
</ul>
</div>
CSS
/*
http://www.paulirish.com/2012/box-sizing-border-box-ftw/
apply a natural box layout model to all elements
*/
*, *:before, *:after {
-moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;
}
#main-container {
width: 100%;
-webkit-perspective: 1000px;
}
p {
margin: 0;
}
p.title {
background-color: #eee;
}
ul {
margin: 0;
padding-left: 0;
list-style-type: none;
}
li {
display: table;
width: 100%;
height: 2em;
border-bottom: 1px solid black;
}
li a {
display: table-cell;
height: 100%;
padding: .5em;
vertical-align: middle;
-webkit-transition: inherit;
}
li a.item-link {
width: 90%;
padding-right: .5em;
}
li a.item-action {
width: 10%;
text-align: center;
}
li input {
display: table-cell;
width: 80%;
margin: .5em;
vertical-align: middle;
}
li:first-child {
border-top: 1px solid black;
}
li.sorting {
border: none;
background-color: #ddd;
//border-top: 1px solid black;
//border-bottom: 1px solid black;
//display: block;
}
.animated {
-webkit-transition: 0.4s;
}
.flipped {
border-top: 1px solid black;
background-color: #555;
-webkit-transform: rotateX(180deg);
}
.flipped a {
color: #eee;
text-decoration: line-through;
-webkit-transform: scaleY(-1) translateZ(1px);
}
.flipped:not(:first-child) {
border-bottom: none;
}
JavaScript
//List of links and actions with sorting and flip animations
//TO FIX: Link should be fully clickable (in entire list item) after flip. ANSWER: Nudging z-axis with translateZ(1px) in the transform seems to fix this. Don't understnad the root cause yet (browser bug?), but question still hanging out at stackoverflow.
//TO FIX: action should be vertically aligned regardless of tall the list item is. ANSWER: Went with table + table-cell layout for list items. Seems to work fine...
//TO FIX: item borders shouldn't slide all over the place when sorting. ANSWER: Display items with table > table-cell seems to cause this. Forcing the display to block while sorting seems to work and doesn't mess up the item layout when sorting (somehow).
//NOTE: forcing to block display causes list item text alignment to break. Can just remove borders on list item and it works find, set background color instead. Not optimal, but better than alignment breaking in item.
//TO FIX: Can I shrink these list items without borders and alignment breaking? ANSWER: YES, problem is sub-pixel rendering. I had font going to .8 em, which is 16px * .8 = 12.8px - the way browsers have to handle this caused the height of some of my list items to be 1px different, breaking the uniformity and borders. Staying at quarter fractions (.25, .5, .75) seems to fix this.
$(function() {
$('ul').on('click', 'li a', function(event) {
listItem = $(this).parent();
listItem.addClass('animated');
listItem.toggleClass('flipped');
});
$('ul').on('webkitTransitionEnd', 'li', function(event) {
$(this).removeClass('animated');
});
$('ul').sortable({
start: function(event, ui) {
ui.item.addClass('sorting');
ui.placeholder.height(ui.item.height());
},
stop: function(event, ui) {
ui.item.removeClass('sorting');
},
update: function(event, ui) {
}
});
});