View Mode Switch

A simple view mode switch that has two example layouts, a grid and a list.

BlueprintViewModeSwitch

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();

})();

Manoela Ilic

Manoela is the main tinkerer at Codrops. With a background in coding and passion for all things design, she creates web experiments and keeps frontend professionals informed about the latest trends.

Stay in the loop: Get your dose of frontend twice a week

👾 Hey! Looking for the latest in frontend? Twice a week, we'll deliver the freshest frontend news, website inspo, cool code demos, videos and UI animations right to your inbox.

Zero fluff, all quality, to make your Mondays and Thursdays more creative!

Feedback 11

Comments are closed.
  1. 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!

  2. 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 🙂

  3. 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.

  4. Indeed, great print. But how to remember the choice of an user ? With JS cookie maybe ?

    • 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();

      })();

  5. I love the functionality here but this conflicts with the different jQuery lightbox plugins I’ve tried.

  6. 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 🙂

  7. 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?