<link href='//fonts.googleapis.com/css?family=Oswald:300' rel='stylesheet' type='text/css'>
<link type="text/css" href="//netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.css" rel="stylesheet">

<div class="controls baby-controls">
</div>

<div class="pagination baby-pagination">
</div>

<ol class="baby" id="baby">
  <li class="baby-item one"></li>
  <li class="baby-item two"></li>
  <li class="baby-item three"></li>
  <li class="baby-item four"></li>
</ol>
// ========================
// Slideshow Utilities
// ========================

// https://css-tricks.com/snippets/sass/covering-mixin/

@mixin cover-element {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
}


// ========================
// Slideshow
// ========================

@mixin slideshow($max-width: 100%) {
  max-width: $max-width;
  margin: 0 auto;
  padding-left: 0;
  list-style: none;
}


// ========================
// Slide Element
// ========================

@mixin transit($transformValue, $axis: x) {
  
  @if $axis == x {
    transform: translate($transformValue, 0);
  } @else {
    transform: translate(0, $transformValue);
  }
  
}

@mixin slide($effect: fade, $easing: .3s, $axis: x) { 
  @include cover-element;
  transition: 
    opacity $easing,
    visibility $easing,
    transform $easing;
  
  @if $effect == slide {
    @include transit(-100%, $axis);
  } @else {
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
  }
  
  
  // Inactive slide properties
  // =========================
  
  // All slides after the active slide
  &.active ~ * {
    
    @if $effect == slide {
      @include transit(200%, $axis);  
    }
    
  }
  
  // The slide next to the active slide
  &.active + * {
    
    @if $effect == slide {
      @include transit(100%, $axis);  
    }
    
  }
  
  // Active State
  // =========================
  
  &.active {
    position: relative;

    @if $effect == slide {
      @include transit(0);  
    } @else {
      pointer-events: auto;
      opacity: 1;
      visibility: visible;
    }

  }

}


// ========================
// Slideshow Controls
// ========================

.controls {
  @include cover-element;
  z-index: 200;
  height: 100%;
  text-align: center;
  pointer-events: none;
  visibility: hidden;
}

  .control { 
    position: absolute;
    top: 0;
    height: 100%;
    cursor: pointer;
    pointer-events: auto;
    visibility: visible;
    
    &:before {
      @include cover-element;
      top: 50%;
      font-family: 'FontAwesome';
      transform: translate(0, -50%);
    }
    
  }
  
  .prev {
    left: 0;

    &:before {
      content: '\f104';
    }

  }

  .next {
    right: 0;

    &:before {
      content: '\f105'; 
    }

  }


// ========================
// Slideshow Pager
// ========================

.pagination {
  @include cover-element;
  z-index: 200;
  text-align: center;
  
  span {
    display: inline-block;
    cursor: pointer;
    border-radius: 100%;
    
    &.active {
      pointer-events: none;
    }
    
  }
  
}


// ========================
// Slideshow Initialization
// ========================

// ||------------||
// ||     ~2     ||
// ||------------||

.baby {
  @include slideshow;
}


// ========================
// Slide Initialization
// ========================

// ||--||----||--||
// ||  || ~2 ||  ||
// ||--||----||--||

.baby-item {
  @include slide('slide');
}


// ========================
// Controls Initialization
// ========================

// < Previous  Next >

.control {
  width: 15%;
  font-size: 3.5em;
}


// ========================
// Pagination Initialization
// ========================
  
// o o o o o

