<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
This Pen doesn't use any external CSS resources.