JSFiddle - React, Tailwind, and code Playground
HTML
<div id="viewport">
<ul id="list">
<li class="above">Foo</li>
<li class="selected">Bar</li>
<li class="below">Barf</li>
<li>Boo</li>
<li>Huh</li>
<li>Wha</li>
<li>Oh</li>
</ul>
</div>
<a href="#" id="up">UP</a> -- <a href="#" id="down">DOWN</a>
CSS
#viewport{
height: 175px;
overflow: hidden;
padding: 0;
}
ul{
list-style-type: none;
padding: 0;
margin: 0;
}
li{
border: 1px solid #ccc;
width: 70px;
height: 50px;
line-height: 50px;
padding: 0 0 0 30px;
margin: 5px;
font-size: 1.5em;
color: #999;
background-color: #fed;
}
li.selected{
border-radius: 20px;
background-color: #fe0
}
li.above{
border-radius: 10px;
border-top-left-radius: 35px;
}
li.below{
border-radius: 10px;
border-bottom-left-radius: 35px;
}
JavaScript
var viewport = $('#viewport'),
list = $('#list'),
itemHeight = $('li', list).first().outerHeight(),
btnUp = $('#up'),
btnDown = $('#down'),
busy = false,
selected, above, below;
var update = function(){
selected = $('li:nth-of-type(2)', list).addClass('selected', 200);
above = selected.prev().addClass('above', 200);
below = selected.next().addClass('below', 200);
setTimeout(function(){ busy = false; }, 200);
};
var goUp = function(){
if(busy) return; else busy = true;
$('li', list).removeClass('selected above below');
list.animate({marginTop: -itemHeight}, 600, 'easeOutBounce', function(){
list.css({marginTop: 0}).append($('li', list).first());
update();
});
}
var goDown = function(){
if(busy) return; else busy = true;
$('li', list).removeClass('selected above below');
list
.css({marginTop: -itemHeight})
.prepend($('li',list).last())
.animate({marginTop: 0}, 600, 'easeOutBounce', update);
}
btnUp.on('click', goUp);
btnDown.on('click', goDown);