<div class="container">
  
<h1>Responsive Magic Line Pagination</h1>

<div class="mainbox">
  
  <div class="pgn">
    <ul class="pgn__list" role="navigation" aria-labelledby="paginglabel">
      <li class="prev" title="Previous Page">
        <a href="#" rel="prev"><i class="pgn__prev-icon icon-angle-left"></i><span class="pgn__prev-txt">Previous</span></a>
      </li>
      <!--<li class="prev" title="Previous Page"></li>-->
      <li class="pgn__item">
        <a href="#">3</a>
        <a href="#">4</a>
        <strong class="current">5</strong>
        <a href="#">6</a>
        <a href="#">7</a>
      </li>
      <li class="next" title="Next Page">
        <a href="#" rel="next"><i class="pgn__next-icon icon-angle-right"></i><span class="pgn__next-txt">Next</span></a>
      </li>
      <!--<li class="next" title="Next Page"></li>-->
    </ul>
  </div><!-- /.pagination -->

  <div class="learnmore">
    <h2>Learn more 💪:</h2>
    <p class="c-fe30">Learn 30 real-world front-end skills like this pen @ <a href="https://frontend30.com/?utm_source=codepen&utm_medium=link&utm_campaign=magiclinepg_link" target="_blank">FrontEnd30.com</a>.
    </p>
    <div class="c-intro">
      <a class="c-ryanyu" href="https://frontend30.com/?utm_source=codepen&utm_medium=link&utm_campaign=magiclinepg_logo" target="_blank">
        <div class="c-ryanyu__front">
          <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/204808/ryan-yu-brand.png" alt="Ryan Yu" />
        </div>
        <div class="c-ryanyu__back"></div>
      </a>
    </div>
  </div>

  <div class="browsers">
    <h2>Supported Browsers ✌️:</h2>
    <ul>
      <li class="chrome">Chrome</li>
      <li class="firefox">Firefox</li>
      <li class="safari">Safari</li>
      <li class="opera">Opera</li>
      <li class="ie">IE 9+</li>
    </ul>
  </div>
  <div class="credit">
    <h2>Credit 👍:</h2>
    <ul>
      <li><a href="https://css-tricks.com/jquery-magicline-navigation/" target="_blank">https://css-tricks.com/jquery-magicline-navigation/</a></li>
    </ul>
  </div>
  <div class="follow">
    <h2>Let's connect 💛:</h2>
    <ul>
      <li>Website: <a href="https://ryanyu.com" target="_blank">ryanyu.com</a></li>
      <li>Twitter: <a href="https://twitter.com/iamryanyu" target="_blank">@iamryanyu</li>
    </ul>
  </div>
  
</div>
  
</div><!-- /.container -->
@import "compass/css3";

@import url(https://fonts.googleapis.com/css?family=Droid+Sans:400,700);

/*-- Variables --*/
$white: unquote(#fff);
$grey: #bec2d8;
$purple: #313868;

$pgn-top-border-color: $white;
$pgn-normal-color: $purple;
$pgn-disabled-color: #bec2d8;

$mq-tablet-small: "screen and (min-width: 37.500em)"; // 600px
$mq-tablet: "screen and (min-width: 48.000em)"; // 768px
$mq-desktop: "screen and (min-width: 64.000em)"; // 1024px

$base-font-pixel: 16;

@function rem($pixel) {
  @return $pixel / 16 + rem;
}

/*-- Placeholder --*/
%list-reset {
  list-style: none;
  margin: 0;
  padding: 0;
}

%clearfix {
  // credit: http://nicolasgallagher.com/micro-clearfix-hack/
  .cf:before,
  .cf:after {
    content: " "; /* 1 */
    display: table; /* 2 */
    line-height: 0;
  }

  .cf:after {
    clear: both;
  }

  /**
   * For IE 6/7 only
   * Include this rule to trigger hasLayout and contain floats.
   */
  .cf {
    *zoom: 1;
  }
}

/*-- Mixins --*/
@mixin font-size($sizeValue: 1) {
  font-size: ($sizeValue * $base-font-pixel) + px;
  font-size: $sizeValue + rem;
}

/*-- General --*/
body {
  font-family: 'Droid Sans', sans-serif;
  background-color: #e1e3f2;
}

h1 {
  color: #313868;
  text-align: center;
  margin-bottom: 100px;

  @include font-size(2.25);
}

h2 {
  color: #5a629b;

  @include font-size(1.25);
}

.container {
  padding: 20px;
}

.mainbox {
  width: 80%;
  margin: 0 auto;
}

// learn more
.learnmore {
  margin: 150px 0 18px;
  overflow: hidden;
}

// browsers
.browsers {
  margin: 0 0 50px;
  overflow: hidden;

  ul {
    @extend %list-reset;
  }

  li {
    float: left;
    text-align: center;
    padding-top: 80px;
    margin-right: 25px;
    background-size: 400px;
    background-image: url('http://outdatedbrowser.com/public/imgs/browsers-bg.png');
    background-repeat: no-repeat;

    @include font-size(.8125);
  }

  .chrome {
    width: 67px;
    background-position: -6px -83px;
  }

  .firefox {
    width: 69px;
    background-position: -85px -83px;
  }

  .safari {
    width: 69px;
    background-position: -246px -83px;
  }

  .opera {
    width: 66px;
    background-position: -327px -83px;
  }

  .ie {
    width: 70px;
    background-position: -165px -83px;
  }
}

// credit
.credit {
  margin: 0 0 50px;
}

.clearfix {
  @extend %clearfix;
}

/*-- Pagination --*/
.pgn {
  width: 100%;
  border-top: 3px solid $pgn-top-border-color;
  clear: both;
  
  li {
    float: left;
  }
  
  a,
  span,
  strong {
    float: left;
    text-align:center;
    padding-top: 20px;
    color: $pgn-normal-color;
    
    @media #{$mq-tablet} {
      display: block;
    }
  }
  
  a {
    text-decoration: none;
  }
  
  .prev,
  .next {
    width: 33.33333%;
    
    @media #{$mq-tablet-small} {
      width: 20%;
    }

    a {
      display: block;
      width: 100%;
    }
  }
  
  .prev {
    float: left;
    
    a {
      text-align: left;
    }
  }
  
  .next {
    float: right;
      
    a {
      text-align: right;
    }
  }
}