.pagination {
  text-align: center;

  span {
    height: 1em;
    width: 1em;
    margin: 2% 1%;
    background: rgba(#fff, .5);

    &:hover {
      background: rgba(#fff, .75);
    }

    &.active {
      background: rgba(#000, .5);
    }

  }

}












// ========================
// Resets
// ========================

*,
*:before,
*:after {
  box-sizing: border-box;
  position: relative;
}

*:before,
*:after { 
  pointer-events: none; 
}


// ========================
// Structure
// ========================

html { 
  overflow-x: hidden;
  font-family: 'Oswald';
}


// ========================
// Presentation
// ========================

$baby-colors:
  #16F4D0,
  #429EA6,
  #153B50,
  #f53B50;

.baby-item {
  height: 100vh;

  &:before {
    position: absolute;
    top: 50%;
    left: 50%;
    font-size: 16vmin;
    transform: translate(-50%, -50%);
  }
  
  @for $i from 1 through 4 {
    
    &:nth-child(#{$i}) {
      background: nth($baby-colors, $i);
      
      &:before {
        content: '#{$i}';
      }
      
    }
    
  }
  
}
View Compiled
// Link me to your sonicSlide in action!

// Version 28.0

// Shuffle elements on load
// https://css-tricks.com/snippets/jquery/shuffle-dom-elements/

// Automatic Rotation
// setInterval(function() {
//   $('.controls--modifier .next').trigger('click');
// }, 10000);


babySonicSlide(
  'baby',
  '.baby-controls', 
  '.baby-pagination', 
  '.baby-item');

function babySonicSlide(list, listController, listPagination, listElement) {
  
  // Variable Setup
  // =================
  
  var prev = listController + ' .prev';
  var next = listController + ' .next';
  
  var pagination = listPagination;
  	var paginationItem = pagination + ' span';
  
  var element = listElement;
  
  var activeClass = 'active';
    var activeElement = element + '.' + activeClass;
  
  
  // Setup Controls
  // =================
  
  $(listController)
    .append('<span class="prev control" />')
    .append('<span class="next control" />');
  
  
  // Setup Pagination
  // =================
  
  if(!($(pagination + ' span').length)) {
    
    $(element).each(function() {

      $(pagination)
        .append('<span></span>');

    });
    
  }
  
  
  // Preparations
  // =================
  
  $(element + ':first-child')
    .addClass(activeClass);
  
  $(paginationItem + ':first-child')
    .addClass(activeClass);
  
  
  // Actions
  // =================
  
  // Previous Click
  // =================
  
  $(prev).click(function() {
    
    if($(element + ':first-child').hasClass(activeClass)) {
      
      $(activeElement)
        .removeClass(activeClass);
      
      $(element)
        .last()
          .addClass(activeClass);
      
    }
    
    else {
      
      $(activeElement)
        .removeClass(activeClass)
        .prev()
          .addClass(activeClass);
    
    }
    
    coordinatePagination();
    
  });
  
  
  // Next Click
  // =================
  
  $(next).click(function() {
    
    if($(element + ':last-child').hasClass(activeClass)) {
      
      $(activeElement)
        .removeClass(activeClass);
      
      $(element)
        .first()
          .addClass(activeClass);
      
    }
    
    else {
      
      $(activeElement)
        .removeClass(activeClass)
        .next()
          .addClass(activeClass);
    
    }
    
    coordinatePagination();
    
  });
  
  
  // Pagination Click
  // =================
  
  $(paginationItem).click(function() {
    
    $(paginationItem)
      .removeClass(activeClass);
    $(this)
      .addClass(activeClass);
    
    $(activeElement)
      .removeClass(activeClass);
    $(element + ':nth-child(' + ($(paginationItem + '.' + activeClass).index() + 1) + ')')
      .addClass(activeClass);
    
  });
  
  
  // Pagination Coor.
  // =================
  
  function coordinatePagination() {
    
    $(paginationItem)
      .removeClass(activeClass);
    $(paginationItem + ':nth-child(' + ($(activeElement).index() + 1) + ')')
      .addClass(activeClass);
    
  }
  
  
  
  //stackoverflow.com/questions/2264072/detect-a-finger-swipe-through-javascript-on-the-iphone-and-android
  var listContainer =  document.getElementsByClassName(list);
  listContainer = listContainer[0];
  
  listContainer.addEventListener('touchstart', handleTouchStart, false);
  listContainer.addEventListener('touchmove', handleTouchMove, false);

  var xDown = null;
  var yDown = null;

  function handleTouchStart(evt) {
    xDown = evt.touches[0].clientX;
    yDown = evt.touches[0].clientY;
  };
  
  function handleTouchMove(evt) {
    if ( ! xDown || ! yDown ) {
      return;
    }

    var xUp = evt.touches[0].clientX;
    var yUp = evt.touches[0].clientY;

    var xDiff = xDown - xUp;
    var yDiff = yDown - yUp;

    if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {
      
      if ( xDiff > 0 ) {
        $('.next').trigger('click');
      } else {
        $('.prev').trigger('click');
      }
      
    }

    /* reset values */
    xDown = null;
    yDown = null;
  };

}




External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. //cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js