CodePen

HTML

            
              <div>
  <p>Inspiration: http://css-tricks.com/slider-with-sliding-backgrounds/</p>
  <ul class="slider" lang="fi">
    <li id="weather_helsinki" class="slider__slide">
      <h3 class="slider__title">Helsinki</h3>
      <abbr class="slider__temperature" title="20 astetta">20°</abbr>
    </li>
    <li id="weather_hyvinkaa" class="slider__slide slider__slide--active">
      <h3 class="slider__title">Hyvinkää</h3>
      <abbr class="slider__temperature" title="24 astetta">24°</abbr>
    </li>
    <li id="weather_pello" class="slider__slide">
      <h3 class="slider__title">Pello</h3>
      <abbr class="slider__temperature" title="25 astetta">25°</abbr>
    </li>
  </ul>
  <ul>
    <li><a href="#weather_helsinki">Helsinki</a></li>
    <li><a href="#weather_hyvinkaa">Hyvinkää</a></li>
    <li><a href="#weather_pello">Pello</a></li>
  </ul>
</div>
<div>
  <p>Multiple just so you can see this is properly done.</p>
  <ul class="slider">
    <li class="slider__slide">
      <h3 class="slider__title">London</h3>
      <abbr class="slider__temperature" title="20 degrees">20°</abbr>
    </li>
    <li class="slider__slide">
      <h3 class="slider__title">Berlin</h3>
      <abbr class="slider__temperature" title="24 degrees">24°</abbr>
    </li>
    <li class="slider__slide slider__slide--active">
      <h3 class="slider__title">Paris</h3>
      <abbr class="slider__temperature" title="25 degrees">25°</abbr>
    </li>
    <li class="slider__slide">
      <h3 class="slider__title">Moscow</h3>
      <abbr class="slider__temperature" title="15 degrees">15°</abbr>
    </li>
    <li class="slider__slide">
      <h3 class="slider__title">Sydney</h3>
      <abbr class="slider__temperature" title="34 degrees">34°</abbr>
    </li>
    <li class="slider__slide">
      <h3 class="slider__title">Tokyo</h3>
      <abbr class="slider__temperature" title="35 degrees">35°</abbr>
    </li>
  </ul>
</div>
            
          
!
via HTML Inspector

