From our sponsor: Meco is a distraction-free space for reading and discovering newsletters, separate from the inbox.
A layout switch with two viewing modes: grid and list. The layout is defined by a view class that gets applied to the main wrapper. Some example media queries show how to make things responsive.
The HTML
<div id="cbp-vm" class="cbp-vm-switcher cbp-vm-view-grid"> <div class="cbp-vm-options"> <a href="#" class="cbp-vm-icon cbp-vm-grid cbp-vm-selected" data-view="cbp-vm-view-grid">Grid View</a> <a href="#" class="cbp-vm-icon cbp-vm-list" data-view="cbp-vm-view-list">List View</a> </div> <ul> <li> <a class="cbp-vm-image" href="#"><img src="images/1.png"></a> <h3 class="cbp-vm-title">Silver beet</h3> <div class="cbp-vm-price">$19.90</div> <div class="cbp-vm-details"> Silver beet shallot wakame tomatillo salsify mung bean beetroot groundnut. </div> <a class="cbp-vm-icon cbp-vm-add" href="#">Add to cart</a> </li> <li> <!-- ... --> </li> <!-- ... --> </ul> </div>
The CSS
@font-face { font-family: 'fontawesome'; src:url('../fonts/fontawesome/fontawesome.eot'); src:url('../fonts/fontawesome/fontawesome.eot?#iefix') format('embedded-opentype'), url('../fonts/fontawesome/fontawesome.woff') format('woff'), url('../fonts/fontawesome/fontawesome.ttf') format('truetype'), url('../fonts/fontawesome/fontawesome.svg#fontawesome') format('svg'); font-weight: normal; font-style: normal; } /* Main container */ .cbp-vm-switcher { padding: 20px; border: 3px solid #47a3da; } /* options/select wrapper with switch anchors */ .cbp-vm-options { text-align: right; padding-bottom: 10px; border-bottom: 3px solid #47a3da; } .cbp-vm-options a { display: inline-block; width: 40px; height: 40px; overflow: hidden; white-space: nowrap; color: #d0d0d0; margin: 2px; } .cbp-vm-options a:hover, .cbp-vm-options a.cbp-vm-selected { color: #47a3da; } .cbp-vm-options a:before { width: 40px; height: 40px; line-height: 40px; font-size: 30px; text-align: center; display: inline-block; } /* General style of switch items' list */ .cbp-vm-switcher ul { list-style: none; padding: 0; margin: 0; } /* Clear eventual floats */ .cbp-vm-switcher ul:before, .cbp-vm-switcher ul:after { content: " "; display: table; } .cbp-vm-switcher ul:after { clear: both; } .cbp-vm-switcher ul li { display: block; position: relative; } .cbp-vm-image { display: block; margin: 0 auto; } .cbp-vm-image img { display: inline-block; max-width: 100%; } .cbp-vm-title { margin: 0; padding: 0; } .cbp-vm-price { color: #c0c0c0; } .cbp-vm-add { color: #fff; background: #47a3da; padding: 10px 20px; border-radius: 2px; margin: 20px 0 0; display: inline-block; transition: background 0.2s; } .cbp-vm-add:hover { color: #fff; background: #02639d; } .cbp-vm-add:before { margin-right: 5px; } /* Common icon styles */ .cbp-vm-icon:before { font-family: 'fontawesome'; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; line-height: 1; -webkit-font-smoothing: antialiased; } .cbp-vm-grid:before { content: "f00a"; } .cbp-vm-list:before { content: "f00b"; } .cbp-vm-add:before { content: "f055"; } /* Individual view mode styles */ /* Large grid view */ .cbp-vm-view-grid ul { text-align: center; } .cbp-vm-view-grid ul li { width: 33%; text-align: center; padding: 25px; margin: 20px 0 0; display: inline-block; min-height: 420px; vertical-align: top; } .cbp-vm-view-grid .cbp-vm-title { font-size: 2em; } .cbp-vm-view-grid .cbp-vm-details { max-width: 300px; min-height: 70px; margin: 0 auto; } .cbp-vm-view-grid .cbp-vm-price { margin: 10px 0; font-size: 1.5em; } /* List view */ .cbp-vm-view-list li { padding: 20px 0; white-space: nowrap; } .cbp-vm-view-list .cbp-vm-image, .cbp-vm-view-list .cbp-vm-title, .cbp-vm-view-list .cbp-vm-details, .cbp-vm-view-list .cbp-vm-price, .cbp-vm-view-list .cbp-vm-add { display: inline-block; vertical-align: middle; } .cbp-vm-view-list .cbp-vm-image { width: 10%; } .cbp-vm-view-list .cbp-vm-title { font-size: 1.3em; padding: 0 10px; white-space: normal; width: 23%; } .cbp-vm-view-list .cbp-vm-price { font-size: 1.3em; width: 10%; } .cbp-vm-view-list .cbp-vm-details { width: 40%; padding: 0 15px; overflow: hidden; white-space: normal; } .cbp-vm-view-list .cbp-vm-add { margin: 0; } @media screen and (max-width: 66.7em) { .cbp-vm-view-list .cbp-vm-details { width: 30%; } } @media screen and (max-width: 57em) { .cbp-vm-view-grid ul li { width: 49%; } } @media screen and (max-width: 47.375em) { .cbp-vm-view-list .cbp-vm-image { width: 20%; } .cbp-vm-view-list .cbp-vm-title { width: auto; } .cbp-vm-view-list .cbp-vm-details { display: block; width: 100%; margin: 10px 0; } .cbp-vm-view-list .cbp-vm-add { margin: 10px; } } @media screen and (max-width: 40.125em) { .cbp-vm-view-grid ul li { width: 100%; } }
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
The JavaScript
/** * cbpViewModeSwitch.js v1.0.0 * http://www.codrops.com * * Licensed under the MIT license. * http://www.opensource.org/licenses/mit-license.php * * Copyright 2013, Codrops * http://www.codrops.com */ (function() { var container = document.getElementById( 'cbp-vm' ), optionSwitch = Array.prototype.slice.call( container.querySelectorAll( 'div.cbp-vm-options > a' ) ); function init() { optionSwitch.forEach( function( el, i ) { el.addEventListener( 'click', function( ev ) { ev.preventDefault(); _switch( this ); }, false ); } ); } function _switch( opt ) { // remove other view classes and any any selected option optionSwitch.forEach(function(el) { classie.remove( container, el.getAttribute( 'data-view' ) ); classie.remove( el, 'cbp-vm-selected' ); }); // add the view class for this option classie.add( container, opt.getAttribute( 'data-view' ) ); // this option stays selected classie.add( opt, 'cbp-vm-selected' ); } init(); })();
Don’t really have anything constructive to add. Just wanted to say I only found Codrops recently and totally love it (actually featured you guys in my last blog post)
Love the demos!
show de bola!
Check out BEM CSS syntax, makes my eyes go crazy looking at all these .cbp-* prefixes! BEM is for defining block, elements and modifiers and are descriptive to read, I think you could get lost easily here 🙂
I haven’t tried it yet and I’ve just looked a bit at the javascript so maybe I missed it, but is there an easy way to remember the choice of the specific user? I’d appreciate some pointers.
Indeed, great print. But how to remember the choice of an user ? With JS cookie maybe ?
how can I have multiple grids on one page . . . I couldn’t figure it out 🙁
Thanks.
It’s probably crude but this is how I got it to work . . . any help cleaning it up would be greatly appreciated.
I would like to see an option that would change all grids on a page in specified ids to be toggled by one control.
Cheers.
/**
* cbpViewModeSwitch.js v1.0.0
* http://www.codrops.com
*
* Licensed under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*
* Copyright 2013, Codrops
* http://www.codrops.com
*/
(function() {
var container = document.getElementById( ‘cbp-vm’ ),
container1 = document.getElementById( ‘cbp-vm1’ ),
optionSwitch = Array.prototype.slice.call( container.querySelectorAll( ‘div.cbp-vm-options > a’ ) ),
optionSwitch1 = Array.prototype.slice.call( container1.querySelectorAll( ‘div.cbp-vm-options > a’ ) );
function init() {
optionSwitch.forEach( function( el, i ) {
el.addEventListener( ‘click’, function( ev ) {
ev.preventDefault();
_switch( this );
}, false );
} );
}
function _switch( opt ) {
// remove other view classes and any any selected option
optionSwitch.forEach(function(el) {
classie.remove( container, el.getAttribute( ‘data-view’ ) );
classie.remove( el, ‘cbp-vm-selected’ );
});
// add the view class for this option
classie.add( container, opt.getAttribute( ‘data-view’ ) );
// this option stays selected
classie.add( opt, ‘cbp-vm-selected’ );
}
function init1() {
optionSwitch1.forEach( function( el1, i ) {
el1.addEventListener( ‘click’, function( ev1 ) {
ev1.preventDefault();
_switch1( this );
}, false );
} );
}
function _switch1( opt1 ) {
// remove other view classes and any any selected option
optionSwitch1.forEach(function(el1) {
classie.remove( container1, el1.getAttribute( ‘data-view’ ) );
classie.remove( el1, ‘cbp-vm-selected’ );
});
// add the view class for this option
classie.add( container1, opt1.getAttribute( ‘data-view’ ) );
// this option stays selected
classie.add( opt1, ‘cbp-vm-selected’ );
}
init();
init1();
})();
I love the functionality here but this conflicts with the different jQuery lightbox plugins I’ve tried.
Terry you could possibly rename the most part of the lightbox js or the view mode js variables so that they possibly wont conflict anymore, this happens a lot when combining multiple jquery files
and thanks for posting your extra work evan with the extra grids 🙂
I have to say MaryLou the minimal design on the demo is looking cool 🙂
Thank you very much. It’s so helpful.
Hi, i’m working with wordpres + woocommerce plugin,
i tried many tutorials on grid/list view, but each time i use products pagination
i lose my css class added by js, how can i remember settings when i change products page?