The HTML
<!-- Bottom bar with filter and cart info -->
<div class="bar">
<div class="filter">
<span class="filter__label">Filter: </span>
<button class="action filter__item filter__item--selected" data-filter="*">All</button>
<button class="action filter__item" data-filter=".jackets">
<i class="icon icon--jacket"></i>
<span class="action__text">Jackets</span>
</button>
<button class="action filter__item" data-filter=".shirts">
<i class="icon icon--shirt"></i>
<span class="action__text">Shirts</span>
</button>
<button class="action filter__item" data-filter=".dresses">
<i class="icon icon--dress"></i>
<span class="action__text">Dresses</span>
</button>
<button class="action filter__item" data-filter=".trousers">
<i class="icon icon--trousers"></i>
<span class="action__text">Trousers</span>
</button>
<button class="action filter__item" data-filter=".shoes">
<i class="icon icon--shoe"></i>
<span class="action__text">Shoes</span>
</button>
</div>
<button class="cart">
<i class="cart__icon fa fa-shopping-cart"></i>
<span class="text-hidden">Shopping cart</span>
<span class="cart__count">0</span>
</button>
</div>
<!-- Main view -->
<div class="view">
<!-- Grid -->
<section class="grid">
<!-- Loader -->
<img class="grid__loader" src="images/grid.svg" width="60" alt="Loader image" />
<!-- Grid sizer for a fluid Isotope (Masonry) layout -->
<div class="grid__sizer"></div>
<!-- Grid items -->
<div class="grid__item shirts">
<div class="slider">
<div class="slider__item"><img src="images/product1/1.png" alt="product1_1" /></div>
<div class="slider__item"><img src="images/product1/2.png" alt="product1_2" /></div>
<div class="slider__item"><img src="images/product1/3.png" alt="product1_3" /></div>
</div>
<div class="meta">
<h3 class="meta__title">Miriam Classic</h3>
<span class="meta__brand">Miriam</span>
<span class="meta__price">$79</span>
</div>
<button class="action action--button action--buy">
<i class="fa fa-shopping-cart"></i>
<span class="text-hidden">Add to cart</span>
</button>
</div>
<div class="grid__item grid__item--size-a jackets">
<!-- ... -->
</div>
<div class="grid__item shoes">
<!-- ... -->
</div>
<div class="grid__item dresses">
<!-- ... -->
</div>
<div class="grid__item trousers">
<!-- ... -->
</div>
</section>
<!-- /grid-->
</div>
<!-- /view -->
<script src="js/isotope.pkgd.min.js"></script>
<script src="js/flickity.pkgd.min.js"></script>
<script src="js/main.js"></script>
The CSS
/* Product grid */
.grid {
position: relative;
overflow: hidden;
max-width: 1300px;
margin: 0 auto;
padding: 1.5em 0 8em;
text-align: center;
}
/* Loader */
.grid__loader {
display: none;
margin: 3em auto 0;
}
.grid--loading .grid__loader {
display: block;
}
/* Clearfix */
.grid:after {
content: '';
display: block;
clear: both;
}
/* Grid items */
.grid__sizer,
.grid__item {
position: relative;
float: left;
width: 20%;
padding: .75em;
}
.no-touch .grid__sizer,
.no-touch .grid__item {
padding: .75em .75em 1.25em;
}
.grid--loading .grid__item {
visibility: hidden;
}
.grid__item--size-a {
width: 40%;
}
/* Gallery */
.slider {
padding: 0;
border-radius: 5px;
background: #24252a;
}
.no-touch .slider {
padding: 0 0 1.25em;
}
.slider__item {
width: 100%;
padding: 1em;
}
.slider__item img {
width: 100%;
}
/* Flickity page dots */
.slider .flickity-page-dots {
bottom: 20px;
opacity: 0;
-webkit-transition: opacity .3s;
transition: opacity .3s;
}
.no-touch .slider:hover .flickity-page-dots {
opacity: 1;
}
.slider .flickity-page-dots .dot {
background: #131417;
}
/* Product meta */
.meta {
position: relative;
margin: 10px 0 0;
padding: 0 60px 0 0;
text-align: left;
}
.meta__brand {
font-size: .85em;
font-weight: bold;
display: block;
color: #595b64;
}
.meta__title {
font-size: .95em;
font-weight: bold;
margin: 0;
padding: .4em 0 .1em;
}
.meta__price {
font-size: .95em;
font-weight: bold;
position: absolute;
top: .45em;
right: .25em;
color: #595b64;
}
/* Action style */
.action {
font-family: Avenir, 'Helvetica Neue', 'Lato', 'Segoe UI', Helvetica, Arial, sans-serif;
font-size: 1.05em;
position: relative;
overflow: hidden;
margin: 0;
padding: .25em;
cursor: pointer;
color: #fff;
border: none;
background: none;
}
.action:focus {
outline: none;
}
.action--button {
color: #5c5edc;
}
.no-touch .action--button:hover {
color: #fff;
outline: none;
}
.text-hidden {
position: absolute;
top: 200%;
}
/* Add to cart button */
.action--buy {
position: absolute;
top: 0;
right: 0;
padding: 1.85em 2.35em;
-webkit-transition: opacity .3s, -webkit-transform .3s;
transition: opacity .3s, transform .3s;
-webkit-transform: translate3d(-5px, 0, 0);
transform: translate3d(-5px, 0, 0);
}
.no-touch .action--buy {
opacity: 0;
}
.no-touch .grid__item:hover .action--buy {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
/* Fixed bottom bar */
.bar {
position: fixed;
z-index: 100;
bottom: 0;
left: 0;
width: 100%;
padding: 1.75em 5em;
text-align: center;
background: #191a1b;
-webkit-transform: translate3d(0, 0, 0);
/* Fix for Chrome flicker on Mac ...party like we're in 2012! */
}
.flexbox .filter {
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
}
/* Filter */
.filter__label {
font-size: .85em;
display: inline-block;
margin: 0 2%;
font-weight: bold;
color: #393A3F;
}
.filter__item {
font-weight: bold;
margin: 0 2%;
padding: .1em;
vertical-align: middle;
color: #a3a3b3;
border-bottom: 2px solid transparent;
}
.filter__item--selected {
color: #5c5edc;
border-color: #5c5edc;
}
.filter__item .icon {
font-size: 1.75em;
display: none;
}
/* Shopping cart */
.cart {
font-size: 1.5em;
position: absolute;
top: 0;
right: 0;
overflow: hidden;
height: 100%;
padding: 0 1.195em;
cursor: pointer;
color: #abacae;
border: none;
background-color: #131415;
}
.no-touch .cart:focus,
.no-touch .cart:hover {
color: #fff;
outline: none;
}
.cart--animate .cart__icon {
-webkit-animation: cartAnim .4s forwards;
animation: cartAnim .4s forwards;
}
@-webkit-keyframes cartAnim {
50% {
opacity: 0;
-webkit-transform: translate3d(50px, 0, 0);
transform: translate3d(50px, 0, 0);
}
51% {
opacity: 0;
-webkit-transform: translate3d(-50px, 0, 0);
transform: translate3d(-50px, 0, 0);
}
100% {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes cartAnim {
50% {
opacity: 0;
-webkit-transform: translate3d(50px, 0, 0);
transform: translate3d(50px, 0, 0);
}
51% {
opacity: 0;
-webkit-transform: translate3d(-50px, 0, 0);
transform: translate3d(-50px, 0, 0);
}
100% {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
.cart__count {
font-size: 9px;
font-weight: bold;
line-height: 15px;
position: absolute;
top: 50%;
right: 20px;
width: 15px;
height: 15px;
margin: -16px 0 0 0;
text-align: center;
color: #fff;
border-radius: 50%;
background: #5c5edc;
}
.cart--animate .cart__count {
-webkit-animation: countAnim .4s forwards;
animation: countAnim .4s forwards;
}
@-webkit-keyframes countAnim {
50% {
opacity: 0;
-webkit-transform: translate3d(0, 80px, 0);
transform: translate3d(0, 80px, 0);
}
51% {
opacity: 0;
-webkit-transform: translate3d(0, -80px, 0);
transform: translate3d(0, -80px, 0);
}
100% {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes countAnim {
50% {
opacity: 0;
-webkit-transform: translate3d(0, 80px, 0);
transform: translate3d(0, 80px, 0);
}
51% {
opacity: 0;
-webkit-transform: translate3d(0, -80px, 0);
transform: translate3d(0, -80px, 0);
}
100% {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
/* Resize grid items on smaller screens */
@media screen and (max-width: 65em) {
.grid__sizer,
.grid__item,
.grid__item--size-a {
width: 33.333%;
}
}
@media screen and (max-width: 50em) {
.grid__sizer,
.grid__item,
.grid__item--size-a {
width: 50%;
}
.bar {
padding-left: 0;
text-align: left;
}
}
@media screen and (max-width: 40em) {
.bar {
padding: .5em 4.5em .5em 0;
}
.flexbox .filter {
-webkit-justify-content: space-around;
justify-content: space-around;
}
.filter__item {
height: 100%;
padding: .5em .1em;
border: none;
}
.filter__item .icon {
display: inline-block;
}
.filter__label,
.action__text {
display: none;
}
.cart {
padding: 0 1em;
}
}
@media screen and (max-width: 25em) {
.grid {
max-width: 75%;
}
.grid__loader {
margin: 0 auto;
}
.grid__sizer,
.grid__item,
.grid__item--size-a {
width: 100%;
}
.action--buy {
font-size: 1.5em;
padding: 1.15em 1.5em;
-webkit-tap-highlight-color: transparent;
}
}
The JavaScript
/**
* main.js
* http://www.codrops.com
*
* Licensed under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*
* Copyright 2015, Codrops
* http://www.codrops.com
*/
;(function(window) {
'use strict';
var support = { animations : Modernizr.cssanimations },
animEndEventNames = { 'WebkitAnimation' : 'webkitAnimationEnd', 'OAnimation' : 'oAnimationEnd', 'msAnimation' : 'MSAnimationEnd', 'animation' : 'animationend' },
animEndEventName = animEndEventNames[ Modernizr.prefixed( 'animation' ) ],
onEndAnimation = function( el, callback ) {
var onEndCallbackFn = function( ev ) {
if( support.animations ) {
if( ev.target != this ) return;
this.removeEventListener( animEndEventName, onEndCallbackFn );
}
if( callback && typeof callback === 'function' ) { callback.call(); }
};
if( support.animations ) {
el.addEventListener( animEndEventName, onEndCallbackFn );
}
else {
onEndCallbackFn();
}
};
// from http://www.sberry.me/articles/javascript-event-throttling-debouncing
function throttle(fn, delay) {
var allowSample = true;
return function(e) {
if (allowSample) {
allowSample = false;
setTimeout(function() { allowSample = true; }, delay);
fn(e);
}
};
}
// sliders - flickity
var sliders = [].slice.call(document.querySelectorAll('.slider')),
// array where the flickity instances are going to be stored
flkties = [],
// grid element
grid = document.querySelector('.grid'),
// isotope instance
iso,
// filter ctrls
filterCtrls = [].slice.call(document.querySelectorAll('.filter > button')),
// cart
cart = document.querySelector('.cart'),
cartItems = cart.querySelector('.cart__count');
function init() {
// preload images
imagesLoaded(grid, function() {
initFlickity();
initIsotope();
initEvents();
classie.remove(grid, 'grid--loading');
});
}
function initFlickity() {
sliders.forEach(function(slider){
var flkty = new Flickity(slider, {
prevNextButtons: false,
wrapAround: true,
cellAlign: 'left',
contain: true,
resize: false
});
// store flickity instances
flkties.push(flkty);
});
}
function initIsotope() {
iso = new Isotope( grid, {
isResizeBound: false,
itemSelector: '.grid__item',
percentPosition: true,
masonry: {
// use outer width of grid-sizer for columnWidth
columnWidth: '.grid__sizer'
},
transitionDuration: '0.6s'
});
}
function initEvents() {
filterCtrls.forEach(function(filterCtrl) {
filterCtrl.addEventListener('click', function() {
classie.remove(filterCtrl.parentNode.querySelector('.filter__item--selected'), 'filter__item--selected');
classie.add(filterCtrl, 'filter__item--selected');
iso.arrange({
filter: filterCtrl.getAttribute('data-filter')
});
recalcFlickities();
iso.layout();
});
});
// window resize / recalculate sizes for both flickity and isotope/masonry layouts
window.addEventListener('resize', throttle(function(ev) {
recalcFlickities()
iso.layout();
}, 50));
// add to cart
[].slice.call(grid.querySelectorAll('.grid__item')).forEach(function(item) {
item.querySelector('.action--buy').addEventListener('click', addToCart);
});
}
function addToCart() {
classie.add(cart, 'cart--animate');
setTimeout(function() {cartItems.innerHTML = Number(cartItems.innerHTML) + 1;}, 200);
onEndAnimation(cartItems, function() {
classie.remove(cart, 'cart--animate');
});
}
function recalcFlickities() {
for(var i = 0, len = flkties.length; i < len; ++i) {
flkties[i].resize();
}
}
init();
})(window);
This Blueprint is page navigation effect based on the Dribbble shot Stacked navigation
by Ilya Kostin. The idea is to show a navigation when clicking on the
menu button and transform all pages in 3D and move them to the bottom of
the viewport. The next two pages are shown in the back of the current
page as a stack. When clicking on a menu item, the respective page comes
up.
1.Demo 2.Download Source
EmoticonEmoticon