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.

Cross-browser CSS: Justify last line of text in a paragraph

UPDATE: Just posted a new simplified technique but unfortunately it only works in Firefox so far, not Chrome: https://kristinlbradley.wordpress.com/2014/07/29/improved-justify-last-line-paragraph-text/


Original Method:
Normally if you use CSS to justify text, the last line of text is aligned left rather than justified as on other lines. This is the desired behavior in most instances but for some layouts you may want to justify the last line as text as well. Following is a cross-browser method you can use which will work in IE6+ in addition to popular modern browsers. (This method is also useful if you want to justify just one line of text such as in a heading.)

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

Regular Justified Text vs. Text Using This Method:

CSS:

p, h1 {
	text-align: justify;
	text-align-last: justify;
}

p:after, h1:after {
	content: "";
	display: inline-block;
	width: 100%;
}

A paragraph tag (p) and a header (h1) are used above just as examples. You can substitute any block level html elements instead such as a div.

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

Caveat: One issue with this method is that extra space is added to the bottom of html elements in browsers other than IE. It appears to happen as a result of how line-height spacing is added by browsers to the last visible line of text.

Update: You can add a negative bottom margin to the elements you are justifying (such as “margin-bottom: -1.2em;”) to remove extra spacing added by :after. You will need to add a margin back for IE.

An Experiment: WIRED on iPad, Recreated in HTML5 & CSS3

In May 2010, WIRED released the iPad edition of WIRED magazine. Currently each edition is produced using Adobe InDesign.

I decided to see if I could re-create a few of the page layouts from the “iPad Edition Free Preview” included with WIRED’s app using semantic HTML5 and CSS3.

So far I have re-created the “From the Editor” column on the first page which has a fairly simple layout. (Later, if I have time I plan to tackle the second page article which has a more complex column layout.)

Since I don’t own copies of any of the fonts WIRED uses, I made do with a couple somewhat similar but much less nice-looking fonts from Google Web Fonts.

Screen Shots of HTML5 / CSS3 Layouts:
horizontal view vertical view

View live in a new window.

(To toggle between horizontal and vertical views, click the little page icon at the top of the screen.)

NOTE: Since these layouts are intended for view within iPad, they were tested only in Safari and Firefox browsers.

(Magazine page designs, WIRED logo and WIRED magazine cover image copyright by WIRED.)