$(function(){ var $slider = $('.slider') , slider_width = 0 , $slider_inner = $slider.children().first() , $elements = $slider_inner.children('.element') , elements_count = $elements.length , element_width = $elements.first().width() , element_margin = 0 , elements_fit = 0 , visible_width = 0 function onResize() { slider_width = $slider.width() elements_fit = Math.floor(slider_width/element_width) // we have a limited number of elements if (elements_fit > elements_count) { elements_fit = elements_count } // we need only odd number if (elements_fit % 2 === 0) { elements_fit -= 1 } // find element margin for balancing element_margin = Math.ceil((slider_width - (element_width * elements_fit))/(elements_fit * 2)) visible_width = (element_width + element_margin * 2) * elements_fit // set container width * 1.5 to fit clonned elements when scroll $slider_inner.width(Math.ceil(visible_width * 1.5)) // add margins $elements.css({'margin-left': element_margin + 'px', 'margin-right': element_margin + 'px'}) } function goTo(index_to) { var index_past = Math.floor(elements_fit/2) // if active element if (index_to === index_past) { return } var index_diff = index_to - index_past , $elements_slice , left_to = 0 if (index_diff > 0) { $elements_slice = $elements.slice(0, index_diff) // append diff elements $elements_slice.clone().appendTo($slider_inner) // compute left offset left_to = -((element_width + element_margin * 2) * index_diff) } else { $elements_slice = $elements.slice(index_diff) // append diff elements $elements_slice.clone().prependTo($slider_inner) // set left offset $slider_inner.css('left', (element_width + element_margin * 2) * index_diff + 'px') } // reindex elements $elements = $slider_inner.children('.element') // scroll to position $slider_inner.animate({ left: left_to + 'px' }, { duration: 1000 , easing: 'swing' , complete: function() { // remove duplicates $elements_slice.remove() // reposition slider $slider_inner.css('left', 0) // reindex elements $elements = $slider_inner.children('.element') } }) } onResize() $(window).on('resize', onResize) $slider .on('click', 'a.slider-control', function(ev){ ev.preventDefault() var direction = $(this).hasClass('left') ? -1 : 1 goTo(Math.floor(elements_fit/2) + direction) }) .on('click', '.element', function(ev){ ev.preventDefault() goTo($elements.index(this)) }) })