Scrollable Horizontal Container Slider w/ Next & Previous Buttons

A basic slider, or scrollable horizontal container with infinite children and next and previous buttons.

by Brett

HTML

<div id="outer-container">
    <div id="prev" class="prev-arrow">Prev</div>
    <div id="next" class="next-arrow">Next</div>
    <ul id="inner-container">
        <li class="item">
            <h2>Hello, First.</h2>
        </li>
        <li class="item">
            <h2>Hello, World.</h2>
        </li>
        <li class="item">
            <h2>Hello, World.</h2>
        </li>
        <li class="item">
            <h2>Hello, World.</h2>
        </li>
        <li class="item">
            <h2>Hello, World.</h2>
        </li>
        <li class="item">
            <h2>Hello, World.</h2>
        </li>
        <li class="item">
            <h2>Hello, World.</h2>
        </li>
        <li class="item">
            <h2>Hello, World.</h2>
        </li>
        <li class="item">
            <h2>Hello, Last.</h2>
        </li>
    </ul>
</div>

SCSS

body {
	margin: 0;
	padding: 0;
}
#outer-container {
	width: 100%;
	height: 200px;
	margin: 0 auto;
	padding: 0;
	background: purple;
	overflow: hidden;
	
	#inner-container {
		width: 100%;
		margin: 0;
		padding: 0;
		list-style-type: none;
		font-size: 0; // trick to eliminate space on inline-block;
		white-space: nowrap;
		overflow: scroll;
		
		.item {
			display: inline-block;
			vertical-align: top;
			width: 250px;
			height: 100px;
			background: red;
			font-size: initial; // reset font-size back to normal after inline-block trick
			text-align: center;
			
			h2 {
				margin: 0;
				line-height: 100px;	
			}
		}
	}
}
.prev-arrow,
.next-arrow {
	display: block;
	position: absolute;
	top: 100px;
	width: 100px;
	height: 100px;
	background: #ccc;
	line-height: 100px;
	text-align: center;
	cursor: pointer;
	
	&.invisible {
		visibility: hidden;	
	}
}
.prev-arrow {
	left: 0;
}
.next-arrow {
	right: 0;
}

JavaScript

// on button clicks
$('#prev').on('click', function() {
    scrollIt('prev');
});
$('#next').on('click', function() {
    scrollIt('next');
});

var outerWidth = $('#outer-container').width(),
    innerWidth = $('#inner-container').width(),
    itemWidth = $('#inner-container > .item').width();

// scroll div when buttons are clicked
function scrollIt(direction) {
    if (direction == 'prev') {
        $('#inner-container').animate({
            scrollLeft: '-=' + itemWidth + 'px'
        }, function() {
            scrollArrows();
        });
    } else if (direction == 'next') {
        $('#inner-container').animate({
            scrollLeft: '+=' + itemWidth + 'px'
        }, function() {
            scrollArrows();
        });
    }
}

function scrollArrows() {
    // prev
    if ((outerWidth - innerWidth) == $('#inner-container').scrollLeft()) {
        $('#prev').addClass('invisible');
    } 
    else {
        $('#prev').removeClass('invisible');
    }
    // next
    if (($('#inner-container > .item').length * itemWidth) - outerWidth == $('#inner-container').scrollLeft()) {
        $('#next').addClass('invisible');
    } 
    else {
        $('#next').removeClass('invisible');
    }
}
scrollArrows();

// also run when element is scrolled
$('#inner-container').scroll(function() {
    scrollArrows();
});