Easy Responsive Design: Thumbnail List

Create a list of thumbnail images that re-sizes according to screen width. Uses simple semantic HTML markup together with a bit of CSS3. Media queries can be used as a further enhancement to this technique.

Works with modern browsers including IE8+

HTML:

<ul class="thumbnail-list">
	<li><img src="http://placekitten.com/200/200" alt=""></li>
	<li><img src="http://placekitten.com/200/200" alt=""></li>
	<li><img src="http://placekitten.com/200/200" alt=""></li>
	<li><img src="http://placekitten.com/200/200" alt=""></li>
	<li><img src="http://placekitten.com/200/200" alt=""></li>
	<li><img src="http://placekitten.com/200/200" alt=""></li>
	<li><img src="http://placekitten.com/200/200" alt=""></li>
	<li><img src="http://placekitten.com/200/200" alt=""></li>
</ul>

CSS:

.thumbnail-list {
	/* remove default list styles */
	list-style: none;
	margin: 0;
	padding: 0;
	/* remove spaces between li tags*/
	font-size: 0;
}

.thumbnail-list li {
	display: inline-block;
	vertical-align: top;
	width: 33.333%;
	padding: 2%;
	-moz-box-sizing: border-box;
	-webkit-box-sizing: border-box;
	box-sizing: border-box;
}

.thumbnail-list img {
	display: block;
	width: 100%;
}

How it works

The first step to styling the unordered list (ul) is to remove default list styles. (If you are already including a CSS reset you can skip this part.) The thumbnail list items (li tags) which contain the images are lined up by displaying them as inline-blocks. Change the width to alter how many items line up in a row. Padding is used to space out the images. (This value can also be changed according to your preferences.) Finally, the CSS3 style “box-sizing” is set to “border-box” to prevent the padding from being added to the total width of the list items. (This allows the images to be spaced out evenly.)

Besides the CSS3 “border-box” style, the final key to making the design responsive is to set the image width to 100%. This ensures that the images always shrink and expand to occupy the full available width inside the li tags they are wrapped width. One disadvantage to making the width 100% is that the images can grow larger than the original sizes which may make them look pixelated. If you want to prevent this you can change “width” to “max-width”. This will still shrink images to fit smaller screens but will not expand them beyond their original size. (Setting the images to “display: block” just removes line-spacing so images will be evenly spaced vertically.)

Optional enhancement using Media Queries

Use media queries to change the number of thumbnails displayed in a row depending on screen orientation or width. Here’s an example of how you can customize the display to show more images in a row for the landscape view of mobile devices such as iPhone and Android.

Additional Optional CSS:

/* Landscape */
@media screen and (orientation:landscape) {
	/* show more in a row */
	.thumbnail-list li {
		width: 20%;
		padding: 2%;
	}
}

See it in action: http://www.webcodeshare.appspot.com/agx3ZWJjb2Rlc2hhcmVyDwsSB1dlYmNvZGUY0dwQDA

NOTE: This layout can actually be achieved without the CSS3 “border-box” style by using margins instead of padding to space apart list items and changing the value of the width + margin to equal the total space you want each item to occupy. For example to display 4 images in a row you would use: “width: 23%; margin: 1%;” which equals 25% in total since the margin gets added to both sides of the li tag.

CAVEAT: If you want to include text inside the li tags remember to set the font-size of the li to your desired value as by default it will inherit “font-size: 0” from the ul styles.

Advertisements

Unobtrusive jQuery Popups

A technique for creating accessible popups using simple semantic HTML and unobtrusive jQuery code.

Advantages

  • Popup content is still accessible when JavaScript is disabled.
  • Popup content is separate from main HTML document which makes adding new popups and linking from multiple pages simple.
  • Easy to use. Doesn’t rely on special classes, IDs or inline JavaScript events.
  • Popup content is loaded through a jQuery AJAX method so there is no page refresh.

HTML for Popup Links (add to your main HTML documents):

<a href="popups/help.html" target="_blank">View help popup</a>

To trigger display of popups you need only add an ordinary link such as above. This links to a separate html document for each popup. The file names for the popup documents can be whatever you like. The only thing to remember is to place all the popup documents into a separate “popups” directory.

Example HTML for Popup:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Help Popup</title>
</head>

<body>
<div id="popup-wrapper">
	<h2>Help</h2>
	<p>This is some helpful information.</p>
</div><!-- /#popup-wrapper -->
</body>
</html>

Within your “popups” directory simply add simple html documents such as above for each popup you wish to display. The only important thing here is that all the content within the body must be wrapped by a div with the id “popup-wrapper”.

Example CSS:

#greyscreen {
	background: #000;
	-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
	filter: alpha(opacity=50);
	-moz-opacity: .50;
	opacity: .50;
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
}

#popup {
	background: #FFF;
	border: 3px solid blue;
	padding: 10px;
	width: 300px;
	height: 350px;
	margin-top: -185px;
	margin-left: -160px;
	overflow: auto;
	position: fixed;
	top: 50%;
	left: 50%;
}

#popup .close {
	cursor: pointer;
	display: inline-block;
	float: right;
}

These are just basic styles for your popups to get you started. You can modify these to suit your particular site design.

(NOTE: IE6 doesn’t support “position: fixed”.)

jQuery Code:

$(document).ready(function() {
	// Unobtrusive Popups
	var $popup = $('<div id="popup"></div>');
	var $greyscreen = $('<div id="greyscreen"></div>');
	
	$popup.prependTo('body').hide();
	$greyscreen.prependTo('body').hide();
	
	$('a[href*=popups]').click(function() {
		$greyscreen.show();
		$popup
		 .fadeIn()
		 .load($(this).attr('href') + ' #popup-wrapper', function() {
		 	$('<span class="close">Close</span>').prependTo($popup);
		 });
		return false;
	});
	
	$greyscreen.click(function() {
		$popup.hide();
		$greyscreen.hide();
	});
	
	$('#popup .close').live('click', function() {
		$popup.hide();
		$greyscreen.hide();
	})
});

Make sure to link to the jQuery library from within the head of your main HTML document so the above code will work.

How it works

Two separate divs for a greyscreen effect and for the popup are created dynamically. These get appended to your main HTML document then are hidden until needed. The script then looks for all links pointing to files within the “popups” directory and attaches special actions when the links are clicked. When users click these links the popup and greyscreen divs are displayed and the popup content is loaded into the popup div. A close button also gets appended to the popup. (The reason for adding the close button using jQuery is because if JavaScript were turned off it would have no purpose.) Finally, actions are added to both the greyscreen div and the close button so that once clicked upon they will again hide the popup.

See it in action:

http://www.bentomaster.com/ Scroll down to the bottom of the page and click the “credits” link.

Expandable Content with jQuery and HTML5 Data Attribute

Using jQuery together with the new HTML5 data attribute and a bit of CSS you can create nice expandable / collapsible content items. This is useful for things such as lists of FAQ questions and answers in order to save space.

HTML Structure:

<div class="toggle-unit">
	<h2 class="toggle-control" data-text="What is the answer?" 
	data-expanded-text="You've found it!">What is the answer?</h2>
	<div class="toggle-content">
		This is the answer you are seeking.
	</div><!-- /.toggle-content -->
</div><!-- /.toggle.unit -->

The key items here are the class names “toggle-unit” then “toggle-control” and “toggle-content” which are contained inside it. The actual HTML tags used aren’t important so if you wished you could make “toggle-unit” into a list item inside of an ordered list for example. The order of the toggle-control and toggle-content can also be switched depending on how you want the content to appear when revealed.

The other items of note here are the two attributes within the toggle-control element, “data-text” and “data-expanded-text”. These are new HTML5 attributes for associating custom data with html elements. These are optional. You only need them if you would like the text within toggle-control to change once its associated content is expanded. (The idea for this nice little added technique comes from Collin Wikman.)

More Information on HTML5 Data Attribute: http://ejohn.org/blog/html-5-data-attributes/

jQuery Code:

$(document).ready(function() {
	$('.toggle-content').hide();

	$('.toggle-control')
	 .addClass('clickable')
	 .bind('click', function() {
		var $control = $(this);
		var $parent = $control.parents('.toggle-unit');

		$parent.toggleClass('expanded');
		$parent.find('.toggle-content').slideToggle();

		// if control has HTML5 data attributes, use to update text
		if ($parent.hasClass('expanded')) {
			$control.html($control.attr('data-expanded-text'));
		} else {
			$control.html($control.attr('data-text'));
		}
	})
});

The jQuery code is pretty straight forward. It is dependent only on the 3 toggle classnames being present as already explained. Two extra classnames are also added by the script itself. First, the toggle-content is hidden. Then, the toggle-control element gets the extra class “clickable”. This can be used to add styles in your CSS to indicate that the element will do something once clicked. Another classname, “expanded”, gets added to the containing toggle-unit element once a user clicks to expand the hidden content. This class can be used to add different styling to the elements depending on whether the content is currently expanded or not.

Optional CSS:

.clickable {cursor: pointer;}

Finally an example of simple CSS you can add to your stylesheet to let users know that the toggle-control is clickable. (The reason for using jQuery to add the “clickable” class is because with JavaScript disabled, all hidden content will be displayed so the toggle-control will no longer do anything once clicked.)

See it all in action: http://www.webcodeshare.appspot.com/agx3ZWJjb2Rlc2hhcmVyDwsSB1dlYmNvZGUY-b0IDA

Cross-browser CSS: Justified Block List

A cross-browser method using semantic markup and CSS to align list items horizontally and space them evenly so they are distributed across the full available width. Useful for laying out lists of thumbnail images or navigation links for example.

Tested in IE6, IE7, IE8, FF, Safari, Chrome

Fixed Width Content Using This Method:

Variable Width Content:

HTML:

<ul class="block-list">
     <li>Content</li>
     <li>Content</li>
<li>Content</li></ul>

CSS:

/* set base font-size (customize to suit) */
body, .block-list li {font-size: 12px;}

/* trigger hasLayout in IE */
.block-list, .block-list li {zoom: 1;}

.block-list {
	font-size: 0 !important; /* remove physical spaces between items */
	text-align: justify;
	text-justify: distribute-all-lines; /* distribute items in IE */
	list-style-type: none;
	margin: 0;
	padding: 0;
}

/* fully justify all items in browsers other than IE */
.block-list:after {
	content: "";
	display: inline-block;
	width: 100%;
}

.block-list li {
	text-align: left; /* customize to suit */
	vertical-align: top; /* can customize to suit */
	display: inline-block;
	width: 31.3%; /* optional, only need for text content to wrap */
	margin-bottom: 1em; /* optional, customize to suit */
}

/* IE hacks to make li's line up */
*+html .block-list li {display: inline;}
* html .block-list li {display: inline;}

IMPORTANT:
There must be no space between the last li tag and the closing ul tag in your HTML markup. This is to fix a bug in Safari so it won’t add extra space after the last list item.