CSS

            
              @import url(http://fonts.googleapis.com/css?family=Josefin+Slab:100);

/* unimportant */
body {
  background: #212121;
}

div {
  background: #C1C1C1;
  border-radius: 2em;
  float: left;
  margin: 1em;
  padding: .5em;
}

/* we have no extra "slider container" here! */
.slider {
  font-family: 'Josefin Slab', sans-serif;
  /* this color is what you see when slides fade in or out */
  background: black;
  /* for our scroll magic */
  overflow: hidden;
  /* remove this if you want to hide the scrollbar */
  overflow-x: auto;
  /* list style resets */
  margin: 0 auto;
  padding: 0;
  /* just to throw text up on the same line */
  vertical-align: text-top;
  /* remove space between inline-blocks */
  font-size: 0;
  white-space: nowrap;
}

/* just to avoid replicating some stuff */
.slider,
.slider__slide {
  /* this is required for JavaScript or you get incorrect scrollLeft values */
  position: relative;
  /* the size of the thing */
  width: 300px;
  height: 500px;
}

/* there are a lot of dynamic effects here, it can be overkill for some devices */
.slider__slide {
  /* cooler than the over abused floats! */
  display: inline-block;
  /* we must restore font size */
  font-size: xx-large;
  color: white;
  text-indent: 25px;
  /* visual appeal stuff! */
  text-shadow: 1px 1px 1px black;
  box-shadow: inset 0 0 35px black;
  opacity: .5;
  transition: opacity .2s ease-in;
}

/* this does the between slides fade in */
.slider__slide--active {
  opacity: 1;
}

/* arrows on :hover */
.slider__slide:not(:first-child):before,
.slider__slide:not(:last-child):after {
  border: 1.5em solid transparent;
  content: '';
  display: block;
  margin-top: -1.5em;
  opacity: 0;
  transition: opacity .5s ease-in 250ms;
  position: absolute;
  top: 50%;
  height: 0;
  width: 0;
  pointer-events: none;
}

.slider__slide:not(:first-child):before {
  border-right-color: white;
  left: -1.25em;
}

.slider__slide:not(:last-child):after {
  border-left-color: white;
  right: -1.25em;
}

.slider__slide--active:hover:before,
.slider__slide--active:hover:after {
  opacity: .3;
}

/* essentially replicates the size of the slide */
.slider__title {
  /* creates the fade to black in bottom of the slide */
  background: linear-gradient(to top, black, rgba(0, 0, 0, .5) 34%, transparent);
  font-size: smaller;
  font-weight: normal;
  /* careful alignment to match height of the slide */
  margin: 300px 0 0 0;
  padding: 50px 0 100px 0;
  height: 50px;
  line-height: 50px;
  /* may do something some day */
  pointer-events: none;
}

/* negative margin so no effect to the size of the slide */
.slider__temperature {
  /* attr element reset */
  border: 0;
  display: block;
  /* big looks good! */
  font-size: 250%;
  /* careful alignment to match 100px height */
  margin: -100px 0 0 0;
  height: 75px;
  line-height: 75px;
  padding-bottom: 25px;
  /* may do something some day */
  pointer-events: none;
}

/*
  Certainly not the best way to identify your slides.
  Use IDs or additional classes or something.
  Makes yer life a tad bit easier, eh?
  Images here are 400px * 500px
*/

div:nth-of-type(1)
.slider__slide:nth-child(1) {
  background-image: url('http://placekitten.com/400/500?image=12');
}

div:nth-of-type(1)
.slider__slide:nth-child(2) {
  background-image: url('http://placekitten.com/400/500?image=13');
}

div:nth-of-type(1)
.slider__slide:nth-child(3) {
  background-image: url('http://placekitten.com/400/500?image=15');
}

div:nth-of-type(2)
.slider__slide:nth-child(1) {
  background-image: url('http://placekitten.com/400/500?image=7');
}

div:nth-of-type(2)
.slider__slide:nth-child(2) {
  background-image: url('http://placekitten.com/400/500?image=3');
}

div:nth-of-type(2)
.slider__slide:nth-child(3) {
  background-image: url('http://placekitten.com/400/500?image=5');
}

div:nth-of-type(2)
.slider__slide:nth-child(4) {
  background-image: url('http://placekitten.com/400/500?image=6');
}

div:nth-of-type(2)
.slider__slide:nth-child(5) {
  background-image: url('http://placekitten.com/400/500?image=2');
}

div:nth-of-type(2)
.slider__slide:nth-child(6) {
  background-image: url('http://placekitten.com/400/500?image=1');
}
            
          
!
? ?
? ?
Must be a valid URL.
+ add another resource
via CSS Lint

JS

            
              // find all .slider elements (i = 0)
(function(sliders, i, activeClass) {
  // go through each slider
  while(sliders[i]) {
    // get all slides of a slider
    (function(slider, slides) {
      /*
        Slide background width overflow:
        - 300px width slides
        - 400px width background images
        - 100px overflow
        - 300 / 100 = 3
      */
      var overflowRatio = 3,
          // onwheel normalize helper
          minDeltaY,
          // prepend with space
          addActiveClass = ' ' + activeClass,
          // match active class
          activeClassMatch = new RegExp(addActiveClass, 'g'),
          // element to scroll to (= "active" slide)
          closestToScrollTo = slides[0],
          // timeout for auto scroll
          scrollTimeout,
          // interval when scrolling
          scrollingInterval,
          // auto scroll function
          scrollingToClosest = function() {
            // calculate a distance to move
            var distance = ~~((closestToScrollTo.offsetLeft - slider.scrollLeft) / 8);
            // see if we end the scroll
            if(Math.abs(distance) < 1) {
              // just set the exact position to go to
              slider.scrollLeft = closestToScrollTo.offsetLeft;
              // use timeout to avoid unnecessary extra event
              setTimeout(function() {
                // now this happens after slider.onscroll event
                clearInterval(scrollingInterval);
                scrollingInterval = undefined;
              }, 0);
            } else {
              // we auto scroll!
              slider.scrollLeft += distance;
            }
          },
          // this finds the closest element to scroll to
          scrollToClosest = function() {
            scrollTimeout = undefined;
            // remove existing auto scroll
            if(scrollingInterval) clearInterval(scrollingInterval);
            scrollingInterval = setInterval(scrollingToClosest, 10);
          }
      // WTF why somebody uses this?!?
      slider.onscroll = function() {
        var sliderLeft = slider.scrollLeft,
            distance, nearestDistance,
            currentActive = closestToScrollTo;
        // are we auto scrolling already?
        if(!scrollingInterval) {
          closestToScrollTo = undefined;
          // loop through all slides
          for(var i = 0; slides[i]; i++)
            (function(slide) {
              // do the neat sliding background effect
              slide.style.backgroundPosition = ~~((sliderLeft - slide.offsetLeft) / overflowRatio) + 'px 0';
              // also find the closest one: calculate distance
              distance = Math.abs(sliderLeft - slide.offsetLeft);
              if(!closestToScrollTo || distance < nearestDistance) {
                nearestDistance = distance;
                closestToScrollTo = slide;
              }
            })(slides[i]);
          // only change class if element has changed
          if(closestToScrollTo !== currentActive) {
            // remove active class
            currentActive.className = (
              ' ' + currentActive.className + ' '
            ).replace(activeClassMatch, '').trim();
            // add active class
            closestToScrollTo.className += addActiveClass;
          }
          // remove existing timeout if have one
          if(scrollTimeout) clearTimeout(scrollTimeout);
          // set timeout for auto scroll to position
          scrollTimeout = setTimeout(scrollToClosest, 150);
        } else {
          // loop through all slides
          for(var i = 0; slides[i]; i++)
            (function(slide) {
              // do the neat sliding background effect
              slide.style.backgroundPosition = ~~((sliderLeft - slide.offsetLeft) / overflowRatio) + 'px 0';
            })(slides[i]);
        }
      };
      // WTF somebody using this again?
      slider.onwheel = function(e) {
        // we want to eliminate vertical scrolling
        if (e.deltaY) {
          // normalize
          if (minDeltaY > Math.abs(e.deltaY) || !minDeltaY) {
            minDeltaY = Math.abs(e.deltaY);
          }
          // scroll a decent amount
          slider.scrollLeft += (e.deltaY / minDeltaY)
          * ((slider.scrollWidth - slider.clientWidth) / slides.length / 10);
          // do not let other wheel events to fire
          e.stopPropagation();
          e.cancelBubble = true; // same for old IE
          // and we don't want the default action either
          e.preventDefault();
          e.returnValue = false; // same for old IE
          // remove existing auto scroll
          if(scrollingInterval) {
            // doing this fixes some jerky behavior
            clearInterval(scrollingInterval);
            scrollingInterval = undefined;
          }
        }
      };
      // support browsers that do not support DOM Level 3 wheel
      slider.onmousewheel = function(e) {
        // old Internet Explorer
        if (!e) e = window.event;
        // we normalize the value so no need to guess how to convert
        e.deltaY = -e.wheelDelta;
        // we have done enough
        slider.onwheel(e);
      };
      var activeSlides = slider.getElementsByClassName(activeClass);
      // see if active has been set
      if(activeSlides.length === 1) {
        // found an active one
        closestToScrollTo = activeSlides[0];
      } else {
        // set initial active class to the first slide
        closestToScrollTo.className += addActiveClass;
      }
      // scroll to active
      scrollToClosest();
      // alternative: immediate scroll
      // slider.scrollLeft = closestToScrollTo.offsetLeft;
    })(
     sliders[i],
     sliders[i++].getElementsByClassName('slider__slide')
    ); // immediate function
  } // while
})(
  document.getElementsByClassName('slider'),
  0,
  'slider__slide--active'
); // immediate function
            
          
!
Must be a valid URL.
+ add another resource
via JS Hint
Loading ..................