/* <ul> */
.pgn__list {
  @extend %list-reset;
    
  width: 100%;
  position: relative;
  top: -3px;
}

/* <li> - pagination numbers */
.pgn__item {
  width: 33.33333%;
  
  @media #{$mq-tablet} {
    width: calc(100% - 230px);
  }
  
  a,
  span,
  strong {
    display: none;
    text-align: center;
    width: 100%;
    
    &.current {
      display: block;
      
    }
  }

  a {
    @media #{$mq-tablet-small} {
      display: block;
    }
  }
}

/* prev/next icon */
.pgn__prev-icon,
.pgn__next-icon {
  margin-top: 1px;

  .disabled & {
    color: $pgn-disabled-color;
  }
}

.pgn__prev-icon {
  .fullprevnext & {
    float: left;
  }
}

.pgn__next-icon {
  .fullprevnext & {
    float: right;
  }
}

/* prev/next text */
.pgn__prev-txt,
.pgn__next-txt {
  display: none;

  .disabled & {
    color: $pgn-disabled-color;
  }

  .fullprevnext & {
    display: inline-block;
    padding-top: 0;
  }
}

.pgn__prev-txt {
  .fullprevnext & {
    float: left;
  }
}

.pgn__next-txt {
  .fullprevnext & {
    float: right;
  }
}

.pgn__magic-line {
  background-color: $pgn-normal-color;
  position: absolute;
  height: 3px;
}

/* =Variables
------------------------------------- */
// Colors
$pure-white: hsla(0, 0%, 100%, 1); // #fff
$pure-black: hsla(0, 0%, 0%, 1); // #000
$grey-dark: hsla(0, 0%, 25%, 1); // #404040
$white-dark: hsla(0, 0%, 95%, 1); /// #f1f1f1
$fuel-yellow: hsla(36, 100%, 49%, 1); // #f89500

$white: hsla(0, 0%, 100%, 1);
$charade: hsla(220, 13%, 18%, 1);
$light-grey: hsla(0, 0%, 83%, 1);
$fuel-yellow: hsla(39, 84%, 53%, 1);
$red: hsla(0, 100%, 50%, 1);
$jade: hsla(158, 100%, 34%, 1);
$gable-green: hsla(180, 49%, 14%, 1);

// Fonts
$droid-serif: 'Droid Serif', serif;
$kalam: 'Kalam', cursive;
$open-sans: 'Open Sans', sans-serif;

// transition
$transition: .5s cubic-bezier(.77, 0, .175, 1);
$transition-fast: .2s cubic-bezier(.77, 0, .175, 1);

.c-intro {
  position: relative;
}

.c-ryanyu {
  background-color: transparent;
  display: block;
  font-family: $kalam;
  height: rem(77);
  margin: rem(20) 0;
  position: relative;
  text-align: center;
  width: rem(77);

  img {
    background-color: $pure-white;
    border: rem(3) solid $fuel-yellow;
    border-radius: 50%;
    height: rem(70);
    object-fit: contain;
    width: rem(70);
  }
}

.c-ryanyu__front {
  backface-visibility: hidden;
  height: inherit;
  position: absolute;
  top: 0;
  transform: rotateX(0) rotateY(0);
  transform-style: preserve-3d;
  transition: all $transition;
  z-index: 2000;

  .c-ryanyu:hover & {
    transform: rotateY(180deg);
  }
}

.c-ryanyu__back {
  background-color: $pure-black;
  backface-visibility: hidden;
  border-radius: 50%;
  color: $fuel-yellow;
  height: inherit;
  position: absolute;
  text-align: center;
  top: 0;
  transform: rotateY(180deg);
  transform-style: preserve-3d;
  transition: all $transition;
  width: inherit;
  z-index: 1000;

  &::before {
    content: 'Ryan Yu';
    display: block;
    transform: rotate(-45deg) translate(-6px, 27px);
    width: rem(50);
  }

  .c-ryanyu:hover & {
    transform: rotateY(0);
  }
}
View Compiled
###global Modernizr:true ###
'use strict'

(($) ->
  $.fn.extend
    mgPgnation: (options) ->
      $this = $(this)

      if $this.length
        $mainNav = @children()
        $pgnNav = $this.find('.pgn__item')
        $curNav = $this.find('.current')
        $magicNav = $this.find('a')
        $prevNav = $this.find('.prev')
        $nextNav = $this.find('.next')
        $prevNavText = $prevNav.find('.pgn__prev-txt')

        ### func :: update prev text ###
        updatePrevText = ->
          $prevNavText = $prevNav.find('.pgn__prev-txt')
          $prevNavText.html 'Prev'

        ### func :: calculate width of each page num ###
        calPgnWidth = ->
          # number of visible <a> plus <strong class="current">
          vsbNav = $this.find('.pgn__item a:visible').length + 1
          vsbNavs = vsbNav + 2
          prevWidth = 100 / vsbNavs
          pgnWidth = 100 - prevWidth * 2
          $prevNav.css 'width', prevWidth + '%'
          $nextNav.css 'width', prevWidth + '%'
          $pgnNav.css 'width', pgnWidth + '%'
          # <a> and <strong>
          $pgnNav.find('a, strong').css 'width', 100 / vsbNav + '%'

        ### func :: calculate and display prev/next ###
        # 85px - display full text
        showPrevNext = ->
          prevNavWidth = $prevNav.innerWidth()

          if prevNavWidth > 100
            $this.addClass 'fullprevnext'

            # display Previous
            $prevNavText.html 'Previous'
          else if prevNavWidth < 101 and prevNavWidth > 60
            $this.addClass 'fullprevnext'

            # display Prev
            $prevNavText.html 'Prev'
          else
            $this.removeClass 'fullprevnext'

        ### func :: draw magic line ###
        magicDraw = ->
          # draw init magic line
          $magicLine.width($curNav.width())
          if $curNav.position() != undefined
            $magicLine.css 'left', $curNav.position().left
          
          # assign orig values
          $magicLine.data 'origLeft', $magicLine.position().left
          $magicLine.data 'origWidth', $magicLine.width()
        # END funcs
        
        # create magic line
        $mainNav.append('<li class="pgn__magic-line">')
        
        # declare magic line
        $magicLine = $this.find('.pgn__magic-line')

        # add extra class & element if no prev or next
        prevNavWidth = $prevNav.innerWidth()

        if prevNavWidth > 100
          prevText = 'Previous'
        else
          prevText = 'Prev'

        if !$prevNav.children().length
          $prevNav.addClass 'disabled'
          $prevNav.append '<a rel="prev"><i class="pgn__prev-icon icon-angle-left"></i><span class="pgn__prev-txt">' + prevText + '</span></a>'

        if !$nextNav.children().length
          $nextNav.addClass 'disabled'
          $nextNav.append '<a rel="next"><i class="pgn__next-icon icon-angle-right"></i><span class="pgn__next-txt">Next</span></a>'

        # calculate pgn width
        calPgnWidth()

        # show prev/next
        showPrevNext()

        # draw magic line
        magicDraw()
        
        # when hover
        $magicNav.hover (->
          $el = $(this)
          leftPos = $el.position().left
          newWidth = $el.width()
          
          # animate magic line
          $magicLine.stop().animate
            left: leftPos
            width: newWidth
        ), ->
          $magicLine.stop().animate
            left: $magicLine.data('origLeft')
            width: $magicLine.data('origWidth')
      
        ### Window Resize Changes ###
        window.addEventListener 'resize', ->
          updatePrevText()
          calPgnWidth()
          showPrevNext()
          magicDraw()
  # END mgPgnation()
      
  # call function here 
  $('.pgn').mgPgnation()

) jQuery
View Compiled

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