<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>kabayview.com</title>
	<atom:link href="http://www.kabayview.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.kabayview.com</link>
	<description>A Web Design &#38; Development Reference Archive</description>
	<lastBuildDate>Mon, 09 Jan 2012 19:50:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Six CSS Layout Features To Look Forward To</title>
		<link>http://www.kabayview.com/css3/six-css-layout-features-to-look-forward-to</link>
		<comments>http://www.kabayview.com/css3/six-css-layout-features-to-look-forward-to#comments</comments>
		<pubDate>Mon, 09 Jan 2012 19:48:51 +0000</pubDate>
		<dc:creator>Lynda Damiata</dc:creator>
				<category><![CDATA[CSS3]]></category>

		<guid isPermaLink="false">http://www.kabayview.com/?p=1171</guid>
		<description><![CDATA[By Divya Manian &#124; December 15th, 2011 &#124; smashingmagazine.com :: A few concerns keep bobbing up now and then for Web developers, one of which relates to how to lay out a given design. Developers have made numerous attempts to do so with existing solutions. Several articles have been written on finding the holy grail <a href='http://www.kabayview.com/css3/six-css-layout-features-to-look-forward-to'> [read more]</a>]]></description>
			<content:encoded><![CDATA[<p>By <a title="Posts by Divya Manian" href="http://coding.smashingmagazine.com/author/divya-manian/" rel="author">Divya Manian</a> | December 15th, 2011 |<br />
<a href="http://smashingmagazine.com/" target="_blank">smashingmagazine.com</a> ::</p>
<p>A few concerns keep bobbing up now and then for Web developers, one of which relates to how to lay out a given design. Developers have made numerous attempts to do so with existing solutions. Several articles have been written on finding the <a href="http://www.alistapart.com/articles/holygrail/">holy grail of CSS layouts</a>, but to date, not a single solution works without major caveats. At the <a href="http://w3conf.org/">W3Conf</a>, I gave a talk on how the CSS Working Group is attempting to solve the concerns of Web developers with multiple proposals. There are six layout proposals that are relevant to us, all of which I described in the talk:</p>
<p><iframe src="http://www.youtube.com/embed/Y_o0Lv_Mhbw" frameborder="0" width="560" height="315"></iframe></p>
<p>Here is a little more about these proposals and how they will help you in developing websites in the future.</p>
<h3 id="generated_content_for_paged_media">Generated Content For Paged Media</h3>
<ul>
<li><a href="http://dev.w3.org/csswg/css3-gcpm/">W3C Editor’s Draft</a></li>
<li><a href="http://people.opera.com/howcome/2011/reader/">Demo</a></li>
<li>Browser support: Opera Labs Build only</li>
</ul>
<p>This proposal outlines a set of features that would modify the contents of any element to flow as pages, like in a book. A <a href="http://www.youtube.com/watch?v=e_xpbQHtVGE">video demonstration</a> shows how to use paged media to generate HTML5 slideshows (look at the <a href="http://people.opera.com/divyam/pagedcontent/">demos for GCPM</a> in the <a href="http://people.opera.com/howcome/2011/reader/">Opera Labs Build</a> to play with the features more). To make the content of an element be paged, you would use this syntax:</p>
<pre>@media paged {
html {
width: 100%;
overflow-style: paged-x;
padding: 5%;
height: 100%;
box-sizing: border-box;
}
}</pre>
<p>This would make the content look something like this:</p>
<p><img class="aligncenter size-full wp-image-1174" title="layout feature" src="http://www.kabayview.com/wp-content/uploads/2012/01/layout-feature.png" alt="" width="518" height="393" /></p>
<p>Here, <code>@media paged</code> indicates that the browser understands paged media and that all of the selectors specified for it should have their styles applied when paged media is supported. Then, you indicate which selector you want to be paged (in the above example, the selector is the <code>html</code> element itself) by specifying the property <code>overflow-style: paged-x</code>. This will simply make the content paged; if you want paged controls to be visible, you need to specify <code>overflow-style: paged-x-controls</code>.</p>
<p>The properties <code>break-before</code>, <code>break-after</code> <code>break-inside</code> can be used to control where the content falls within the pages. For example, if you want headings to only appear with their corresponding content and never at the end of the page or standing alone, you can specify that:</p>
<pre>h3, h2 {
break-after: avoid;
}</pre>
<p>This ensures that if a heading occurs on the last line of a page, it will be pushed to the next page with the content that it introduces.</p>
<h4 id="api">API</h4>
<p>Two properties are available on an element whose content is paged: <code>currentPage</code> and <code>pageCount</code>. You can set the <code>currentPage</code> property via JavaScript, which would trigger a page change on that element. This would then trigger an <code>onpagechange</code> event on that element, which you could use to run other scripts that are required when the page changes. The <code>pageCount</code> property stores the total number of pages in the paged element. These properties are useful for implementing callbacks that should be triggered on page change; for example, to render notes for a particular slide in a slide deck.</p>
<h3 id="multiple_columns">Multiple Columns</h3>
<ul>
<li><a href="http://dev.w3.org/csswg/css3-multicol/">W3C Editor’s Draft</a></li>
<li><a href="http://people.opera.com/pepelsbey/experiments/multicol/">Demo</a></li>
<li>Browser support: Opera 11.1+, Firefox 2+, Chrome 4+, Safari 3.1+, IE 10+</li>
</ul>
<p>Multiple columns are now available in most browsers (including IE10!), which makes them pretty much ready to use on production websites. You can render the content of any element into multiple columns simply by using <code>column-width: &lt;length unit&gt;</code> or <code>column-count: &lt;number&gt;</code>. As with paged content, you can use <code>break-before</code>, <code>break-after</code> or <code>break-inside</code> to control how the content displays within each column. You can also make one of the child elements span the whole set of columns by using <code>column-span: all</code>. Here is how that would look:</p>
<p><img class="aligncenter size-large wp-image-1176" title="column-span-all" src="http://www.kabayview.com/wp-content/uploads/2012/01/column-span-all-1024x626.png" alt="" width="695" height="424" /></p>
<p>Columns are balanced out with content by default. If you would prefer that columns not be balanced, you can set that by using <code>column-fill: auto</code> property. Here is an example of the default behaviour (i.e. <code>column-fill: balanced</code>):</p>
<p><img class="aligncenter size-full wp-image-1177" title="column-fill-auto" src="http://www.kabayview.com/wp-content/uploads/2012/01/column-fill-auto.png" alt="column fill automatic" width="742" height="278" /></p>
<p>Note that the last column is empty, and each column is filled one after the other.</p>
<h3 id="regions">Regions</h3>
<ul>
<li><a href="http://dev.w3.org/csswg/css3-regions/">W3C Editor’s Draft</a></li>
<li><a href="http://ie.microsoft.com/testdrive/Graphics/hands-on-css3/hands-on_regions.htm">Demo</a></li>
<li>Browser support: IE 10+, Chrome 15+, Safari 6+</li>
</ul>
<p>The closest equivalent to regions would be <a href="http://www.creativepro.com/article/on-the-move-to-indesign-linking-two-text-frames">InDesign’s linking of text frames</a>. With the properties in this proposal, you can make the content of selected elements flow through another set of elements. In other words, your content need not be tied to the document flow any longer.</p>
<p>To begin, you need to select elements whose content will be part of a “named flow,” like this:</p>
<pre>article.news { flow-into: article_flow; }</pre>
<p>Here, all of the content in the <code>article</code> element with the class name <code>news</code> will belong to the flow named <code>article_flow</code>.</p>
<p>Then, you select elements that will render the contents that are part of this named flow:</p>
<pre>#main {
flow-from: article_flow;
}</pre>
<p>Here, the element with the ID <code>main</code> will be used to display the content in the flow named <code>article_flow</code>. This element has now become a region that renders the content of a named flow. Note that any element that is a region establishes new “block-formatting contexts” and “stacking contexts.” For example, if a child element is part of a flow and is absolutely positioned, it will now only be absolutely positioned with respect to the region it belongs to, and not to the whole viewport.</p>
<p>You can also tweak the styles of content that flows through a region:</p>
<pre>@region #main {
p { color: indianred; }
}</pre>
<p><img class="aligncenter size-full wp-image-1180" title="region-styling" src="http://www.kabayview.com/wp-content/uploads/2012/01/region-styling.png" alt="region styling" width="613" height="415" /></p>
<h4 id="interface-api">API</h4>
<p>An interface named <code>getNamedFlow</code> and an event named <code>regionLayoutUpdate</code> are available for elements that are regions.</p>
<h4 id="getnamedflow">getNamedFlow</h4>
<p>This returns the flow that that particular region is associated with. The properties available are:</p>
<ul>
<li><code>overflow</code>A read-only boolean that tells you whether all of the content of the named flow fits within the regions that are part of the flow or whether it overflows.</li>
<li><code>contentNodes</code>A NodeList of all the content elements that belong to the flow.</li>
<li><code>getRegionsByContentNode</code>This returns all of the regions that a particular content element would flow through. A very long paragraph might flow through more than one region; with this method, you can retrieve all of the regions that that paragraph element flows through.</li>
<li><code>regionLayoutUpdate</code>This event gets triggered every time an update is made to the layout of a region. If the region’s dimensions are altered, then the child content elements that are part of that region might alter, too (for example, a few might move to another region, or more child elements might become part of the region).</li>
</ul>
<h3 id="exclusions">Exclusions</h3>
<ul>
<li><a href="http://dev.w3.org/csswg/css3-exclusions/">Draft specification</a> (a combination of two proposals: “Exclusions” and “Positioned Floats”)</li>
<li><a href="http://ie.microsoft.com/testdrive/Graphics/hands-on-css3/hands-on_positionedfloats.htm">Demo</a></li>
<li>Browser support: IE 10+</li>
</ul>
<p>Exclusions allow inline content to be wrapped around or within custom shapes using CSS properties. An element becomes an “exclusion element” when <code>wrap-flow</code> is set to a value that is not <code>auto</code>. It can then set the “wrapping area” for inline text outside or within it, according to various CSS properties. The <code>wrap-flow</code> can take the following values: <code>left</code>, <code>right</code>, <code>maximum</code>,<code>both</code>, <code>clear</code> or the default value of <code>auto</code>. Here is how each of these values would affect the inline content around the exclusion element:</p>
<p><img class="aligncenter size-full wp-image-1182" title="exclusion_wrap_side_auto" src="http://www.kabayview.com/wp-content/uploads/2012/01/exclusion_wrap_side_auto.png" alt="exclusion wrap side auto" width="429" height="342" /></p>
<p><em><code>wrap-flow: auto</code></em></p>
<p><img class="aligncenter size-full wp-image-1181" title="exclusion_wrap_side_right" src="http://www.kabayview.com/wp-content/uploads/2012/01/exclusion_wrap_side_right.png" alt="exclusion wrap side right" width="426" height="347" /></p>
<p><em><code>wrap-flow: right</code></em></p>
<p><img class="aligncenter size-full wp-image-1183" title="exclusion_wrap_side_both" src="http://www.kabayview.com/wp-content/uploads/2012/01/exclusion_wrap_side_both.png" alt="exclusion wrap side both" width="443" height="345" /></p>
<p><em><code>wrap-flow: both</code></em></p>
<p><img class="aligncenter size-full wp-image-1184" title="exclusion_wrap_side_clear" src="http://www.kabayview.com/wp-content/uploads/2012/01/exclusion_wrap_side_clear.png" alt="exclusion wrap side clear" width="425" height="335" /></p>
<p><em><code>wrap-flow: clear</code></em></p>
<p><img class="aligncenter size-full wp-image-1185" title="exclusion_wrap_side_maximum_L" src="http://www.kabayview.com/wp-content/uploads/2012/01/exclusion_wrap_side_maximum_L.png" alt="exclusion wrap side maximum L" width="426" height="348" /></p>
<p><em><code>wrap-flow: maximum</code></em></p>
<p>The <code>wrap-margin</code> property can be used to offset the space between the boundary of the exclusion element and the inline text <em>outside</em> of it. The <code>wrap-padding</code> property is used to offset the space between the boundary of the exclusion element and the inline text <em>inside</em> it.</p>
<p><img class="aligncenter size-full wp-image-1186" title="exclusions_padding_margin" src="http://www.kabayview.com/wp-content/uploads/2012/01/exclusions_padding_margin.png" alt="exclusion padding margin" width="372" height="301" /></p>
<p>In the above image, the space between the content outside of the red dashed circular border and the black text outside of it is determined by the <code>wrap-margin</code>, while the space between the red dashed circular border and the blue text within it is determined by the <code>wrap-padding</code>.</p>
<p>Now comes the fun part: specifying custom shapes for the wrapping area. You can use two properties: <code>shape-outside</code> lets you set the wrapping area for inline text outside of the exclusion element, while <code>shape-inside</code> lets you set the wrapping area for inline text inside the exclusion element.</p>
<p><img class="aligncenter size-full wp-image-1187" title="exclusions-shapes" src="http://www.kabayview.com/wp-content/uploads/2012/01/exclusions-shapes.png" alt="exclusion shapes" width="478" height="399" /></p>
<p>Both of these properties can take SVG-like syntax (<code>circle(50%, 50%, 100px);</code>) or image URLs to set the wrapping area.</p>
<p>Exclusions make magazine-like layouts on the Web a trivial matter and could spark the kind of creative use of content that we are used to seeing in print!</p>
<h3 id="grid">Grid</h3>
<ul>
<li><a href="http://dev.w3.org/csswg/css3-grid-align/">W3C Editor’s Draft</a></li>
<li><a href="http://ie.microsoft.com/testdrive/Graphics/hands-on-css3/hands-on_grid.htm">Demo</a></li>
<li>Browser support: IE 10+</li>
</ul>
<p>Grid properties allow you to throw block-level elements into a grid cell, irrespective of the flow of content within the grid parent element. An element becomes a grid when <code>display</code> is set to <code>grid</code>. You can then set the number of columns and rows with the <code>grid-columns</code> and <code>grid-rows</code> properties, respectively. You can then declare each child selector itself as part of a grid cell, like so:</p>
<pre>#title {
grid-column: 1; grid-row: 1;
}
#score {    grid-column: 2; grid-row: 1;
}</pre>
<p>You can also use a template to plan the grid:</p>
<pre>body {
grid-template: "ta"
"sa"
"bb"
"cc";
}</pre>
<p>In this syntax, each string refers to a row, and each character refers to a grid cell. In this case, the content of grid cell represented by the character <code>a</code> spans two rows but just one column, and the content represented by <code>b</code> spans two columns but just one row.</p>
<p>Now you can set any of the child element’s <code>grid-cell</code> position:</p>
<pre>#title {
grid-cell: 't';
}</pre>
<p>This will make the element with the ID <code>title</code> within the body element to be positioned in the grid cell represented by the character <code>t</code> in the <code>grid-template</code> property.</p>
<p>If you are not using <code>grid-template</code>, you can also declare how many columns or rows a particular element should occupy with the <code>grid-row-span</code> and <code>grid-column-span</code> properties.</p>
<h3 id="flexbox">Flexbox</h3>
<ul>
<li><a href="http://dev.w3.org/csswg/css3-flexbox/">W3C Editor’s Draft</a></li>
<li><a href="http://ie.microsoft.com/testdrive/html5/griddle/default.html">Demo</a></li>
<li>Browser support: WebKit Nightlies</li>
</ul>
<p>Flexbox allows you to distribute child elements anywhere in the box (giving us the much-needed vertical centering), along with flexible units that let you control the fluidity of the child elements’ dimensions.</p>
<p>Note that this specification has changed substantially since it was first proposed. Previously, you would invoke Flexbox for an element with <code>display: box</code>, but now you would use <code>display: Flexbox</code> to do so. Child elements can be vertically aligned to the center with <code>flex-pack: center</code> and horizontally aligned to the center with <code>flex-align: center</code>. Also note that all elements that obey the Flexbox need to be block-level elements.</p>
<h3 id="how_do_various_properties_interact_with_each_other">How Do Various Properties Interact With Each Other?</h3>
<p>You might wonder how to use these properties in combination. The following table shows which of these features can be combined.</p>
<table>
<thead>
<tr>
<th></th>
<th>Paged Media</th>
<th>Multiple Columns</th>
<th>Regions</th>
<th>Exclusions</th>
<th>Grid</th>
<th>Flexbox</th>
</tr>
</thead>
<tbody>
<tr>
<th>Paged Media</th>
<td>✓</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th>Multiple Columns</th>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td></td>
<td></td>
</tr>
<tr>
<th>Regions</th>
<td></td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td></td>
<td></td>
</tr>
<tr>
<th>Exclusions</th>
<td></td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td></td>
<td></td>
</tr>
<tr>
<th>Grid</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td>✓</td>
<td></td>
</tr>
<tr>
<th>Flexbox</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>✓</td>
</tr>
</tbody>
</table>
<p>As you can see, the multiple-column properties can be used in conjunction with generated content for paged media, regions and exclusions. <del>But grid, Flexbox and regions are mutually exclusive (i.e. if an element is a grid, it cannot be a Flexbox or region).</del> Do note that, as <a href="http://coding.smashingmagazine.com/2011/12/15/six-css-layout-features-to-look-forward-to/#comment-562612">Alan Stearns says in the comments</a>, while a grid container cannot be a Flexbox or a region, a grid cell could become a region, or a Flexbox child item could be a region.</p>
<h4 id="a_note_before_you_rush_out_to_use_them_in_your_client_projects">A Note Before You Rush Out To Use Them In Client Projects</h4>
<p>The specifications are always changing, so be careful with them. Except for multiple columns, I would recommend using these strictly in personal projects and demos. The syntaxes and properties used in some of the demos are different from what you would find in the actual specifications, because they have changed since the builds that support a previous version of the specification came out. Also, because they are still unstable, all of these properties are vendor-prefixed, which means you have to add support for each prefix as support is added.</p>
<p>If you do use these features, just make sure that the content is readable in browsers that do not support them. The easiest way to do this would be to use <a href="http://modernizr.com/">feature detection</a> and then use CSS to make the content readable when the feature is unsupported.</p>
<h3 id="help_the_working_group">Help The Working Group!</h3>
<p>Do these layout proposals sound exciting to you? Jump on the <a href="http://lists.w3.org/Archives/Public/www-style/">www-style</a> mailing list to provide feedback on them! Just note that the mailing list will flood your inbox, and you should carefully filter the emails so that you pay attention only to the drafts you are interested in.</p>
<p>Write demos and test how these work, and if you find bugs in the builds that have these properties, provide feedback to the browser vendors and submit bug reports. If you have suggestions for changing or adding properties to these proposals, do write in in the mailing list (or you can <a href="https://twitter.com/divya">bug me on Twitter</a>)!</p>
<p>These are exciting times, and within a few years the way we lay out Web pages will have changed dramatically! Perhaps this will finally sound the death knell of print. (Just kidding.)</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kabayview.com/css3/six-css-layout-features-to-look-forward-to/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>String Handling Functions</title>
		<link>http://www.kabayview.com/php/string-handling-functions</link>
		<comments>http://www.kabayview.com/php/string-handling-functions#comments</comments>
		<pubDate>Mon, 09 Jan 2012 19:01:39 +0000</pubDate>
		<dc:creator>Lynda Damiata</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.kabayview.com/?p=1162</guid>
		<description><![CDATA[&#124; By: James Appleyard &#124; Posted: December 26, 2011 &#124; PHP Tutorials phpmaster.com :: PHP has a vast selection of built-in string handling functions that allow you to easily manipulate strings in almost any possible way. However, learning all these functions, remembering what they do, and when they might come in handy can be a <a href='http://www.kabayview.com/php/string-handling-functions'> [read more]</a>]]></description>
			<content:encoded><![CDATA[<p>| By: <a title="Posts by James Appleyard" href="http://phpmaster.com/author/jappleyard/" rel="author">James Appleyard</a> | Posted: <abbr title="">December 26, 2011</abbr> | <a title="View all posts in PHP Tutorials" href="http://phpmaster.com/category/php-tutorials/" rel="category tag">PHP Tutorials</a><br />
<a href="http://phpmaster.com/" target="_blank">phpmaster.com</a> ::</p>
<p><img class="aligncenter size-full wp-image-1164" title="27442300" src="http://www.kabayview.com/wp-content/uploads/2012/01/27442300.jpg" alt="String Handling Functions" width="616" height="190" />PHP has a vast selection of built-in string handling functions that allow you to easily manipulate strings in almost any possible way. However, learning all these functions, remembering what they do, and when they might come in handy can be a bit daunting, especially for new developers. There is no way I can cover every string function in one article, and besides, that is what the PHP manual is for! But what I will do is show how to work with some of the most commonly used string handling functions that you should know. After this, you’ll be working with strings as well as any concert violinist!</p>
<h2>On the Case</h2>
<p>PHP offers several functions that enable you to manipulate the case of characters within a string without having to edit the string character by character. Why would you care about this? Well maybe you want to ensure that certain text is all in upper case such as acronyms, titles, for emphasis or just to ensure names are capitalized correctly. Or maybe you just want to compare two strings and you want to ensure the letters you are comparing are the same character set. The case manipulation functions are pretty easy to get to grips with; you just pass the string as a parameter to the function and the return value you is the processed string.</p>
<p>If you wanted to ensure all the letters in a specific string were uppercase, you can use the <code>strtoupper()</code> function as follows:</p>
<pre>&lt;?php
$str = "Like a puppet on a string.";
$cased = strtoupper($str);
// Displays: LIKE A PUPPET ON A STRING.
echo $cased;</pre>
<p>It is perhaps obvious but still worth noting that numbers and other non-alphabet characters will not be converted.</p>
<p>As you can probably guess, the <code>strtolower()</code> function does the exact opposite of <code>strtoupper()</code> and converts a string into all lowercase letters:</p>
<pre>&lt;?php
$str = "LIKE A PUPPET ON A STRING.";
$cased = strtolower($str);
// Displays: like a puppet on a string.
echo $cased;</pre>
<p>There may be other times when you want to ensure certain words, such as names or titles, just have the first letter of each word capitalized. For this you can use the <code>ucwords()</code> function:</p>
<pre>&lt;?php
$str = "a knot";
$cased = ucwords($str);
// Displays: A Knot
echo $cased;</pre>
<p>It is also possible to manipulate the case of just the first letter of a string using the <code>lcfirst()</code> and <code>ucfirst()</code> functions. If you want the first letter to be lowercase, use <code>lcfirst()</code>. If you want the first letter to be uppercase, use <code>ucfirst()</code>. The <code>ucfirst()</code> function is probably the most useful since you can use it to ensure a sentence always starts with a capital letter.</p>
<p>&nbsp;</p>
<h2>A Quick Trim</h2>
<p>Sometimes a string needs trimming round the edges. It may have whitespace or other characters at the beginning or end which needs removing. The whitespace can be an actual space character, but it can also be a tab, carriage return, etc. One example of when you might need to do something like this is when you’re working with user input and you want to clean it up it before you start processing it. The <code>trim()</code>function in PHP lets you to do just that; you can pass the string as a parameter and all whitespace from the beginning and end of that string will be removed:</p>
<pre>&lt;?php
$str = "  A piece of string?  ";
// Displays: string(22) " A piece of string? "
var_dump($str);

$trimmed = trim($str);
// Displays: string(18) "A piece of string?"
var_dump($trimmed);</pre>
<p><code>trim()</code> is also multi-purpose in that in addition to the string you can also pass it a set of characters and it will remove any that match from the beginning or end:</p>
<pre>&lt;?php
$str = "A piece of string?";
$trimmed = trim($str, "A?");
// Displays: string(16) " piece of string"
var_dump($trimmed);</pre>
<p>You do need to be careful when you work with these additional characters since <code>trim()</code> will only remove whitespace if you specifically provide it as one of the characters you want removed:</p>
<pre>&lt;?php
$str = "A piece of string?";
$trimmed = trim($str, "A ?");
// Displays: string(15) "piece of string"
var_dump($trimmed);</pre>
<p>Even though <code>trim()</code> only removes characters at the start and end of a string, it has removed both “A” and the space because when “A” is removed the space becomes the new start of the string, and so that is also removed.</p>
<p>There are also <code>ltrim()</code> and <code>rtrim()</code> functions in PHP which are similar to the <code>trim()</code> function but only remove whitespace (or other specified characters) from the left or right of the string respectively.</p>
<h2>How Long is a (Piece of) String?</h2>
<p>Very often when working with strings, you’ll want to know how long it is. For example, when dealing with a form, you may have a field where you want to make sure users can’t go over a certain number of characters. To count the number of characters in a string, you can use the <code>strlen()</code> function:</p>
<pre>&lt;?php
$str = "How long is a piece of string?";
$size = strlen($str);
// Displays: 30
echo $size;</pre>
<h2>Cutting Strings Down to Size</h2>
<p>Another common situation is finding specific text within a given string and “cutting it” out so you can do something else with it. To cut a string down to size, you need a good pair of scissors, and in PHP your scissors are the <code>substr()</code> function.</p>
<p>To use the <code>substr()</code> function, pass the string you want to work with as a parameter along with a positive or negative integer. The number determines where you’ll start cutting the string; 0 starts you off at the first character of the string (remember that when you count through a string, the first character on the left starts at position 0, not 1).</p>
<pre>&lt;?php
$str = "How to cut a string down to size";
$snip = substr($str, 13);
//Displays: string down to size
echo $snip;</pre>
<p>When you use a negative number, <code>substr()</code> will start backwards from the end of the string.</p>
<pre>&lt;?php
$str = "How to cut a string down to size";
$snip = substr($str, -7);
//Displays: to size
echo $snip;</pre>
<p>An optional third parameter to <code>substr()</code> is the length, another integer value that allows you to specify the number of characters you want to extract from the string.</p>
<pre>&lt;?php
$str = "How to cut a string down to size";
$snip = substr($str, 13, 6);
//Displays: string
echo $snip;</pre>
<p>If you just need to find the position of a particular piece of text within a string and nothing else, you can use the <code>strpos()</code> function which returns the position your selection is from the start of the string. A useful trick, especially when you don’t know the starting position of the text you to cut from a string, is to combine the two functions. Rather than specifying a start position as an integer, you can search for a specific piece of text and then extract that.</p>
<pre>&lt;?php
$str = "How to cut a string down to size";
$snip = substr($str, strpos($str, "string"), 6);
//Displays: string
echo $snip;</pre>
<h2>Swap Shop</h2>
<p>Finally, let’s look at replacing a piece of the string with something else, for which you can use <code>str_replace()</code> function. This is ideal for situations where you just want to swap out instances of specific words or a set of characters in a string and replace them with something else:</p>
<pre>&lt;?php
$oldstr = "The cat was black";
$newstr = str_replace("black", "white", $oldstr);
// Displays: The cat was white
echo $newstr;</pre>
<p>You can also provide arrays to <code>str_replace()</code> if you want to replace multiple values:</p>
<pre>&lt;?php
$oldstr  = "The flag was red white and blue.";
$america = array("red", "white", "blue");
$germany = array("black", "red", "yellow");
$newstr = str_replace($america, $germany, $oldstr);
// Displays: The flag was black red and yellow.
echo $newstr;</pre>
<h2>Summary</h2>
<p>Hopefully, this article has given you a taste of some of the things you can do with strings in PHP and made you hungry to learn more. I’ve really barely scraped the tip of the iceberg! The best place to find out more about all of the different string functions is to take some time to read the String Functions page in the PHP Manual.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kabayview.com/php/string-handling-functions/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Responsive Design Approach for Complex, Multicolumn Data Tables</title>
		<link>http://www.kabayview.com/html5/a-responsive-design-approach-for-complex-multicolumn-data-tables</link>
		<comments>http://www.kabayview.com/html5/a-responsive-design-approach-for-complex-multicolumn-data-tables#comments</comments>
		<pubDate>Mon, 09 Jan 2012 18:17:43 +0000</pubDate>
		<dc:creator>Lynda Damiata</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Responsive Web Design]]></category>

		<guid isPermaLink="false">http://www.kabayview.com/?p=1127</guid>
		<description><![CDATA[Posted by Maggie on 12/29/2011 filamentgroup.com :: In responsive web design, one of the toughest design problems to solve is how format complex tabular data for display on smaller screens. In this post, we&#8217;ll explore an experimental approach to rendering a complex table, using progressive enhancement and responsive design methods, that displays comfortably at a <a href='http://www.kabayview.com/html5/a-responsive-design-approach-for-complex-multicolumn-data-tables'> [read more]</a>]]></description>
			<content:encoded><![CDATA[<p>Posted by Maggie on 12/29/2011<br />
<a href="http://filamentgroup.com/" target="_blank">filamentgroup.com</a> ::</p>
<p><img class="alignleft size-full wp-image-1152" title="dwpe-ad-cover-sml" src="http://www.kabayview.com/wp-content/uploads/2012/01/dwpe-ad-cover-sml.png" alt="Progressice Enhancement" width="97" height="125" />In responsive web design, one of the toughest design problems to solve is how format complex tabular data for display on smaller screens. In this post, we&#8217;ll explore an experimental approach to rendering a complex table, using progressive enhancement and responsive design methods, that displays comfortably at a wide range of screen sizes, provides quick access to the data, and preserves the table structure so that data can still be compared across columns.</p>
<p>We&#8217;ve been batting around the idea of making tables responsive for awhile.</p>
<p>Our initial attempts to make table data palatable on small screens include showing a <a href="http://jsbin.com/apane6/14/">thumbnail image that links to the data</a> or a <a href="http://jsbin.com/emexa4">canvas-based chart</a>; others have developed responsive CSS workarounds that display a definition list, using either <a href="http://jsbin.com/arixic">list</a> or <a href="http://css-tricks.com/responsive-data-tables/">table</a> markup. Which approach to take depends on the type of data. For example, structured data where each row is a unique object or entity—say, business contacts, or favorite Netflix movies—are well-suited to a definition list style on small screens, because header and cell data can be displayed as simple label and value pairs (i.e., Name: Maggie Wachs, Company: Filament Group&#8230;). The switch to a chart or other visualization on smaller screens works well for a simple numeric comparison of a single value. And snapping down to a thumbnail image that launched a full table to pan and zoom was an okay fallback in lieu of no data at all.</p>
<p>But we encountered a scenario that didn&#8217;t quite work with any of the above solutions: a table of complex of financial data with 6-8 related data points, where comparisons and trends among columns are important to see. Visual relationships between headings and cells, and between neighboring columns, are crucial to understanding the data and would be lost on smaller screens if we displayed a list or chart.</p>
<p>We needed a happy medium: a way to keep the basic table structure in place—with headings above, and whole columns that sit side-by-side—and simultaneously display a manageable amount of data at a size that&#8217;s comfortably readable.</p>
<h2>A table for every screen</h2>
<p>The approach we devised starts with a full data set, and uses a simple priority-based class designation to display a manageable subset of data columns for common target screen sizes, and also gives the user control to change column visibility easily.</p>
<p>It&#8217;s probably easier to explain with a concrete example: we&#8217;ll use a table that lists technology companies and their stock prices and several stock performance metrics. Each row displays data for a single company; columns organize data points by type for comparison. <a href="http://filamentgroup.com/examples/rwd-table-patterns/">View the demo</a>.</p>
<p>All data columns will display on desktops and tablets in landscape orientation, but only a subset will fit comfortably on anything smaller. So the first order of business is to identify which columns of data are essential to see at all screen widths by default, or optional (shown only when space allows). In our table of tech company stocks, the data is somewhat meaningless without the company name, current stock value, or most recent change, so we&#8217;ll consider those essential. The trade time, previous close, and open values would be nice to see if the screen can fit those columns, so we&#8217;ll make them optional. The remaining data—bid, ask, and 1-year target estimate—are less important in relative terms, so they will appear on only the widest screens.</p>
<p><img class="aligncenter size-full wp-image-1129" title="breakpoints" src="http://www.kabayview.com/wp-content/uploads/2012/01/breakpoints.png" alt="" width="920" height="888" /></p>
<p>In this case, we want users to have the last word regarding which columns to show, so we&#8217;ll also create a custom menu that lets them choose which columns to display:</p>
<p><img class="aligncenter size-full wp-image-1132" title="menu" src="http://www.kabayview.com/wp-content/uploads/2012/01/menu.png" alt="" width="420" height="263" /></p>
<p>&nbsp;</p>
<p>The final result is a table that displays a limited set of columns on smaller screens, and provides quick access to data that&#8217;s hidden because of space constraints (<a href="http://filamentgroup.com/examples/rwd-table-patterns/">view the demo</a>). To accomplish this, we&#8217;ll use progressive enhancement to ensure that we&#8217;re serving a usable experience to all devices. We&#8217;ll start with well-formed, semantic table markup and very basic CSS, and then if the browser is capable, apply JavaScript and enhanced CSS (including media queries) to conditionally show a larger number of columns as screen space allows.</p>
<h2>Markup</h2>
<p>A basic table — with consecutive columns and descriptive headings — is an efficient way to display a complex data set; data arranged into columns and rows are easy to scan and compare. So an HTML table is the clear markup choice for our financial data.</p>
<p>We&#8217;ll start with a well-formed <code>table</code> that contains a <code>thead</code> for the heading row, followed by a <code>tbody</code> for the cells.</p>
<pre>&lt;table cellspacing="0" id="tech-companies"&gt;
&lt;thead&gt;
&lt;tr&gt;
...header cells...
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
...rows of data...
&lt;/tbody&gt;
&lt;/table&gt;</pre>
<p>As we fill in the content, we&#8217;ll add descriptive classes to identify the essential and optional content. We&#8217;ll assign these classes only to the headers; later, we&#8217;ll write a little JavaScript to map these headers to their respective columns of data.</p>
<pre>&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Company&lt;/th&gt;
&lt;th&gt;Last Trade&lt;/th&gt;
&lt;th&gt;Trade Time&lt;/th&gt;
&lt;th&gt;Change&lt;/th&gt;
&lt;th&gt;Prev Close&lt;/th&gt;
&lt;th&gt;Open&lt;/th&gt;
&lt;th&gt;Bid&lt;/th&gt;
&lt;th&gt;Ask&lt;/th&gt;
&lt;th&gt;1y Target Est&lt;/th&gt;
&lt;/tr&gt;
...
&lt;/thead&gt;</pre>
<p>Notice that we added a second class to the Company header, <code>persist</code>. Essential columns are present by default at small screen sizes, but we&#8217;ll still be able to toggle their visibility with the custom menu. Marking the Company column with this class provides a way for us to omit it from the menu, and prevent it from being hidden.</p>
<p>We&#8217;ll complete the table with rows of data that correspond to the column headers:</p>
<pre>&lt;table cellspacing="0" id="tech-companies"&gt;
&lt;thead&gt;
...
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;GOOG &lt;span&gt;Google Inc.&lt;/span&gt;&lt;/th&gt;
&lt;td&gt;597.74&lt;/td&gt;
&lt;td&gt;12:12PM&lt;/td&gt;
&lt;td&gt;14.81 (2.54%)&lt;/td&gt;
&lt;td&gt;582.93&lt;/td&gt;
&lt;td&gt;597.95&lt;/td&gt;
&lt;td&gt;597.73 x 100&lt;/td&gt;
&lt;td&gt;597.91 x 300&lt;/td&gt;
&lt;td&gt;731.10&lt;/td&gt;
&lt;/tr&gt;
...
&lt;/tbody&gt;</pre>
<p>Later when we apply JavaScript, we&#8217;ll create a custom menu based on the table&#8217;s content and append it to the page, immediately above the table. The menu will consist of a container element for a &#8220;Display&#8221; button and the menu overlay:</p>
<pre>&lt;div&gt;
&lt;a href="#"&gt;Display&lt;/a&gt;
&lt;div&gt;
...menu content...
&lt;/div&gt;
&lt;/div&gt;</pre>
<p>The menu overlay will contain a list of options, one for each column, where each option has a <code>label</code> and checkbox <code>input</code> for toggling that column&#8217;s visibility (columns with the <code>persist</code> class will be excluded from the menu):</p>
<pre>&lt;div&gt;
&lt;a href="#"&gt;Display&lt;/a&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;input type="checkbox" name="toggle-cols" id="toggle-col-1" value="co-1"&gt;
&lt;label for="toggle-col-1"&gt;Last Trade&lt;/label&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;input type="checkbox" name="toggle-cols" id="toggle-col-2" value="co-2"&gt;
&lt;label for="toggle-col-2"&gt;Trade Time&lt;/label&gt;
&lt;/li&gt;
...
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;</pre>
<p>When the script builds the menu, it will automatically assign <code>name</code> and <code>value</code> attributes and unique IDs to the <code>input</code> elements, and matching <code>for</code> attributes to their labels.</p>
<p>Last but not least, we&#8217;ll wrap the table in a container element to simplify positioning the menu:</p>
<pre>&lt;div&gt;
&lt;table cellspacing="0" id="tech-companies"&gt;
...
&lt;/table&gt;
&lt;/div&gt;</pre>
<h2>CSS</h2>
<p>We&#8217;ll assume you&#8217;re already familiar with using CSS3 media queries to render pages responsively. If not, we highly recommend Ethan Marcotte&#8217;s definitive article, <a href="http://www.alistapart.com/articles/responsive-web-design/">Responsive Web Design</a>, and <a href="http://www.abookapart.com/products/responsive-web-design">book by the same title</a>.</p>
<p>Let&#8217;s start with the table. We want it to fill the available space, so we&#8217;ll assign a width of 100%:</p>
<pre>table {
width: 100%;
font-size: 1.2em;
}</pre>
<p>And then apply color, padding, and alignment properties to make the data easier to scan:</p>
<pre>thead th {
white-space: nowrap;
border-bottom: 1px solid #ccc;
color: #888;
}
th, td {
padding: .5em 1em;
text-align: right;
}
th:first-child,
td:first-child {
text-align: left;
}
tbody th, td {
border-bottom: 1px solid #e6e6e6;
}</pre>
<p>Next, we&#8217;ll write the rules that hide and show columns. We&#8217;ve scoped these styles to a class, <code>enhanced</code>, which is assigned to the table via JavaScript. This ensures that column visibility is altered only when JavaScript is available. By default, we&#8217;ll hide all columns, and show only those marked with the <code>essential</code> class:</p>
<pre>.enhanced th,
.enhanced td {
display: none;
}
.enhanced th.essential,
.enhanced td.essential {
display: table-cell;
}</pre>
<p>Using CSS3 media queries, we&#8217;ll show optional columns when the browser is 500px wide or greater, and all columns at 800px or greater:</p>
<pre>@media screen and (min-width: 500px) {
.enhanced th.optional,
.enhanced td.optional {
display: table-cell;
}
}

@media screen and (min-width: 800px) {
.enhanced th,
.enhanced td {
display: table-cell;
}
}</pre>
<p>When using this approach, how you prioritize and categorize your data must correspond to the number of screen size breakpoints you plan to support. In our example, we&#8217;ve chosen to have two breakpoints, at 500 and 800 pixels wide, and two levels of importance, essential and optional. If we were to add another break point, say around 400px, we would need to rework our categories to include a third (i.e., primary, secondary, tertiary) so that we can mark each column to be visible at a particular breakpoint.</p>
<p>When the custom menu is inserted into the table&#8217;s container, it will appear just above the table on the right:</p>
<pre>.table-menu-wrapper {
position: absolute;
top: -3em;
right: 0;
}</pre>
<p>The menu itself will also be absolutely positioned, and by default will be hidden with the <code>table-menu-hidden</code> class (later, we&#8217;ll write JavaScript to toggle that class when the &#8220;Display&#8221; button is clicked):</p>
<pre>.table-menu {
position: absolute;
right: 0;
left: auto;
background-color: #fff;
padding: 10px;
border: 1px solid #ccc;
font-size: 1.2em;
width: 12em;
}
.table-menu-hidden {
left: -999em;
right: auto;
}</pre>
<p>Finally, we&#8217;ll add relative positioning to the table&#8217;s container. Later, when we append the menu we can position it without having to calculate location coordinates:</p>
<pre>.table-wrapper {
position: relative;
margin: 5em 5%;
}</pre>
<h2>JavaScript</h2>
<p>The table we just created is usable on its own; any browser that renders HTML will display it. With a few JavaScript enhancements, we&#8217;ll be able to view the table at smaller screen sizes without sacrificing the table structure. (The following examples use <a href="http://filamentgroup.com/lab/responsive_design_approach_for_complex_multicolumn_data_tables/jquery.com">jQuery</a>.)</p>
<p>First we&#8217;ll append the <code>enhanced</code> class for scoping styles:</p>
<pre>// add class for scoping styles - cells should be hidden only when JS is on
table.addClass("enhanced");</pre>
<p>We&#8217;ll create a container element for the menu, which will come into play a little later in the script:</p>
<pre><code>var container = $('&lt;div class="table-menu table-menu-hidden"&gt;&lt;ul /&gt;&lt;/div&gt;'); </code></pre>
<p>Then we&#8217;ll enhance the markup with classes and attributes that allow us to control column visibility. We&#8217;ll loop through the table headers and assign them unique IDs, then reference those IDs in <code>headers</code> attributes assigned to associated cells. (The <code><a href="http://www.w3.org/TR/html4/struct/tables.html#adef-headers">headers</a></code> attribute identifies to which header(s) a cell belongs.) We&#8217;ll also copy the classes that we assigned to the column headers — essential and optional — and assign them to the associated columns.</p>
<pre>$( "thead th" ).each(function(i){
var th = $(this),
id = th.attr("id"),
classes = th.attr("class");  // essential, optional (or other content identifiers)

// assign an ID to each header, if none is in the markup
if (!id) {
id = ( "col-" ) + i;
th.attr("id", id);
};

// loop through each row to assign a "headers" attribute and any classes (essential, optional) to the matching cell
// the "headers" attribute value = the header's ID
$( "tbody tr" ).each(function(){
var cell = $(this).find("th, td").eq(i);
cell.attr("headers", id);
if (classes) { cell.addClass(classes); };
});
...</pre>
<p>Next, while still looping through the headers, we&#8217;ll create a menu item for each column, except for those marked with the <code>persist</code> class. Each menu item consists of a checkbox and label with the column header text.</p>
<pre>...
// create the menu hide/show toggles
if ( !th.is(".persist") ) {

// note that each input's value matches the header's ID;
// later we'll use this value to control the visibility of that header and it's associated cells
var toggle = $('&lt;li&gt;&lt;input type="checkbox" name="toggle-cols" id="toggle-col-'+i+'" value="'+id+'" /&gt; &lt;label for="toggle-col-'+i+'"&gt;'+th.text()+'&lt;/label&gt;&lt;/li&gt;');

// append each toggle to the container
container.find("ul").append(toggle);

...</pre>
<p>And then we&#8217;ll bind events to each checkbox for controlling that column&#8217;s visibility.</p>
<pre>...

// assign behavior
toggle.find("input")

// when the checkbox is toggled
.change(function(){
var input = $(this),
val = input.val(),  // this equals the header's ID, i.e. "company"
cols = $("#" + val + ", [headers="+ val +"]"); // so we can easily find the matching header (id="company") and cells (headers="company")

if (input.is(":checked")) { cols.show(); }
else { cols.hide(); };
})

// custom event that sets the checked state for each toggle based on column visibility, which is controlled by @media rules in the CSS
// called whenever the window is resized or reoriented (mobile)
.bind("updateCheck", function(){
if ( th.css("display") ==  "table-cell") {
$(this).attr("checked", true);
}
else {
$(this).attr("checked", false);
};
})

// call the custom event on load
.trigger("updateCheck");

}; // end conditional statement ( !th.is(".persist") )
}); // end headers loop</pre>
<p>After closing the headers loop, we&#8217;ll bind our custom event to the window&#8217;s resize and orientation change events:</p>
<pre>// update the inputs' checked status
$(window).bind("orientationchange resize", function(){
container.find("input").trigger("updateCheck");
});</pre>
<p>And, last but not least, append our checkbox menu to the page and bind show/hide menu events:</p>
<pre>var menuWrapper = $('&lt;div /&gt;'),
menuBtn = $('&lt;a href="#"&gt;Display&lt;/a&gt;');

menuBtn.click(function(){
container.toggleClass("table-menu-hidden");
return false;
});

menuWrapper.append(menuBtn).append(container);
table.before(menuWrapper);  // append the menu immediately before the table

// assign click-away-to-close event
$(document).click(function(e){
if ( !$(e.target).is( container ) &amp;&amp; !$(e.target).is( container.find("*") ) ) {
container.addClass("table-menu-hidden");
}
});</pre>
<h2>Media query support for IE: Respond.js</h2>
<p>Older versions of IE (8 and earlier) don&#8217;t natively support CSS3 media queries, so we need to use a workaround in those browsers to implement our responsive table. Thanks to our own Scott Jehl, we can use a lightweight polyfill script, <a href="https://github.com/scottjehl/Respond">respond.js</a>, that enables support for min- and max-width media query properties. The script is open source and available on <a href="https://github.com/scottjehl/Respond">github</a>.</p>
<h2>Keep the conversation going</h2>
<p>The pattern discussed here is one possibility for coding a responsive table. We hope to discover more, and will update our <a href="https://github.com/filamentgroup/RWD-Table-Patterns">RWD-Table-Patterns</a> git repository as we come across additional use cases.</p>
<p>The demo code shown here is open source and available for download. Feel free to put it through its paces. If you use it and see room for improvement, please submit a pull request and we&#8217;ll review it as soon as possible.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kabayview.com/html5/a-responsive-design-approach-for-complex-multicolumn-data-tables/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Apply CSS3 Transformations to Background Images</title>
		<link>http://www.kabayview.com/css3/how-to-apply-css3-transformations-to-background-images</link>
		<comments>http://www.kabayview.com/css3/how-to-apply-css3-transformations-to-background-images#comments</comments>
		<pubDate>Thu, 01 Dec 2011 18:03:10 +0000</pubDate>
		<dc:creator>Lynda Damiata</dc:creator>
				<category><![CDATA[CSS3]]></category>

		<guid isPermaLink="false">http://www.kabayview.com/?p=1096</guid>
		<description><![CDATA[By Craig Buckler &#124; October 27, 2011 &#124; sitepoint.com :: Scaling, skewing and rotating any element is possible with the CSS3 transform property. It’s supported in all modern browsers (with vendor prefixes) and degrades gracefully, e.g. #myelement { -webkit-transform: rotate(30deg); -moz-transform: rotate(30deg); -ms-transform: rotate(30deg); -o-transform: rotate(30deg); transform: rotate(30deg); } Great stuff. However, this rotates the <a href='http://www.kabayview.com/css3/how-to-apply-css3-transformations-to-background-images'> [read more]</a>]]></description>
			<content:encoded><![CDATA[<p>By <a title="Posts by Craig Buckler" href="http://www.sitepoint.com/author/craig-buckler/" rel="author">Craig Buckler</a> | October 27, 2011 |<br />
<a href="http://www.sitepoint.com/" target="_blank">sitepoint.com</a> ::</p>
<p>Scaling, skewing and rotating any element is possible with the CSS3 <code>transform</code> property. It’s supported in all modern browsers (with vendor prefixes) and degrades gracefully, e.g.</p>
<pre>#myelement
{
-webkit-transform: rotate(30deg);
-moz-transform: rotate(30deg);
-ms-transform: rotate(30deg);
-o-transform: rotate(30deg);
transform: rotate(30deg);
}</pre>
<p>Great stuff. However, this rotates the whole element — it’s content, border and background image. What if you only want to rotate the background image? Or what if you want the background to remain fixed while the element is rotated?</p>
<p>Currently, there’s no W3C proposal for background-image transformations. It would be incredibly useful so I suspect one will appear eventually, but that doesn’t help developers who want to use similar effects today.</p>
<p>Fortunately, there is a solution. In essence, it’s a hack which applies the background image to a before or after pseudo element rather than the parent container. The pseudo element can then be transformed independently.</p>
<h2>Transforming the Background Only</h2>
<p>The container element can have any styles applied but it must be set to <code>position: relative</code> since our pseudo element will be positioned within it. You should also set <code>overflow: hidden</code> unless you’re happy for the background to spill out beyond the container.</p>
<pre>#myelement
{
position: relative;
overflow: hidden;
}</pre>
<p>We can now create an absolutely-positioned pseudo element with a transformed background. The z-index is set -1 to ensure it appears below the container’s content.</p>
<pre>#myelement:before
{
content: "";
position: absolute;
width: 200%;
height: 200%;
top: -50%;
left: -50%;
z-index: -1;
background: url(background.png) 0 0 repeat;
-webkit-transform: rotate(30deg);
-moz-transform: rotate(30deg);
-ms-transform: rotate(30deg);
-o-transform: rotate(30deg);
transform: rotate(30deg);
}</pre>
<p>Note you may need to adjust the pseudo element’s width, height and position. For example, if you’re using a repeated image, a rotated area must be larger than its container to fully cover the background:</p>
<p><img class="aligncenter size-full wp-image-1097" title="589-transform-background-100pc" src="http://www.kabayview.com/wp-content/uploads/2011/12/589-transform-background-100pc.png" alt="transform background" width="398" height="174" /></p>
<h2>Fixing the Background on a Transformed Element</h2>
<p>All transforms on the parent container are applied to pseudo elements. Therefore, we need to <em>undo</em> that transformation, e.g. if the container is rotated by 30 degrees, the background must be rotated -30 degrees to return to a fixed position:</p>
<pre>#myelement
{
position: relative;
overflow: hidden;
-webkit-transform: rotate(30deg);
-moz-transform: rotate(30deg);
-ms-transform: rotate(30deg);
-o-transform: rotate(30deg);
transform: rotate(30deg);
}
#myelement:before
{
content: "";
position: absolute;
width: 200%;
height: 200%;
top: -50%;
left: -50%;
z-index: -1;
background: url(background.png) 0 0 repeat;
-webkit-transform: rotate(-30deg);
-moz-transform: rotate(-30deg);
-ms-transform: rotate(-30deg);
-o-transform: rotate(-30deg);
transform: rotate(-30deg);
}</pre>
<p>Again, you will need to adjust the size and position to ensure the background covers the parent container adequately.</p>
<p>Please <a href="http://blogs.sitepointstatic.com/examples/tech/background-transform/index.html"><strong>view the demonstration page</strong></a> for examples. The full code is contained in the HTML source.</p>
<p>The effects work in IE9, Firefox, Chrome, Safari and Opera. IE8 will not show any transformations but the background appears.</p>
<p>IE6 and 7 do not support pseudo elements so the background disappears. However, if you want to support those browsers, you could apply a background image to the container then set it to “none” using an advanced selector or conditional CSS.</p>
<p>Full code contained in the HTML source:</p>
<pre>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
&lt;meta charset="UTF-8" /&gt;
&lt;title&gt;Background Image Transformations&lt;/title&gt;
&lt;style&gt;
body
{
	font-family: arial, helvetica, freesans, sans-serif;
	font-size: 100%;
	color: #333;
	background-color: #ddd;
}

h1
{
	font-size: 1.5em;
	font-weight: normal;
	margin: 0;
}

#element0, #element1, #element2, #element3
{
	width: 12em;
	font-size: 2em;
	text-align: center;
	line-height: 5em;
	margin: 3em auto;
	border: 2px solid #666;
	border-radius: 7px;
}

#element0, #element1
{
	background: url(background.png) 0 0 repeat;
}

#element1, #element3
{
	-webkit-transform: rotate(30deg);
	-moz-transform: rotate(30deg);
	-ms-transform: rotate(30deg);
	-o-transform: rotate(30deg);
	transform: rotate(30deg);
}

#element2, #element3
{
	position: relative;
	overflow: hidden;
}

#element2:before, #element3:before
{
	content: "";
	position: absolute;
	width: 200%;
	height: 200%;
	top: -50%;
	left: -50%;
	z-index: -1;
	background: url(background.png) 0 0 repeat;
}

#element2:before
{
	-webkit-transform: rotate(30deg);
	-moz-transform: rotate(30deg);
	-ms-transform: rotate(30deg);
	-o-transform: rotate(30deg);
	transform: rotate(30deg);
}

#element3:before
{
	-webkit-transform: rotate(-30deg);
	-moz-transform: rotate(-30deg);
	-ms-transform: rotate(-30deg);
	-o-transform: rotate(-30deg);
	transform: rotate(-30deg);
}
&lt;/style&gt;

&lt;/head&gt;
&lt;body&gt;

&lt;h1&gt;Background Image Transformations&lt;/h1&gt;

&lt;div id="element0"&gt;No Transformation&lt;/div&gt;
&lt;div id="element1"&gt;Transformed Element&lt;/div&gt;

&lt;div id="element2"&gt;Transformed Background&lt;/div&gt;

&lt;div id="element3"&gt;Fixed Background&lt;/div&gt;

&lt;p&gt;For more information, please please refer to:&lt;br /&gt;
&lt;a href="<a href="view-source:http://blogs.sitepoint.com/css3-transform-background-image/">http://blogs.sitepoint.com/css3-transform-background-image/</a>"&gt;How to Apply CSS3 Transformations to Background Images&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This example code was developed by &lt;a href="<a href="view-source:http://twitter.com/craigbuckler">http://twitter.com/craigbuckler</a>"&gt;Craig Buckler&lt;/a&gt; of &lt;a href="<a href="view-source:http://optimalworks.net/">http://optimalworks.net/</a>"&gt;OptimalWorks.net&lt;/a&gt; for &lt;a href="<a href="view-source:http://sitepoint.com/">http://sitepoint.com/</a>"&gt;SitePoint.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It can be used without any restrictions but please don't expect 24/7 support! A link back to &lt;a href="<a href="view-source:http://www.sitepoint.com/">http://www.sitepoint.com/</a>"&gt;SitePoint.com&lt;/a&gt; is appreciated.&lt;/p&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kabayview.com/css3/how-to-apply-css3-transformations-to-background-images/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Attaching Files To Your Posts Using WordPress Custom Meta Boxes, Part 2</title>
		<link>http://www.kabayview.com/wordpress/attaching-files-to-your-posts-using-wordpress-custom-meta-boxes-part-2</link>
		<comments>http://www.kabayview.com/wordpress/attaching-files-to-your-posts-using-wordpress-custom-meta-boxes-part-2#comments</comments>
		<pubDate>Thu, 01 Dec 2011 17:39:12 +0000</pubDate>
		<dc:creator>Lynda Damiata</dc:creator>
				<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.kabayview.com/?p=1074</guid>
		<description><![CDATA[Tom McFarlin on Oct 25th 2011 &#124; wp.tutsplus.com :: In the first post, we took a look at how to attach a file – specifically, a PDF – to WordPress posts and pages without having to use a plugin or third-party solution. At this point, you can only upload files – there’s no way to <a href='http://www.kabayview.com/wordpress/attaching-files-to-your-posts-using-wordpress-custom-meta-boxes-part-2'> [read more]</a>]]></description>
			<content:encoded><![CDATA[<p><a title="Posts by Tom McFarlin" href="http://wp.tutsplus.com/author/tom/">Tom McFarlin</a> on Oct 25th 2011 |<br />
<a href="http://wp.tutsplus.com/" target="_blank">wp.tutsplus.com</a> ::</p>
<p><a title="Attaching Files To Your Posts Using WordPress Custom Meta Boxes, Part 1" href="http://www.kabayview.com/wordpress/attaching-files-to-your-posts-using-wordpress-custom-meta-boxes-part-1">In the first post</a>, we took a look at how to attach a file – specifically, a PDF – to WordPress posts and pages without having to use a plugin or third-party solution. At this point, you can only upload files – there’s no way to actually deactivate the link or delete the link to the file once it has been uploaded. In this post, we’ll take a look at how to provide some slightly better styling for the download link and how to extend the custom meta box functionality by allowing users to delete files after they’ve downloaded them.</p>
<p>&nbsp;</p>
<hr />
<h2>Dress It Up</h2>
<p>If you followed along with the code in the first post, then you should have a functional demo of how attaching a PDF to a WordPress post (or page) works; however, the overall presentation doesn’t look very good:</p>
<p><img class="aligncenter size-full wp-image-1075" title="figure_0" src="http://www.kabayview.com/wp-content/uploads/2011/12/figure_0.png" alt="figure example" width="779" height="256" /></p>
<p>Before going any further, let’s clean this up a bit so that it looks a bit more integrated with the default theme. Remember that we’re using <a href="http://theme.wordpress.com/themes/twentyeleven/">Twentyeleven</a> as our default theme so that we’re all on the same page as we work through the tutorial.</p>
<p>First, let’s move the download link into a more logical location. If you’ve been following along since the first post, you’ll recall that we placed the download link in single.php which is located in the root of the theme directory. Open the file and locate the block of code that looks like this:</p>
<pre>get_template_part( 'content', 'single' );
$doc = get_post_meta(get_the_ID(), 'wp_custom_attachment', true);

&lt;a href="    &lt;?php echo $doc['url']; ?&gt;"&gt;
Download PDF Here
&lt;/a&gt;</pre>
<p>Copy all but the first line of code and remove it from the file. This should leave only a call to <a href="http://codex.wordpress.org/Function_Reference/get_template_part">get_template_part</a>.</p>
<p>Next, locate custom-single.php. This is a template file located in the root of the theme directory. Find the call to <a href="http://codex.wordpress.org/Function_Reference/the_content">the_content()</a> and then paste the code you just copied directly below it. This should result in the following block of code:</p>
<pre>the_content();
$doc = get_post_meta(get_the_ID(), 'wp_custom_attachment', true);
&lt;a href="    &lt;?php echo $doc['url']; ?&gt;"&gt;
Download PDF Here
&lt;/a&gt;</pre>
<p>Now, let’s wrap the link in a container so that we can easily style it. I’m giving my container the ID of ‘wp_custom_attachment.’ Feel free to use whatever you like, just remember to refer to it correctly in your stylesheet.</p>
<p>Here’s my markup:</p>
<pre>the_content();
$doc = get_post_meta(get_the_ID(), 'wp_custom_attachment', true);
&lt;div id="wp_custom_attachment"&gt;
&lt;a href="&lt;!--?php echo $doc['url']; ?--&gt;"&gt;
Download PDF Here
&lt;/a&gt;
&lt;/div&gt;&lt;!-- #wp_custom_attachment --&gt;</pre>
<p>And here’s my CSS:</p>
<pre>.wp_custom_attachment {
margin: 8px 0 8px 0;
border: 1px solid #DDD;
background: #EEE;
padding: 8px;
text-align: center;
border-radius: 4px;
}</pre>
<p>Permitting you’ve written everything correctly, the download link should now look like this:</p>
<p><img class="aligncenter size-full wp-image-1082" title="figure_1" src="http://www.kabayview.com/wp-content/uploads/2011/12/figure_1.png" alt="example figure 1" width="660" height="240" /></p>
<p>Much better, right? It’s now styled such that it looks to be more tightly integrated with the theme. Remember to make the corresponding changes to page.php, as well (considering that we’re supporting file attachments on both posts and pages).</p>
<hr />
<h2>Download, When Available</h2>
<p>Before moving on, we have one more small change to make to the code we just added. Right now, the download link is displayed unconditionally. This means that whether or not a post actually has a file, we’re displaying the download link.</p>
<p>Ideally, we only want to display the download link whenever there is a file to download. As such, we’ll need a conditional. Specifically, we’ll need to get the associated post meta data, determine if there is an actual URL for the file attachment. If so, we’ll display the link; otherwise, we won’t.</p>
<p>In the block of code we just added to content-single.php, place an opening if statement just above the opening wp_custom_attachment tag and close the statement just below the closing container tag. Right now, the code should look something like this:</p>
<pre>the_content();
$doc = get_post_meta(get_the_ID(), 'wp_custom_attachment', true);
if() {
&lt;div id="wp_custom_attachment"&gt;
&lt;a href="&lt;!--?php echo $doc['url']; ?--&gt;"&gt;
Download PDF Here
&lt;/a&gt;
&lt;/div&gt;&lt;!-- #wp_custom_attachment --&gt;
} // end if</pre>
<p>We need to check the presence of the document’s URL. There are a number of ways to do this, but I typically check by taking a look at its URL attribute. The resulting code block is:</p>
<pre>the_content();
$doc = get_post_meta(get_the_ID(), 'wp_custom_attachment', true);
if(strlen(trim($doc['url'])) &gt; 0) {
&lt;div id="wp_custom_attachment"&gt;
&lt;a href="&lt;!--?php echo $doc['url']; ?--&gt;"&gt;
Download PDF Here
&lt;/a&gt;
&lt;/div&gt;&lt;!-- #wp_custom_attachment --&gt;
} // end if</pre>
<p>At this point, the download link should only display when there is a valid file attached to the give post or page. Try it out.</p>
<hr />
<h2>Deleting The File</h2>
<p>At this point, we’ve tied up some loose ends from the previous post and we’re ready to finish up the functionality necessary to delete attachments.</p>
<h3>Laying The Foundation</h3>
<p>Recall from the last post that once the user attempts to upload a file, we have a serialization function that fires that’s responsible for actually writing the file to disk. For reference, this takes place in save_custom_meta_data.</p>
<p>In order to properly delete a file, we need to track the existing file’s location and whether or not a user has actually requested to delete the file. We’ll do that with a combination of an input box and an anchor.</p>
<p>First, locate the ‘wp_custom_attachment’ function that we created in the last post. This is where we added the file input element. Just below the input element add the following code (the full function will be provided below):</p>
<pre>// Create the input box and set the file's URL as the text element's value
$html .= '&lt;input type="text" id="wp_custom_attachment_url" name="wp_custom_attachment_url" value=" ' . $doc['url'] . '" size="30" /&gt;';</pre>
<p>This will add an a text input element which tracks the value of the uploaded document’s URL. We’ll clean this up a bit later in the tutorial, but for now, let’s introduce an an anchor for deleting the file. Just below the two lines of code we just added, write the following:</p>
<pre>$html .= '&lt;a href="javascript:;" id="wp_custom_attachment_delete"&gt;' . __('Delete File') . '&lt;/a&gt;';</pre>
<p>&nbsp;</p>
<p>Take note: we’ve given the anchor a unique ID. This will be necessary when we begin hooking up the administration area to handle user events. If you don’t give your anchor this ID, make note of whatever you do assign.</p>
<p>We’re not quite done yet. Remember how we setup the single post and page views to conditionally display the download link? We need to do the same thing for the delete link. Specifically, we need to only show the delete link if a document exists. So, in similar fashion, wrap the anchor in a conditional statement that checks for the presence of the document’s URL:</p>
<pre>// Display the 'Delete' option if a URL to a file exists
if(strlen(trim($doc['url'])) &gt; 0) {
$html .= '&lt;a href="javascript:;" id="wp_custom_attachment_delete"&gt;' . __('Delete File') . '&lt;/a&gt;';
} // end if</pre>
<p>It’s nothing too heavy, right? To be complete, here’s the full function as it stands:</p>
<pre>function wp_custom_attachment() {

wp_nonce_field(plugin_basename(__FILE__), 'wp_custom_attachment_nonce');

$html = '
&lt;p&gt;';
$html .= 'Upload your PDF here.';
$html .= '&lt;/p&gt;';
$html .= '&lt;input type="file" id="wp_custom_attachment" name="wp_custom_attachment" value="" size="25" /&gt;';

// Grab the array of file information currently associated with the post
$doc = get_post_meta(get_the_ID(), 'wp_custom_attachment', true);

// Create the input box and set the file's URL as the text element's value
$html .= '&lt;input type="text" id="wp_custom_attachment_url" name="wp_custom_attachment_url" value=" ' . $doc['url'] . '" size="30" /&gt;';

// Display the 'Delete' option if a URL to a file exists
if(strlen(trim($doc['url'])) &gt; 0) {
$html .= '&lt;a href="javascript:;" id="wp_custom_attachment_delete"&gt;' . __('Delete File') . '&lt;/a&gt;';
} // end if

echo $html;

} // end wp_custom_attachment
&lt;/p&gt;</pre>
<p>We’ll revisit this function a little but later in the tutorial but, for now, test it out. First, navigate to a post that has no attachment. You should see the file input box and an empty input box. After uploading a file, you should see the input box contain the URL of the file followed by a link for deleting the file.</p>
<p>But we’re not done yet. After all, the delete link doesn’t actually do anything.</p>
<h3>Wiring It Up</h3>
<p>Next, locate the ‘js’ directory in the theme root. Add a new file called custom_attachment.js. We’ll write code for this momentarily, but the purpose of the file will be what allows us to actually delete the PDF that we’ve attached to a post.</p>
<p>After that, open up functions.php and add the following function at the end of the file:</p>
<pre>function add_custom_attachment_script() {

wp_register_script('custom-attachment-script', get_stylesheet_directory_uri() . '/js/custom_attachment.js');
wp_enqueue_script('custom-attachment-script');

} // end add_custom_attachment_script
add_action('admin_enqueue_scripts', 'add_custom_attachment_script');</pre>
<p>This function will read the JavaScript file that we just created and include it on any administrative page in the WordPress backend. Enqueuing and Registering scripts is beyond the scope of the tutorial, but I recommend <a href="http://codex.wordpress.org/Function_Reference/wp_enqueue_script">reading up on it</a>.</p>
<p>Next, let’s revisit the JavaScript file. Generally speaking, the code should do the following things:</p>
<ul>
<li>Determine if the delete link is present</li>
<li>If the link is present, attach a custom event handler that clears out the text input that contains the URL of the file</li>
<li>Hide the link once the file has been marked for deletion</li>
</ul>
<p>The source code is below and it has been fully commented to help explain what each line is doing:</p>
<pre>jQuery(function($) {

// Check to see if the 'Delete File' link exists on the page...
if($('a#wp_custom_attachment_delete').length === 1) {

// Since the link exists, we need to handle the case when the user clicks on it...
$('#wp_custom_attachment_delete').click(function(evt) {

// We don't want the link to remove us from the current page
// so we're going to stop it's normal behavior.
evt.preventDefault();

// Find the text input element that stores the path to the file
// and clear it's value.
$('#wp_custom_attachment_url').val('');

// Hide this link so users can't click on it multiple times
$(this).hide();

});

} // end if

});</pre>
<p>At this point, the file will not be deleted but you should have a functional view. Locate a page that has a file attached to it. Your custom meta box should look something like this:</p>
<p><img class="aligncenter size-full wp-image-1089" title="figure_2" src="http://www.kabayview.com/wp-content/uploads/2011/12/figure_2.png" alt="figure example 2" width="298" height="152" />After clicking on the ‘Delete Link’ anchor, the custom meta box should look like this:</p>
<p><img class="aligncenter size-full wp-image-1090" title="figure_3" src="http://www.kabayview.com/wp-content/uploads/2011/12/figure_3.png" alt="example figure 3" width="301" height="146" /></p>
<p>If not, double-check your debugging console to verify that you don’t have any JavaScript errors.</p>
<hr />
<h2>Deleting The File</h2>
<p>At this point, we’ve done all but actually delete the file. To do this, we’ll need to update the save_custom_meta_data function that we wrote in the first post. Recall that the functional includes a conditional checks the contents of the $_FILES collection coming from the POST request. If the collection is populated, then we serialization the file.</p>
<p>Since we’re attempting to delete the file, the $_FILES collection shouldn’t contain any data so all of our code will need to be contained in an else clause. The full source code for the function will be provided below, but here’s how the functional should work:</p>
<ul>
<li>Check to see if there’s a document associated with the post</li>
<li>Check to see if the text box used for tracking the file’s URL is empty</li>
<li>If a file exists and the text box is empty, delete the file and update the associated meta data</li>
</ul>
<p>This should be straightforward: We’ve given each post a text element that contains the URL to the file. If the file URL is empty, it means the user has clicked on the ‘Delete File’ link and is requesting to delete the file. Here’s how we can achieve just that:</p>
<pre>// Grab a reference to the file associated with this post
$doc = get_post_meta($id, 'wp_custom_attachment', true);

// Grab the value for the URL to the file stored in the text element
$delete_flag = get_post_meta($id, 'wp_custom_attachment_url', true);

// Determine if a file is associated with this post and if the delete flag has been set (by clearing out the input box)
if(strlen(trim($doc['url'])) &gt; 0 &amp;&amp; strlen(trim($delete_flag)) == 0) {

// Attempt to remove the file. If deleting it fails, print a WordPress error.
if(unlink($doc['file'])) {

// Delete succeeded so reset the WordPress meta data
update_post_meta($id, 'wp_custom_attachment', null);
update_post_meta($id, 'wp_custom_attachment_url', '');

} else {
wp_die('There was an error trying to delete your file.');
} // end if/el;se

} // end if</pre>
<p>Once the file is deleted, note that we also have to update the post meta data by emptying out the attachment’s value as well as the attachment’s URL value. In the odd case that the file doesn’t delete, we’re displaying a simple error message. Advanced error handling is beyond the scope of this post.</p>
<p>As promised, here’s the full serialization function:</p>
<pre>function save_custom_meta_data($id) {

/* --- security verification --- */
if(!wp_verify_nonce($_POST['wp_custom_attachment_nonce'], plugin_basename(__FILE__))) {
return $id;
} // end if

if(defined('DOING_AUTOSAVE') &amp;&amp; DOING_AUTOSAVE) {
return $id;
} // end if

if(!current_user_can('edit_page', $id)) {
return $id;
} // end if
/* - end security verification - */

// Make sure the file array isn't empty
if(!emptyempty($_FILES['wp_custom_attachment']['name'])) {

// Setup the array of supported file types. In this case, it's just PDF.
$supported_types = array('application/pdf');

// Get the file type of the upload
$arr_file_type = wp_check_filetype(basename($_FILES['wp_custom_attachment']['name']));
$uploaded_type = $arr_file_type['type'];

// Check if the type is supported. If not, throw an error.
if(in_array($uploaded_type, $supported_types)) {

// Use the WordPress API to upload the file
$upload = wp_upload_bits($_FILES['wp_custom_attachment']['name'], null, file_get_contents($_FILES['wp_custom_attachment']['tmp_name']));

if(isset($upload['error']) &amp;&amp; $upload['error'] != 0) {
wp_die('There was an error uploading your file. The error is: ' . $upload['error']);
} else {
add_post_meta($id, 'wp_custom_attachment', $upload);
update_post_meta($id, 'wp_custom_attachment', $upload);
} // end if/else

} else {
wp_die("The file type that you've uploaded is not a PDF.");
} // end if/else

} else {

// Grab a reference to the file associated with this post
$doc = get_post_meta($id, 'wp_custom_attachment', true);

// Grab the value for the URL to the file stored in the text element
$delete_flag = get_post_meta($id, 'wp_custom_attachment_url', true);

// Determine if a file is associated with this post and if the delete flag has been set (by clearing out the input box)
if(strlen(trim($doc['url'])) &gt; 0 &amp;&amp; strlen(trim($delete_flag)) == 0) {

// Attempt to remove the file. If deleting it fails, print a WordPress error.
if(unlink($doc['file'])) {

// Delete succeeded so reset the WordPress meta data
update_post_meta($id, 'wp_custom_attachment', null);
update_post_meta($id, 'wp_custom_attachment_url', '');

} else {
wp_die('There was an error trying to delete your file.');
} // end if/el;se

} // end if

} // end if/else

} // end save_custom_meta_data
add_action('save_post', 'save_custom_meta_data');</pre>
<p>By now, you’ve got a fully functioning custom meta box. Give it a try.</p>
<hr />
<h2>Cleaning It Up</h2>
<p>We’ve got one last minor change to make just to make our UI complete. Remember the text input that we added earlier in the tutorial that’s responsible for maintaining the file’s URL? We can mark that as hidden – there’s no reason the user needs to see it. The JavaScript source will still use it properly and its value will be read in the serialization function.</p>
<p>The final wp_custom_attachment function should look like this:</p>
<pre>function wp_custom_attachment() {

wp_nonce_field(plugin_basename(__FILE__), 'wp_custom_attachment_nonce');

$html = '&lt;p&gt;';
$html .= 'Upload your PDF here.';
$html .= '&lt;/p&gt;';
$html .= '&lt;input type="file" id="wp_custom_attachment" name="wp_custom_attachment" value="" size="25" /&gt;';

// Grab the array of file information currently associated with the post
$doc = get_post_meta(get_the_ID(), 'wp_custom_attachment', true);

// Create the input box and set the file's URL as the text element's value
$html .= '&lt;input type="hidden" id="wp_custom_attachment_url" name="wp_custom_attachment_url" value=" ' . $doc['url'] . '" size="30" /&gt;';

// Display the 'Delete' option if a URL to a file exists
if(strlen(trim($doc['url'])) &gt; 0) {
$html .= '&lt;a href="javascript:;" id="wp_custom_attachment_delete"&gt;' . __('Delete File') . '&lt;/a&gt;';
} // end if

echo $html;

} // end wp_custom_attachment</pre>
<p>These two posts covered a lot of information. There are a number of canned solutions – be it plugins, themes, or other add-ons – available for integrating functionality like this, but part of being a good developer is knowing when to use a third-party solution and when to roll your own.</p>
<p>Additionally, if you’re working with WordPress in a professional capacity, then it’s important to understand the API. Hopefully this series has helped showcase much of what can be done by leveraging core functionality of WordPress.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kabayview.com/wordpress/attaching-files-to-your-posts-using-wordpress-custom-meta-boxes-part-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Responsive IMGs Part 2 — In-depth Look at Techniques</title>
		<link>http://www.kabayview.com/responsive-web-design/responsive-imgs-part-2-%e2%80%94-in-depth-look-at-techniques</link>
		<comments>http://www.kabayview.com/responsive-web-design/responsive-imgs-part-2-%e2%80%94-in-depth-look-at-techniques#comments</comments>
		<pubDate>Tue, 15 Nov 2011 14:42:50 +0000</pubDate>
		<dc:creator>Lynda Damiata</dc:creator>
				<category><![CDATA[Responsive Web Design]]></category>

		<guid isPermaLink="false">http://www.kabayview.com/?p=1061</guid>
		<description><![CDATA[September 30th, 2011 by Jason Grigsby &#124; cloudfour.com :: In Responsive IMGs Part 1, I took a high-level look at what responsive IMGs are, the problem they are trying to solve, and the common issues they face. In this post, I’m going to take a deeper look at the specific techniques being used to provide <a href='http://www.kabayview.com/responsive-web-design/responsive-imgs-part-2-%e2%80%94-in-depth-look-at-techniques'> [read more]</a>]]></description>
			<content:encoded><![CDATA[<p>September 30th, 2011 by Jason Grigsby |<br />
<a href="http://www.cloudfour.com/" target="_blank">cloudfour.com</a> ::</p>
<p>In <a title="Responsive IMGs — Part 1" href="http://www.kabayview.com/responsive-web-design/responsive-imgs-%e2%80%94-part-1" target="_blank">Responsive IMGs Part 1</a>, I took a high-level look at what responsive IMGs are, the problem they are trying to solve, and the common issues they face. In this post, I’m going to take a deeper look at the specific techniques being used to provide responsive IMGs and try to evaluate what works and doesn’t. If you haven’t read <a title="Responsive IMGs — Part 1" href="http://www.kabayview.com/responsive-web-design/responsive-imgs-%e2%80%94-part-1" target="_blank">part 1</a>, you may want to do so before reading this post as it will help explain some of the terms I use.</p>
<p>When I started working on this project two months ago, I thought I would get to the end and be able to say, “Here are the three approaches that work best. Go download them and figure out how to integrate them into your systems.” Oh naivety!</p>
<p>What I’ve found is that there is no comprehensive solution. Instead, we have several months of experiments. Each experiment has its own advantages and disadvantages.</p>
<p>Because of this, the best thing we can do is understand the common elements and challenges so that we can start to pick the best parts of each for building our own solutions.</p>
<p>So um… this is a long post. Sorry.</p>
<h2>Abandoned approaches</h2>
<h3>Dynamic Base Tag</h3>
<p>Many of the early techniques used javascript to dynamically change the base tag. The new base tag would add directories into the path that would be used to indicate what size image should be retrieved. After the document loaded, the base tag would be removed.</p>
<p>Unfortunately, this approach ran into race conditions that I described in part 1. I found that Google Chrome was downloading both the mobile and desktop images. <a href="http://twitter.com/scottjehl">Scott Jehl</a> found the problem to be a difference between how inline and external javascript is handled. He submitted a <a href="https://bugs.webkit.org/show_bug.cgi?id=66474" target="_blank">bug</a> to webkit which has been marked as “won’t fix” because:</p>
<blockquote><p>Inserting base element effectively changes all the subsequent URLs on the page. Any script may insert one so to avoid double loads we could never load anything else as long as there is a pending script load. This would mean disabling preloading, which is out of the question.</p></blockquote>
<p>In theory, you could still use a dynamic base tag inline, but the Filament Group has been primarily using a cookies-based approach instead which seems safer.</p>
<h3>Temporary images</h3>
<p>Another early technique was to have the src of imgs pointing to a temporary image and then having javascript replace the source with the correct file path. In most cases, the image was an one pixel transparent gif set up with caching which would hopefully prevent the browser from requesting it more than once no matter how many times it was referenced in the page.</p>
<p>The problem with this technique is that if javascript isn’t present, the browser will never download the images.</p>
<h2 id="js-based">Javascript-based solutions</h2>
<h3 id="altpaths">Where do you store the path to alternate versions of an image?</h3>
<p>If the the img points to ‘small.jpg’, where do you put the information that ‘large.jpg’ is what should be loaded on larger screens?</p>
<h4 id="url_parameters">URL parameters</h4>
<p>One solution is to put the path to alternate versions of the image in the src attribute as url parameters. In its simplest form:</p>
<p><code>&lt;img src="small.jpg?full=large.jpg"&gt;</code></p>
<p>If you have multiple sizes of images, they simply get added as additional values on the url. The key to making this work is coupling it with an .htaccess file.</p>
<h5>Potential CDN, proxies, and caching issues</h5>
<p>The big drawback to using URL parameters is that it may cause problems with content deliver networks and proxies that doesn’t pay attention to url parameters when caching content. Some caching algorithms ignore anything that has a URL parameter on it which means that pages will slow down because images aren’t cached.</p>
<p>Others will simply cache the first version of the image they see. If the first person behind a proxy cache happened to view the page on a mobile phone, then every subsequent user sees the mobile size image until the cache expires.</p>
<p>How likely is this to be an issue? I had the same question so I asked Steve Souders. He says that it is <a href="http://twitter.com/#%21/souders/status/118912008098811905">enough of a problem that you can’t ignore it</a>. This echoes comments by Bryan and Stephanie Rieger at Breaking Development about problems with caching and CDNs.</p>
<p>Therefore, I think we should be looking for techniques that don’t use url parameters.</p>
<h5>Examples of this approach:</h5>
<ul>
<li><a href="https://github.com/filamentgroup/Responsive-Images">Responsive Images JS Master Branch</a></li>
<li><a href="https://github.com/allmarkedup/responsive-images-alt">Responsive images alt</a></li>
<li><a href="http://www.craig-russell.co.uk/responsive-images-and-context-aware-image-sizing/">Responsive Images and Context Aware Sizing</a></li>
<li><a href="http://www.grahambird.co.uk/lab/doubletake/">Responsive images with Doubletake.js</a></li>
<li><a href="http://www.jamesfairhurst.co.uk/posts/view/responsive_images_with_php_and_jquery/">Responsive images with PHP and jQuery</a></li>
<li><a href="http://blog.keithclark.co.uk/responsive-images-using-cookies/">Responsive images using cookies</a></li>
<li><a href="https://github.com/ahume/Responsive-Images">Context aware responsive images</a></li>
</ul>
<p><a name="data-attributes"></a><a name="toc-anchor-1977-9"></a></p>
<h4 id="data-attributes">Data attributes</h4>
<p>Instead of putting the file path into the url parameters, the information is put in one or more data- attributes. For example:</p>
<blockquote><p>&lt;img src=”small.r.jpg” data-fullsrc=”large.jpg”&gt;</p></blockquote>
<p>Which element has data attributes added to it and how many are added depends on the technique.</p>
<h5>Looping through every img tag</h5>
<p>The only disadvantage to this technique that I’m aware of is the fact that the javascript has to loop through every image, check for data attributes, and then modify the src attribute depending on screen size. This is probably not a big problem on desktop browsers which is where the loop is mostly to be used.</p>
<h5>Examples of this approach</h5>
<ul>
<li><a href="https://github.com/filamentgroup/Responsive-Images/tree/data-attribute-based">Responsive Images JS data-attribute-based branch</a></li>
<li><a href="http://www.monoliitti.com/images/">Testing Responsive Images</a></li>
<li><a href="http://www.headlondon.com/our-thoughts/technology/posts/creating-responsive-images-using-the-noscript-tag">Creating responsive images using the noscript tag</a></li>
</ul>
<h4 id="filestructure">Assumed file structure</h4>
<p>In this variation, the file path isn’t included in the HTML document. Instead, it is assumed that the images are put on the server in a regular fashion. For example, all small images might be in /images/sml/ whereas large images are in /images/lrg/.</p>
<p>If this is true, then the html doesn’t need to provide both paths. It just needs to provide the image filename (e.g., boat.jpg) and then let javascript modify the src to be appropriate for the size of the screen (/images/lrg/boat.jpg for desktop).</p>
<h5>Examples of this approach</h5>
<ul>
<li><a href="https://github.com/allmarkedup/responsive-images-alt">responsive-images-alt</a></li>
<li><a href="http://adaptive-images.com/">Adapative images</a></li>
</ul>
<h4 id="dynamic-filenames">Dynamic file names</h4>
<p>One of the things that I suggested in part 1 was that we might need arbitrary image sizes. Some of the solutions are built around the assumption that you can pass the dimensions that you want in the url and get back an image at that size.</p>
<p>Because the images are resized on the fly, there is no need to store alternative file paths in the HTML document. Javascript will modify the filename from something like ‘boat.jpg’ to ‘boat-480×200.jpg’. There is no issue with caching or CDNs because each image is unique.</p>
<h5>Some images cannot simply be resized</h5>
<p>This approach doesn’t provide a good solution for manually choosing images at different sizes. It assumes that resizing images will work in all cases which we know is not true.</p>
<h5>Examples of this approach</h5>
<ul>
<li><a href="https://github.com/filamentgroup/Responsive-Images/tree/meaningful-base">Responsive Images JS meaningful branch</a></li>
<li><a href="http://blog.trasatti.it/2011/05/responsive-images-and-tinysrc.html">Responsive images and tinySrc</a></li>
</ul>
<h3 id="htaccess">Role of .htaccess (or similar rewrite rules)</h3>
<p>Many of the solutions rely on server rewrite rules. The examples are usually written using Apache .htaccess files, but they could be any sort of rewrite rule.</p>
<p>Lets look at a snippet of the .htaccess file from <a href="https://github.com/filamentgroup/Responsive-Images/tree/cookie-driven">Responsive Images JS cookie-based branch</a> to see how rewrite rules are being used:</p>
<p><code>RewriteEngine On<br />
#large cookie, large image<br />
RewriteCond %{HTTP_COOKIE} rwd-screensize=large<br />
RewriteCond %{QUERY_STRING} large=([^&amp;]+)<br />
RewriteRule .* %1 [L]<br />
</code></p>
<p>The first line turns rewrite rules on. Next comes a couple of conditions (RewriteCond). The first checks to see if there is a cookie called rwd-screensize that has the value of large. The second checks to see if the query string for the url contains a value for large. This .htaccess file is looking for something like:</p>
<p><code>&lt;img src="small.jpg?large=large.jpg"&gt;</code></p>
<p>If both conditions are met—the cookie is set to large and there is a large value in the query string—then the rewrite rule will send the file that was specified in the query string (in the example above, that would be large.jpg).</p>
<p>The rwd-screensize cookie is set by javascript after it tests for the screen size.</p>
<h3 id="preventdownload">How do you prevent the browser from downloading multiple images?</h3>
<p>With the basics out of the way, we can now get to the tricky part. As mentioned in part 1, intercepting the browser before it starts downloading images so that you can evaluate and possibly change the source of those images is tricky and may result in race conditions.</p>
<p>Now that the dynamic base tag has been ruled out, there are two main techniques that remain.</p>
<h4 id="cookies">Set a cookie</h4>
<p>This is the method that the Filament Group settled on for the Boston Globe. Javascript is inserted into the head of the document so that it evaluates as soon as possible.</p>
<p>After it determines the screen size, it sets a cookie. Every subsequent image request sent from the browser will include the cookie. The server can use the cookie to determine the best image to sent back to the user.</p>
<h5>Potential problems</h5>
<p>If the browser doesn’t support cookies or the user blocks them, then the javascript will have no effect.</p>
<p>Also, Yoav Weiss has done some testing and <a href="http://blog.yoav.ws/2011/09/Preloaders-cookies-and-race-conditions">shared results</a> that indicate that duplicate files will be downloaded by IE9. Firefox will download duplicate files if the script is external, but not if it internal. This suggests that cookies may also be subject to the race condition problem that caused us to abandon the dynamic base tag approach.</p>
<h5>Examples of this approach</h5>
<ul>
<li><a href="https://github.com/filamentgroup/Responsive-Images/tree/cookie-driven">Responsive Images cookie branch</a></li>
<li><a href="http://blog.keithclark.co.uk/responsive-images-using-cookies/">Responsive images using cookies</a></li>
<li><a href="https://github.com/allmarkedup/responsive-images-alt">responsive-images-alt</a></li>
</ul>
<h4 id="noscript">Noscript tag</h4>
<p>Within the last couple of months, new techniques have emerged that use the noscript tag as a way to prevent extra downloads. The first post I saw describing this technique was by <a href="https://twitter.com/#%21/tiny_m">Mairead Buchan</a>. She describe it as having “<a href="http://www.headlondon.com/our-thoughts/technology/posts/creating-responsive-images-using-the-noscript-tag"> the elegance of a wading hippo</a>”. Despite that description, I think this technique holds promise.</p>
<p>A <a href="http://www.monoliitti.com/images/">cleaner implementation of the noscript approach</a> was created independently by <a href="http://twitter.com/#%21/apeisa">Antti Peisa</a>. Here is the html:</p>
<p><code><br />
&lt;noscript data-large='Koala.jpg' data-small='Koala-small.jpg' data-alt='Koala'&gt;<br />
&lt;img src='Koala.jpg' alt='Koala' /&gt;<br />
&lt;/noscript&gt;<br />
</code></p>
<p>The values for the various sizes of image tags are stored in the data attributes on the noscript tag itself. Antti then provides sample jQuery code used to process the image:</p>
<p><code><br />
$('noscript[data-large][data-small]').each(function(){<br />
var src = screen.width &gt;= 500 ? $(this).data('large') : $(this).data('small');<br />
$('&lt;img src="' + src + '" alt="' + $(this).data('alt') + '" /&gt;').insertAfter($(this));<br />
});<br />
</code></p>
<p>These lines go through the document to find noscript tags with the appropriate data attributes. It tests for the screen size and then inserts a new img tag with the appropriate image path and alt tag.</p>
<h5>No race conditions!</h5>
<p>When using the noscript tag, there are no rendering race conditions. The image in the noscript tag never starts downloading. Mairead explained that “<a href="http://www.headlondon.com/our-thoughts/technology/posts/creating-responsive-images-using-the-noscript-tag">it works because children of the &lt;noscript&gt; tag are not added to the DOM</a>”.</p>
<p>This makes sense. The browser knows if javascript is available before it starts rendering a page. If javascript is available, there is no reason to worry about doing anything with items inside the noscript tag. If they aren’t getting added to the DOM, they certainly aren’t going to get downloaded.</p>
<p>This technique also has fallbacks if javascript isn’t enabled and doesn’t rely on cookies or htaccess files.</p>
<h5>Potential gotchas</h5>
<p>The biggest gotcha will be devices that profess to support javascript, but have poor implementations. For example, Blackberry 4.5 has javascript, but javascript cannot manipulate the DOM. Ergo, the noscript tag will not get used because scripts are available, but the script won’t successfully add a new img tag so no images will show.</p>
<p>Please note, this is speculation on my part. I know how Blackberry 4.5 behaves, but I haven’t tested this particular approach on a 4.5 device.</p>
<p>Even though this approach does not create a race condition, it is important that the javascript execute as quickly as possible. Inserting all of these images may require the browser to reflow the page. It also may cause the browser to load assets less efficiently because it cannot start prefetching assets.</p>
<p>Because of the need to execute as quickly as possible, it makes sense to remove the jQuery dependency from Antti’s javascript and put the code in the head of the document.</p>
<h5>Examples of this approach</h5>
<ul>
<li><a href="http://www.headlondon.com/our-thoughts/technology/posts/creating-responsive-images-using-the-noscript-tag">“Creating responsive images using the noscript tag</a></li>
<li><a href="http://www.monoliitti.com/images/">Testing Responsive Images</a></li>
<li><a href="https://gist.github.com/1200270">Responsive context aware images without cookies or server logic</a></li>
</ul>
<h4>Is screen size the right thing to look at?</h4>
<p>Most of these techniques rely on the size of the screen to determine what the image size should be. Andy Hume points out that the size of the screen may be misleading. He <a href="http://blog.andyhume.net/content-aware-responsive-images">writes</a>:</p>
<blockquote><p>The content driven approach to fixing this is to decide which image to load based on whether the image will be stretched beyond its true pixel width. If you stretch an image beyond its true width it begins to look pixelated or blurry. In this scenario, we want to load in a higher resolution version of the image.</p></blockquote>
<p><a href="https://github.com/ahume/Responsive-Images">Andy’s fork of the Responsive Images JS</a> tackles this problem (and adds support for nginx).</p>
<h3>Boston Globe Responsive IMGs are Busted</h3>
<p>I’ve been looking forward to the Boston Globe’s launch for quite some time. It is a tremendous feat of engineering and design. It has the volume of traffic necessary to test different approaches to responsive IMGs and see what works and what doesn’t.</p>
<p>The technique that they chose to use combines data attributes with cookies. Unfortunately, responsive IMGs are currently broken on the Boston Globe site. This is a known problem and they are working on fixing it.</p>
<p>The upshot is that we don’t yet have a large scale deployment of any of these techniques that we can interrogate and point to as validation that a particular combination is battle-hardened.</p>
<h3 id="mostpromising">Most promising javascript only techniques</h3>
<p>In my mind, cookies plus data-src and noscript are the two most promising techniques. Both have problems, but they have far fewer gotchas than other approaches.</p>
<h2>Server side solutions</h2>
<p>Most of the javascript techniques require little, if any, support from the server. There are alternate approaches that leverage the server for a bunch of the heavy lifting.</p>
<h3 id="uasniffing">User agent string parsing</h3>
<p>A few people have demonstrated solutions that do light-weight user agent string parsing to identify various mobile phones. If the user agent can be identified as iPhone or Android, then declare the device mobile and set the image size appropriately.</p>
<p>Unlike a lot of developers, I don’t have a problem with device detection based on user agent string. But if you’re going to start doing it for mobile, you have to take on real device detection via WURFL, Device Atlas, etc. Simplistic regular expression matching and assumptions about screen sizes isn’t going to work.</p>
<h3 id="devicedetection">Device detection</h3>
<p>There are a couple of different approaches that rely on device detection to determine the screen size and deliver an appropriate image back. Device detection databases are pretty good about having basic information like screen size.</p>
<h4 id="tinysrc">Sencha.io Src (formerly called TinySRC)</h4>
<p><a href="http://twitter.com/jamespearce">James Pearce</a> created a fantastic service called TinySRC. He later went to work for Sencha and TinySRC became Sencha.io Src. <a href="http://www.sencha.com/products/io/">Sencha.io Src</a> automatically resizes images for you. You reference Sencha.io Src in your img stag like this:</p>
<p><code>http://src.sencha.io/http://www.myapp.com/myimg.jpg<br />
</code></p>
<p>When a browser requests the url above, Sencha.io Src will look up the user agent of the device making the request to determine what size image is appropriate. It will then grab the image from your server and resize it. It then caches the resized image so that subsequent requests can be served quickly.</p>
<p>In addition to the automatic mode, Sencha.io Src will also allow you to specify specific sizes that you would like the image resized to.</p>
<h5>Combining Responsive Images JS with Sencha.io Src</h5>
<p><a href="http://twitter.com/#%21/andreatrasatti">Andrea Trasatti</a> forked Scott Jehl’s Responsive Images JS to <a href="http://blog.trasatti.it/2011/05/responsive-images-and-tinysrc.html">combine responsive IMGs with TinySRC</a>. The script finds the screen size using javascript and then uses htaccess to request the image at the correct size from Sencha.io Src.</p>
<p>Andrea’s version was written fairly early. It still uses dynamic base tags, url parameters, and results in “1 HTTP request for every image that we might avoid”. But all of these problems could be remedied by combining what Andrea started with some of the newer approaches.</p>
<h5>Potential drawbacks</h5>
<p>First, if you have a religious aversion to device detection, then you probably don’t want to use Sencha.io Src or you need to use it in a scenario where can specify the image size that you want.</p>
<p>As an aside, I’ve found it funny to see people who speak ill of device detection and user agent strings suggest that people use TinySRC. I once saw a slide deck that dismissed device detection and then a couple of slides later talked about how great TinySRC is. If only they knew.</p>
<p>On a more practical level, you have to evaluate whether or not the service will remain up and what happens if all of your content points to sencha urls that suddenly go away. I don’t think Sencha is going to go anywhere anytime soon. I know James well enough to know he’ll want to keep this service running forever if he can. But even all that said, looking at the long term availability of a service is something that needs to be considered.</p>
<h4 id="wurfl">WURFL-based solution</h4>
<p>WURFL is the largest open source device database. After attending the <a href="http://bdconf.com/">Breaking Development</a> conference earlier this month, Carson McDonald was inspired to develop a <a href="https://github.com/carsonmcdonald/ServerSideResponsiveImageExample#readme">WURFL-based solution for images</a>. It’s awesome to see something come together so quickly after the conference.</p>
<p>(BTW, <a href="http://bdconf.com/">Breaking Development</a> is the best conference in North America for web on mobile. Registration for the next event opens today. You should attend!)</p>
<p>Carson notes that his approach will likely have the same problems with CDNs and caching because different size images come from the same url.</p>
<h2>Image resizing services</h2>
<h3>Google’s mod_pagespeed</h3>
<p>Google’s <a href="http://code.google.com/speed/page-speed/docs/payload.html#ScaleImages">mod_pagespeed Apache module</a> automates many performance tasks and includes an option to scale any images on the fly. There are many ways to scale images (GD, ImageMagick, etc.). I decided to call out mod_pagespeed because it was one I hadn’t considered until I saw it suggested in a forum. I don’t know of anyone who has explored how it might be used in an responsive IMGs solutions.</p>
<h2>Combining client and server approaches</h2>
<h3 id="adaptiveimages">Adaptive Images</h3>
<p>As you can probably tell by now, there are few solutions that you can simply install and forgot about. Most require at minimum changes to the way you mark up the page. The two solutions that come closest to be plug and play are Sencha.io Src and <a href="http://adaptive-images.com/">Adaptive-Images.com</a>.</p>
<p>Adaptive images was developed by <a href="http://twitter.com/responsiveimg">Matt Wilcox</a>. It turns the premise of Responsive IMGs on its head by assuming that the markup on the page will contain the large versions of images and will not start with the mobile versions.</p>
<p>The solution consists of three pieces:</p>
<p>1. A small snippet of javascript placed in the head that sets a cookie with the screen width and height.</p>
<p><code>&lt;script&gt;document.cookie='resolution='+Math.max(screen.width,screen.height)+'; path=/';&lt;/script&gt;</code></p>
<p>2. A .htaccess that rewrites all requests for images to a php file. You declare directories that you want to exempt from this rewrite. For example, you don’t want your media query savvy CSS background images getting routed through the php file.</p>
<p>3. The php file which resizes the image based on breakpoints that you can configure.</p>
<p>The best part of Matt’s solution is that as long as you can separate out your image files so you can exclude ones that shouldn’t be resized, you can implement this technique without making any changes to your existing markup. Existing pages and posts will suddenly have different image sizes.</p>
<h5>And now for the problems</h5>
<p>Come on, by now you weren’t expecting it to be that simple did you?</p>
<p><span style="text-decoration: line-through;">Because the images start with the large size, if javascript is not available, the large size will be delivered. The most common devices to not have javascript support are older feature phones. The type of devices that will choke and even crash on large images are older feature phones.</span></p>
<p><span style="text-decoration: line-through;">This technique also suffers from the same race conditions that most of the javascript solutions do. The cookie has to be set early to avoid extra downloads.</span></p>
<p>Update: <a href="http://www.cloudfour.com/responsive-imgs-part-2/#comment-33653">Matt commented below</a> and points out that the default settings will result in a small image being delivered if javascript isn’t present. The markup will point to a large version, but the php file returns a small version. All of this is configurable.</p>
<p>Also, he is right that the result of the race condition <a href="http://www.cloudfour.com/responsive-imgs-part-2/#comment-33660">would not be multiple downloads</a>. I think the race condition still exists with different drawbacks, but I’m going continue the conversation in the comments where Matt and I can converse.</p>
<p>I also missed the fact that the url will stay the same regardless of the size of image which can cause issues with CDNs and proxy caching as noted earlier.</p>
<h3 id="yiibu">Yiibu profile approach</h3>
<p>Brian and Stephanie Rieger presented the work they did for <a href="http://browser.nokia.com/">browser.nokia.com</a> at Breaking Development conference. For that project, they invented a new way to combine client side information with device detection.</p>
<p>When a browser first requests something from the server, they don’t know anything about the device. So they check with a device detection database to see what they can find out about the size of the screen (and other details). They then check their own local database of tacit knowledge. This a database of things they’ve learned about how specific browsers work and any overrides they want to use. They use the combination of this information to deliver the appropriate HTML, javascript and images.</p>
<p>Once the browser gets this information, a javascript runs that tests the various aspects of the browser including screen size. It then stores this information in a profile cookie.</p>
<p>On the second request, the server receives the profile cookie and compares it to the information it has in its tacit database. It may update the tacit database. It combines the information into a revised profile combining server side information with client feature detection data.</p>
<p>I’m likely doing a poor job of describing the solution. Your best bet is to look at their slides:</p>
<ul>
<li><a href="http://www.slideshare.net/yiibu/adaptation-why-responsive-design-actually-begins-on-the-server">Adaptation: Why responsive design actually begins on the server</a></li>
<li><a href="http://www.slideshare.net/yiibu/pragmatic-responsive-design">Pragmatic Responsive Design</a></li>
</ul>
<p>This combined technique mitigates the problem of first load without any of the race conditions or potential problems that the client-only solutions have. It also extends beyond images to other content and javascript.</p>
<h5>Sounds great. What’s the catch?</h5>
<p>It is a complex system and requires significant changes to infrastructure to support. Bryan and Stephanie have published the approach, but the code isn’t available for download. It may be coming, but they took a well-deserved vacation after spending most of the summer working on the Nokia Browser project.</p>
<p>Probably the biggest problem with this approach is that most of us are not the Riegers. They have been doing mobile web for years. Their tacit knowledge of devices is exceptional. Freaking geniuses. That’s hard to replicate.</p>
<p>The same is true of the Boston Globe project. The team working on that included significant portions of the jQuery Mobile team and the <a href="http://twitter.com/beep">guy who coined the phrase responsive web design</a>. Few of us are going to be so lucky on our next project.</p>
<h2>Summary</h2>
<p>As I’ve reviewed the various techniques, I keep thinking back to something Andy Hume <a href="http://www.cloudfour.com/responsive-imgs/#comment-33388">said</a> in response to part 1:</p>
<blockquote><p>Our current solutions are hugely dependant on the current (and undefined) behaviour of browsers in regard to the page-load race conditions you mention. For example, most responsive image implementations would be compromised if a particular type of look-ahead pre-parser (<a href="http://goo.gl/TyzTi">http://goo.gl/TyzTi</a>) began to speculatively download images before actually parsing the HTML or executing any script. (<strong>I half expect us to get bitten by this any day.</strong>) One way or the other we need to consort with browser makers to get future-friendly.</p></blockquote>
<p>That’s the truth of it. Most of these techniques are based on our hope that browsers continue to download assets in the order we have observed to date. If the the order changes or if browsers start pre-parsing more aggressively, the whole house of cards may fall down.</p>
<p>In part 3 of this series, I’m going to look at the conversations going on about ways to change the img tag or replace it with something that will work better with multiple file sources.</p>
<h4>Sources and Acknowledgments</h4>
<p>I reviewed 18 different techniques for this post. My notes are captured in a <a href="https://docs.google.com/spreadsheet/ccc?key=0AisdYBkuKzZ9dHpzSmd6ZTdhbDdoN21YZ29WRVdlckE&amp;hl=en_US">Google spreadsheet</a> that you are welcome to review for detailed comments on each library. Thanks to everyone for publishing their thoughts and experiments. I learned a lot from each one.</p>
<p>This series wouldn’t have been possible without the assistance of <a href="http://twitter.com/scottjehl">Scott Jehl</a> and <a href="http://twitter.com/byranrieger">Bryan</a> and <a href="http://twitter.com/stephanierieger">Stephanie Rieger</a>. Scott in particular helped me sort out the problems with the main Responsive Images JS library. Thanks to all three of you for putting up with my many naive questions and for taking the time to explain all of the work you’ve been doing!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kabayview.com/responsive-web-design/responsive-imgs-part-2-%e2%80%94-in-depth-look-at-techniques/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Responsive IMGs — Part 1</title>
		<link>http://www.kabayview.com/responsive-web-design/responsive-imgs-%e2%80%94-part-1</link>
		<comments>http://www.kabayview.com/responsive-web-design/responsive-imgs-%e2%80%94-part-1#comments</comments>
		<pubDate>Tue, 15 Nov 2011 14:28:04 +0000</pubDate>
		<dc:creator>Lynda Damiata</dc:creator>
				<category><![CDATA[Responsive Web Design]]></category>

		<guid isPermaLink="false">http://www.kabayview.com/?p=1053</guid>
		<description><![CDATA[September 27th, 2011 by Jason Grigsby &#124; cloudfour.com :: In my post “Where are the Mobile First Responsive Web Designs”, I noted that one of the first things I look for when trying to determine whether or not a responsive web design is “mobile first” is whether or not it has a strategy for handling <a href='http://www.kabayview.com/responsive-web-design/responsive-imgs-%e2%80%94-part-1'> [read more]</a>]]></description>
			<content:encoded><![CDATA[<p>September 27th, 2011 by Jason Grigsby |<br />
<a href="http://www.cloudfour.com/" target="_blank">cloudfour.com</a> ::</p>
<p>In my post “<a href="http://www.cloudfour.com/where-are-the-mobile-first-responsive-web-designs/" target="_blank">Where are the Mobile First Responsive Web Designs</a>”, I noted that one of the first things I look for when trying to determine whether or not a responsive web design is “mobile first” is whether or not it has a strategy for handling the IMG tag.</p>
<p>A recent Smashing Magazine <a href="http://www.smashingmagazine.com/2011/07/22/responsive-web-design-techniques-tools-and-design-strategies/">round up of responsive web design techniques</a> included several new approaches for handling IMG tags which makes it the perfect time to dig into this problem and the potential solutions in more depth.</p>
<h3>Why IMG Tags Suck for Responsive Web Design</h3>
<p>If you want your site to load as quickly as possible, you do want to deliver larger files than are needed. Many responsive web design sites provide mobile devices images at sizes appropriate for desktop and ask the mobile device to resize the image.</p>
<p>In my research, I found nearly <a href="http://www.cloudfour.com/css-media-query-for-mobile-is-fools-gold/">80% decrease in file size by delivering images at the actual size</a> they were going to be used on a mobile device.</p>
<p>So what’s the problem with the IMG element in responsive designs? Unlike CSS images which can provide different source files based on screen resolution using media queries, IMGs have a single source attribute.</p>
<h3>What are Responsive IMGs?</h3>
<p>Responsive IMGs are images delivered using the HTML IMG tag that come from different sources depending the screen size. There are many different techniques for accomplishing Responsive IMGs.</p>
<p>As far as I can tell, Scott Jehl first coined the phrase <a href="http://filamentgroup.com/lab/responsive_images_experimenting_with_context_aware_image_sizing/">Responsive Images</a> to describe a javascript solution to the img source problem. He also referred to Responsive IMGs as a general term <a href="http://twitter.com/#%21/scottjehl/status/95505111572418561">recently</a> so I’m hopeful he doesn’t mind the fact that I’m extending his definition to describe any technique that attempts to provide images at an appropriate size for a responsive design.</p>
<h3 id="challenges">Responsive IMGs Challenges</h3>
<p>There are some common challenges that any Responsive IMG technique will face. As we review the various techniques that have been proposed, we need to keep these challenges in mind.</p>
<h4>Minimum Bar: Start with Mobile, No Extra Downloads</h4>
<p>Scott Jehl set a <a href="http://twitter.com/#%21/scottjehl/status/95505111572418561">minimum bar for Responsive IMGs</a> by stating they must do the following:</p>
<ol>
<li>Start with mobile img</li>
<li>Upgrade to larger size without downloading both</li>
</ol>
<p>Both of these are worthy and necessary goals.</p>
<h4 id="firstload">The First Page Load Problem</h4>
<p>Any solution that relies on client-side scripting to make a decision about what image source to display will suffer from a first page load problem. The first time someone visits a site, the server won’t know what size image to provide.</p>
<p><img class="aligncenter size-full wp-image-1054" title="unknown-vessel" src="http://www.kabayview.com/wp-content/uploads/2011/11/unknown-vessel.jpg" alt="responsive images 1" width="500" height="375" /></p>
<p>Image from Bryan Rieger’s <a href="http://www.slideshare.net/yiibu/muddling-through-the-mobile-web">Muddling Through the Mobile Web</a> presentation, photo by <a href="http://www.flickr.com/photos/wscullin/3770015203">wscullin</a>, licensed under <a href="http://creativecommons.org/licenses/by/2.0/">Creative Commons</a>.</p>
<p>If javascript is added that determines what image size is appropriate, then this information can be retained for the user session via cookies or similar techniques. In theory, on subsequent requests the server can make a decision about what size image to include in IMG tag.</p>
<p>FWIW, the speed of first load is a big deal. The speed of a person’s first experience can dictate their impression of a product and company. Google, Yahoo and others have talked about how minor speed differences makes a big difference in usage of their products.</p>
<h4 id="raceconditions">Rendering Race Conditions</h4>
<p>Techniques that rely on adjusting the image source attribute via javascript need to make sure that the modification happens before the image requests start.</p>
<p>Browser makers have done a lot of work to download as many assets as possible at the same time. Usually this is a good thing. But in the case of responsive imgs, the javascript needs to evaluate what size image to retrieve before any image requests start.</p>
<p>A lot of earlier work was done using dynamic base tags. This worked when the javascript was inline in the head tag, but failed to prevent images from downloading twice when an external javascript file is used.</p>
<p>The upshot is that nearly every client side technique requires deep understanding of the order in which different browsers process and download assets. Or more realistically, each approach needs to be tested extensively.</p>
<h4 id="cdn_caching">Content Delivery Networks and Caching</h4>
<p>When you deliver different size images at the same url, you can run into problems with CDNs and other caching at the edge of the network. If the first person to request an image is on a mobile phone, people who follow via the same CDN or cache will also see the mobile-optimized image even if they are on desktop unless consider CDNs in your strategy.</p>
<h3 id="futurefriendly">Future Friendly Responsive IMGs</h3>
<p>If we accept that the “quantity and diversity of connected devices—many of which we haven’t imagined yet—will explode”, then we need to consider look for solutions that are <a href="http://futurefriend.ly/">future friendly</a>. In addition to the current experimentation, we need to start thinking about what a long term solution might look like.</p>
<p>For example, many of the early solutions for Responsive IMGs consist of two size images: one for desktop and one for mobile screen sizes. Will two image sizes really suffice for all of the devices that are coming?</p>
<p>Also, a lot of the solutions right now tackle one part of the problem. They may tackle the client side changes to switch the image source, but leave as an exercise for the developer to figure out how image resizing will be handled. For shared libraries, limited scope makes sense.</p>
<p>But as we look at what systems will need to do to be successful in the future, we need to think about what we want out of both the server and client side.</p>
<p>Here are some of the things that I think a future friendly technique will need to consider:</p>
<ul>
<li id="arbitrarysize"><strong>Support arbitrary image resizing</strong> — We cannot anticipate what screen sizes may be coming. We need systems that handle image resizing automatically and support any arbitrary size needed for a particular page.</li>
<li id="artdirection"><strong>Art direction can override automatic resizing</strong> — Not every image can be resized without losing the meaning of the image. Sometimes cropping an image may work better than resizing it. Automatic tools need to easily support manual override.</li>
</ul>
<p><img class="aligncenter size-full wp-image-1055" title="unreadable-image" src="http://www.kabayview.com/wp-content/uploads/2011/11/unreadable-image.png" alt="unreadable image" width="500" height="375" /></p>
<ul>
<li id="highres"><strong>Support for higher resolution displays</strong> — What do we do with the iPhone 4’s <a href="http://www.apple.com/iphone/features/retina-display.html">retina display</a>and other devices sharing similar high resolution screens? It is an open question about whether we should deliver higher resolution images to those devices given the performance hit that will occur if the person is on a slow connection.But regardless of how we chose to handle it right now, it is clear that the trend towards more pixels per inch on displays is not going away. If anything, we’re seeing indicators that higher density will soon be available on desktop displays as well.This means that our current definition of what is a large image for web is probably too small for future devices. With that in mind, it probably makes sense for systems to accept the highest resolution image possible—even if that resolution isn’t currently being used—so that when new devices become available the high resolution source is already available and hasn’t been lost.</li>
<li id="speed"><strong>Connection speed should be part of the criteria</strong> — We can be much smarter about the size of the image we deliver if we can tell something about the network connection. We need an easier way to get at this information.</li>
<li id="new-img-tag"><strong>A replacement for the IMG tag?</strong> — All of the responsive image solutions are attempting to deal with the fact that the image tag has only a single source. There have been various proposals recently to take a new look at what the tag should be and see if we can find a long term replacement.</li>
</ul>
<p>That’s my short list. <strong>What would you add?</strong></p>
<p>In part 2, I’ll take a closer look at the current alternatives for responsive imgs and which ones hold the most promise.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kabayview.com/responsive-web-design/responsive-imgs-%e2%80%94-part-1/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Type study: Sizing the legible letter</title>
		<link>http://www.kabayview.com/typography/type-study-sizing-the-legible-letter</link>
		<comments>http://www.kabayview.com/typography/type-study-sizing-the-legible-letter#comments</comments>
		<pubDate>Mon, 14 Nov 2011 15:33:29 +0000</pubDate>
		<dc:creator>Lynda Damiata</dc:creator>
				<category><![CDATA[Typography]]></category>

		<guid isPermaLink="false">http://www.kabayview.com/?p=1040</guid>
		<description><![CDATA[November 9, 2011 &#124; blog.typekit.com :: Type study is an ongoing series of guest posts about typography on the web. In this article, Ethan Marcotte dishes up advice on font size. Yes, it’s true. This is a blog entry about sizing text for the web. …look, I know you’re still out there. I can hear <a href='http://www.kabayview.com/typography/type-study-sizing-the-legible-letter'> [read more]</a>]]></description>
			<content:encoded><![CDATA[<p>November 9, 2011 |<br />
<a href="http://blog.typekit.com/" target="_blank">blog.typekit.com</a> ::<br />
<em>Type study is an ongoing series of guest posts about typography on the web. In this article, Ethan Marcotte dishes up advice on font size.</em></p>
<p>Yes, it’s true. This is a blog entry about sizing text for the web.</p>
<p>…look, I know you’re still out there. I can hear you breathing.</p>
<p>Sure, sizing text isn’t the most glamorous topic. What’s more, it can get downright contentious, with camps forming around their favorite units of measurement. The truth is, each approach has its own unique strengths and limitations. So below, let’s dive into a few popular methods, discuss them with a bit of equanimity, and wrap up this little essay with a better understanding of our options for <code>font-size</code>.</p>
<h2>Our old friend, the pixel</h2>
<p>Let’s dive in with a quick little demo. To start us off, I pulled a short passage from <a href="http://www.gutenberg.org/ebooks/55" target="_blank">an old, favorite book</a>, marked it up in some basic HTML5, and applied some light CSS. If you’d like, you can view <a href="http://ethanmarcotte.com/fontsizing/example-px.html" target="_blank">my little page</a>.</p>
<p><img class="aligncenter size-full wp-image-1041" title="article-example" src="http://www.kabayview.com/wp-content/uploads/2011/11/article-example.jpg" alt="article example" width="560" height="464" /></p>
<p>Now, sharp-eyed reader that you are, you’ve probably noticed the markup’s as modest as the design:</p>
<pre>&lt;article&gt;
  &lt;header&gt;
    &lt;h1&gt;
      &lt;img src="dorothy.png" alt="" /&gt;A Brief Excerpt from &lt;cite&gt;The Wonderful Wizard of&amp;nbsp;Oz&lt;/cite&gt;
    &lt;/h1&gt;
    &lt;h2&gt;by &lt;a href="#"&gt;L. Frank Baum&lt;/a&gt;&lt;/h2&gt;
  &lt;/header&gt;

  &lt;div&gt;
    &lt;p&gt;&lt;b&gt;The Lion hesitated&lt;/b&gt; no longer, but drank till…&lt;/p&gt;
    …
  &lt;/div&gt;&lt;!-- /end .article-body --&gt;

  &lt;footer&gt;
    &lt;p&gt;Words by …&lt;/p&gt;
  &lt;/footer&gt;
&lt;/article&gt;</pre>
<p>Our page is essentially one big <code>article</code> element, which contains:</p>
<ol>
<li>A <code>header</code> to house the headline (<code>h1.main-title</code>) and byline (marked up oh-so-imaginatively as <code>h2.byline</code>).</li>
<li>The primary text is contained inside a <code>div</code> with a class of <code>article-body</code>.</li>
<li>Finally, a <code>footer</code> element rounds out the copy with some attribution.</li>
</ol>
<p>Nothing too fancy, right? Well, the styling’s just as unassuming. Now, since this is an article about font sizing, let’s not worry our pretty little heads about layout. Instead, let’s focus on the fonts:</p>
<pre>body {
  font: normal 16px/24px adobe-text-pro, Cambria, Georgia, "Times New Roman", Times, serif;
}

.main-title {
  font: normal 30px/36px abril-display, Palatino, Georgia, Times, serif;
}

.main-title cite {
  font-size: 42px;
  line-height: 50px;
}

.article-body {
  font-size: 18px;
}

.caps,
figure,
footer {
  font-size: 14px;
}</pre>
<p>From the outset, it’s obvious the page relies heavily on <a href="https://typekit.com/fonts/adobe-text-pro?utm_source=typekit-blog&amp;utm_medium=blog&amp;utm_content=111108&amp;utm_campaign=education">Adobe Text Pro</a> set on the <code>body</code>, with <a href="https://typekit.com/fonts/abril-display?utm_source=typekit-blog&amp;utm_medium=blog&amp;utm_content=111108&amp;utm_campaign=education">TypeTogether’s elegant (and new!) Abril Display</a> prettying up our <code>.main-title</code> headline. And with those defaults established, the rest of the CSS is dedicated to specifying a few different font sizes: five rules, five different <code>font-size</code> values, each set in pixels. And that’s basically it.</p>
<p>Easy, right? I think that’s half the appeal of the mighty pixel, actually: just how <em>easy</em> it is to use. We can transfer a few pixel values from Photoshop into CSS, and — <em>voilà</em> — your work’s nearly finished. But efficiency aside, I think there’s something appealing about the promise of <em>control</em> that comes with declaring a few quick pixel values, a control that’s so darn appealing to us designers. But for all its strengths, <code>px</code> isn’t the best game in town.</p>
<p>In fact, there’s one well-known drawback to sizing type in pixels: Internet Explorer’s “Text Size” tool (<a href="http://simplebits.com/notebook/2008/03/25/ie8-2/">still</a>) won’t resize any text set in pixels. Now, it’s true that many desktop browsers, including more recent versions of <acronym title="Internet Explorer">IE</acronym>, include some form of <a href="https://en.wikipedia.org/wiki/Page_zooming">page zoom</a>, which can magnify the size of your entire design, including its text. But older versions of <acronym title="Internet Explorer">IE</acronym> are, alas, still out there.</p>
<p>Moreover, exploring alternatives to the venerable pixel might result in some real, practical benefits. Ever built a menu that allowed the user to dynamically change the size of text on a page? I’ve worked on a few, including <a href="http://bostonglobe.com/">one that launched recently</a>. If your design’s universally set in pixels, each text size “level” would require you to redeclare sizes for every <code>px</code>-based element of your design. So it’s very possible that on some projects, pixels simply won’t scale. (Pun unfortunate, but intended.)</p>
<p>Now that I’ve stepped off my soapbox, let’s take a look at a slightly more proportional alternative, a unit of measurement that <em>does</em> play nicely with resizing: namely, <a href="https://en.wikipedia.org/wiki/Em_%28typography%29">the <code>em</code></a>.</p>
<h2>Becoming context-aware with ems</h2>
<p>Because I’m a sucker for nostalgia, let’s revisit our <code>body</code> rule. Here’s what we’re currently working with:</p>
<pre>body {
  font: normal 16px adobe-text-pro, Cambria, Georgia, "Times New Roman", Times, serif;
}</pre>
<p>Before we start getting more proportional, let’s tweak it ever so slightly:</p>
<pre>body {
  font: normal 100% adobe-text-pro, Cambria, Georgia, "Times New Roman", Times, serif;
}</pre>
<p>Catch the difference? All we’ve done is change the <code>font-size</code> value to <code>100%</code>, setting our document’s base type size to the browser’s default, which is usually <code>16px</code>. As a result, we’re left with a flexible baseline, a point of reference from which we can size our text up or down using relative units of measurement—specifically, the <code>em</code>.</p>
<p>It’s worth mentioning that some folks prefer setting the <code>body</code> to a <code>font-size</code> of <code>62.5%</code>, as this gives us a relative baseline of approximately <code>10px</code>—which can make relative font sizing much, much easier. Richard Rutter, author of <a href="http://clagnut.com/blog/348/">the original <code>62.5%</code> technique</a>, wrote <a href="http://www.alistapart.com/articles/howtosizetextincss">a fantastic article for <em>A List Apart</em></a> recommending <code>100%</code> as a better baseline, one that ensured more consistent cross-browser results.</p>
<p>But I digress. Regardless of what your baseline preference might be, our job at this point is to convert our pixel-based <code>font-size</code> values into their <code>em</code> equivalents. To do so, we’ll need to do a teensy bit of math: we’ll simply take the <em>target</em> pixel value we’ve already set, and then divide it by the <code>font-size</code> of its containing element — in other words, its <em>context</em>. The <em>result</em> is our desired <code>font-size</code>, but converted neatly into relative terms, which we can then drop directly into our CSS as <code>em</code>s.</p>
<p>In other words, relative font sizes can be calculated like so:</p>
<blockquote><p>target ÷ context = result</p></blockquote>
<p>Let’s take a quick example. Remember our main headline?</p>
<pre>.main-title {
  font: normal 30px/36px abril-display, Palatino, Georgia, Times, serif;
}</pre>
<p>In order to turn the headline’s <code>30px</code> size into an <code>em</code>-based value, we need to define it in relationship to its context — that is, the <code>font-size</code> of the <code>body</code> element. Let’s assume our <code>font-size: 100%</code> is roughly equivalent to <code>16px</code>. So let’s plug our <code>.main-title</code>’s target font size (<code>30px</code>) and its context (<code>16px</code>) into our formula:</p>
<blockquote><p>30 ÷ 16 = 1.875</p></blockquote>
<p><a href="https://www.youtube.com/watch?v=W45DRy7M1no">Boom</a>. <code>30px</code> is 1.875 times greater than <code>16px</code>, so our font size is <code>1.875em</code>.</p>
<p>Now you may recall that the book’s title was wrapped in a <code>cite</code> element <em>inside</em> our main headline, and sized a bit larger than the text that preceded it:</p>
<pre>.main-title cite {
  font-size: 42px;
}</pre>
<p>If we want to convert that <code>42px</code> to <code>em</code>s, it’s important to note that <em>our context has changed</em>. Since we’ve set a <code>font-size</code> on our <code>.main-title</code> headline, the <code>font-size</code> of any elements within need to be expressed in relation to that value. In other words, our <code>cite</code>’s target value of <code>42px</code> needs to be divided not by <code>16px</code>, the <code>body</code>’s <code>font-size</code>, but by the <code>30px</code> we set on our headline:</p>
<blockquote><p>42 ÷ 30 = 1.4</p></blockquote>
<p>And that’s it. With a little bit of contextual awareness, we’re left with a proportional <code>font-size</code> for our <code>.main-title</code> headline, as well as the <code>cite</code> inside it:</p>
<pre><code>.main-title { font: normal 1.875em/36px abril-display, Palatino, Georgia, Times, serif; /* 30 / 18 */ } .main-title cite { font-size: 1.4em; /* 42 / 30 */ line-height: 50px; } </code></pre>
<p>(I personally like including the <code>target</code> and <code>context</code> values as comments in my CSS, usually off to the right of the relevant property. I’ve found it makes revising these relative values much easier, especially since the origin of a value like <code>1.875em</code> might not be immediately apparent.)</p>
<p>Sizing text proportionally simply requires a little contextual awareness. And that applies to setting our document’s <code>line-height</code>, too. For example:</p>
<pre>.main-title {
  font: normal 1.875em/36px abril-display, Palatino, Georgia, Times, serif;  /* 30 / 18 */
}

.main-title cite {
  font-size: 1.4em;  /* 42 / 30 */
  line-height: 50px;
}</pre>
<p>The line height in both rules — <code>36px</code> for <code>.main-title</code>, and <code>50px</code> for the <code>cite</code> within it — are still in pixels, which means the <code>line-height</code> values won’t scale along with their respective relative <code>font-size</code> values. Presumably because they hate freedom.</p>
<p>But thankfully, we can quickly move those pixel-based values into something more proportional. But this time, our context is the <code>font-size</code> itself, our target the pixel-based <code>line-height</code>s. So with that in mind, let’s do a little bit more math:</p>
<blockquote><p>36 ÷ 30 = 1.2</p>
<p>50 ÷ 42 = 1.2</p></blockquote>
<p>There we are: both <code>.main-title</code> and the <code>cite</code> within it have a <code>line-height</code> of 1.2. And since the two elements share the same line height, we can actually just set the value once on the higher element, and let its descendants inherit it:</p>
<pre>.main-title {
  font: normal 1.875em/1.2 abril-display, Palatino, Georgia, Times, serif;  /* 30 / 18; 36 / 30 */
}

.main-title cite {
  font-size: 1.4em;  /* 42 / 30 */
}</pre>
<p>That is, as the kids say, that. What’s more, we don’t actually need to add units to the <code>line-height</code>, as <a href="http://meyerweb.com/eric/thoughts/2006/02/08/unitless-line-heights/">Eric Meyer’s covered</a> so ably before. Instead, we can leave that proportional value in place, <em>sans</em> pixels, percentages, or <code>em</code>s.</p>
<p>But yes! Context rocks! And armed with that knowledge, we can turn to our remaining pixel-based rules:</p>
<pre>.article-body {
  font-size: 18px;
}

.caps,
figure,
footer {
  font-size: 14px;
}</pre>
<p>As before, with some simple math and an awareness of a given element’s context, we can turn those values into oh-so-flexible <code>em</code>s:</p>
<pre>.article-body {
  font-size: 1.125em;  /* 18 / 16 */
}

/* figure and .caps are children of .article-body, so their context is 18px */
figure,
.caps {
  font-size: 0.777777778em;  /* 14 / 18 */
}

/* The footer's context is the body element, so we'll use 16px here */
footer {
  font-size: 0.875em;  /* 14 / 16 */
}</pre>
<p>And with that, we’ve successfully moved <a href="http://ethanmarcotte.com/fontsizing/example-em.html">our page</a> beyond the pixel. The design’s identical to <a href="http://ethanmarcotte.com/fontsizing/example-px.html">the original <code>px</code>-based version</a>, but considerably more flexible, proportional, and accessible.</p>
<h2>Meet the rem</h2>
<p>The <code>em</code> is powerful voodoo indeed, but it’s not without its limitations. Obviously, it requires an awareness of an element’s context, which can be unwieldy at best. What’s more, it can complicate moving modules within your design, as their <code>font-size</code> might be tied to a specific position in the document’s hierarchy. So for especially complicated, content-heavy sites, this could potentially require some work.</p>
<p>Thankfully, there’s been some traction on improving our old friend the <code>em</code>. Introduced in the CSS3 specification, <a href="http://www.w3.org/TR/css3-values/#rem-unit">the <code>rem</code></a> behaves much like the <code>em</code>: it’s a relative unit of measurement, sizing text up or down from a baseline value. But the <code>rem</code> is sized relative to the root of your document—in other words, the value set on the <code>body</code> element.</p>
<p>Here’s what our CSS looks like, once we switch everything over to <code>rem</code>s:</p>
<pre>body {
  font: normal 100%/1.5 adobe-text-pro, Cambria, Georgia, "Times New Roman", Times, serif;
}

.main-title {
  font: normal 1.875rem abril-display, Palatino, Georgia, Times, serif;  /* 30 / 16 */
}

.main-title cite {
  font-size: 2.625rem;  /* 42 / 16 */
}

.article-body {
  font-size: 1.125rem;  /* 18 / 16 */
}

.caps,
figure,
footer {
  font-size: 0.875rem;  /* 14 / 16 */
}</pre>
<p>This is still relative font sizing, so we’re still using our <code>target ÷ context</code> formula. But now, our context is <code>16px</code> <em>throughout the CSS</em>. That’s right: no more tracking various context values, worrying about which element’s inheriting which <code>font-size</code> value and going slowly mad. And as someone who hates math, this consistency is kind of exciting.</p>
<p>Sadly, support for the <code>rem</code> is still evolving. Firefox 3.6+, Chrome, Safari 5, and <acronym title="Internet Explorer 9">IE9</acronym> all support the rem. (And IE9+ even resizes text set in <code>rem</code>s!) Unfortunately, while support’s broad, that doesn’t mean it’s universal. So if you’re supporting a significant number of browsers beyond that list, you might need to declare a fallback in pixels:</p>
<pre>body {
  font: normal 100% adobe-text-pro, Cambria, Georgia, "Times New Roman", Times, serif;
}

.main-title {
  font: normal 30px abril-display, Palatino, Georgia, Times, serif;
  font-size: 1.875rem;  /* 30 / 16 */
}

.main-title cite {
  font-size: 42px;
  font-size: 2.625rem;  /* 42 / 16 */
}

.article-body {
  font-size: 18px;
  font-size: 1.125rem;  /* 18 / 16 */
}

.caps,
figure,
footer {
  font-size: 14px;
  font-size: 0.875rem;  /* 14 / 16 */
}</pre>
<p>Sexy? Maybe not. But <a href="http://ethanmarcotte.com/fontsizing/example-rem.html">this hybrid approach</a> leaves us with resizable text in <code>rem</code>-compliant browsers, with a pixel-based fallback for older ones — a match made in heaven.</p>
<h2>Pixels, ems, and rems—oh my!</h2>
<p>Whether you prefer slinging <code>px</code> or <code>em</code>, or have started dabbling in <code>rem</code> — each approach has its unique drawbacks and strengths, its own unique contributions to the project you’re working on.</p>
<p>Pixels afford a high degree of precision, but at the expense of versatility. And while <code>em</code>s offer us both the control we crave and the accessibility we need, there’s a certain amount of overhead with the contextual math involved. I hope better browser support means <code>rem</code>s offer a way forward — but personally, those <code>px</code>-based fallbacks don’t feel like an appropriate trade-off. Hopefully, we’ll be able to move past those fallbacks soon.</p>
<p><img class="alignleft size-full wp-image-1050" title="ethan_marcotte" src="http://www.kabayview.com/wp-content/uploads/2011/11/ethan_marcotte.png" alt="Ethan Marcotte" width="75" height="75" /><a href="http://twitter.com/beep">Ethan Marcotte</a> is an independent designer/developer who’s passionate about web standards, gorgeous design, and how the two intersect. He’s perhaps best known for starting that whole “<a href="http://www.alistapart.com/articles/responsive-web-design">responsive web design</a>” thing, and even wrote <a href="http://www.abookapart.com/products/responsive-web-design">a little book on the topic</a>.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kabayview.com/typography/type-study-sizing-the-legible-letter/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lea Verou &#124; CSS3 Secrets: 10 things you might not know about CSS3 &#124; Fronteers 2011</title>
		<link>http://www.kabayview.com/css3/lea-verou-css3-secrets-10-things-you-might-not-know-about-css3-fronteers-2011</link>
		<comments>http://www.kabayview.com/css3/lea-verou-css3-secrets-10-things-you-might-not-know-about-css3-fronteers-2011#comments</comments>
		<pubDate>Fri, 11 Nov 2011 17:19:55 +0000</pubDate>
		<dc:creator>Lynda Damiata</dc:creator>
				<category><![CDATA[CSS3]]></category>

		<guid isPermaLink="false">http://www.kabayview.com/?p=1035</guid>
		<description><![CDATA[Lea Verou &#124; CSS3 Secrets: 10 things you might not know about CSS3 &#124; Fronteers 2011 from Fronteers on Vimeo. Transcript Lea Verou: [0:05] Hello, everyone. Thank you for being here today. This talk is a bit different from other talks you might be used to. It doesn&#8217;t have a topic. Sure, it&#8217;s about CSS3, <a href='http://www.kabayview.com/css3/lea-verou-css3-secrets-10-things-you-might-not-know-about-css3-fronteers-2011'> [read more]</a>]]></description>
			<content:encoded><![CDATA[<p><iframe src="http://player.vimeo.com/video/31719130?title=0&amp;byline=0&amp;portrait=0" frameborder="0" width="400" height="225"></iframe></p>
<p><a href="http://vimeo.com/31719130">Lea Verou | CSS3 Secrets: 10 things you might not know about CSS3 | Fronteers 2011</a> from <a href="http://vimeo.com/fronteers">Fronteers</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<h3>Transcript</h3>
<p>Lea Verou: [0:05] Hello, everyone. Thank you for being here today. This talk is a bit different from other talks you might be used to. It doesn&#8217;t have a topic. Sure, it&#8217;s about CSS3, but it&#8217;s not about a specific CSS3 feature, and it&#8217;s not a general introduction. It&#8217;s for people who have done some work with CSS3 already and just wanted to learn a few things to do it better.</p>
<p>[0:31] It&#8217;s little bits and pieces I&#8217;ve discovered while working with CSS3, a bunch of different features. It&#8217;s kind of like 10 different small talks, the first being &#8211; oh, also, I think I have to warn you because I know many of you might be allergic, there might be traces of JavaScript, not many, don&#8217;t worry. It&#8217;s not too much, but there can be some traces.</p>
<p>[1:05] For the first part, I think most of you have worked with a basic case of at least basic transitions. For example, something like this. That&#8217;s like the very basic transition. I&#8217;m pretty sure you probably know that you can specify some ease-in keywords to set how the transition progresses. This is the default one, which is called ease, but there are others like ease-in, for example, which starts slowly and then becomes faster or ease-out, which is like the opposite.</p>
<p>[1:39] Also, all these keywords can be expressed in a more detailed form that allows us to do even more easing functions that are allowed by the keywords. For example, the default ease keyword can also be written as cubic-bezier(.25, .1, .25, 1), I think. Yes. But this function can be used to express many, may different effects.</p>
<p>[2:12] It&#8217;s a bit hard to picture how it works if you don&#8217;t see a graphic or a presentation, so I&#8217;ve coded this tool , in which you drag the handles and you can preview the results. Essentially, the way cubic-bezier works is that the first two parameters are the coordinates of this point. As you can see, if I move it, they change. The second ones are the coordinates of these points.</p>
<p>[2:41] A very interesting thing you can do with this function, except just expressing easing, is that you can drag it like this so that it moves above 100%. The vertical axis is the progression of the property and the horizontal axis is the progression of the time. If you move it above 100% on the vertical axis, what do you think will happen? The transition progresses above 100%, but eventually, it has to snap back to 100 % here.</p>
<p>[3:18] Let me make my cursor bigger so that I can show things.</p>
<p>[3:26] OK, but it has to snap back here at 100%, so essentially what that thing is &#8211; getting above 100 and then snapping back &#8212; it&#8217;s a bounce. We can preview it here. It&#8217;s the pink one. Do you see that it went beyond the ending point and then it snapped back? We can make the bounce even more intense if we move this even more to the top. As you can see now, the bounce is much more intense.</p>
<p>[4:02] We can do many kinds of interesting effects with this. This is something like the JavaScript warning I had on the cover. It uses a scale transform, which bounces, so it scales a bit more than the end value, and then it snaps back.</p>
<p>[4:20] What&#8217;s way more cool, although less useful than those, is when you actually apply bouncing to colors. For example, these colors allow me to change the background of the slide when I click on them. It has a bouncing transition already, and it&#8217;s a quite intense bounce, as you can imagine, because the last value is five, so the second point is much higher.</p>
<p>[4:45] Let&#8217;s try to transition from this value for this color to gray. It moves back to green and then it snaps to gray. It&#8217;s very interesting I think. Of course, if you try to transition to edge colors like, for example, to red, you won&#8217;t see any bounce because there&#8217;s no point in moving beyond 2, 50, 50. There&#8217;s no color that&#8217;s like RGB 300.</p>
<p>This is supported by every modern browser, every browser that supports transitions. There used to be a problem with WebKit, and currently, if you try to test it on Chrome or Safari, it won&#8217;t work. It will drop the value. That&#8217;s because in the first versions of the spec, values &#8211; cubic-bezier values &#8212; out of the 0: [5:13] 1 range weren&#8217;t allowed.</p>
<p>[5:35] If you see the spec right now, it says that they&#8217;re still not allowed, but the dev version of the spec that&#8217;s not yet published perfectly allows them. That&#8217;s why Opera, Firefox, and now IE10 support them. WebKit did not, but recently a patch was landed. If you test in the nightlies, you can actually test that implementation. I&#8217;m hoping that soon it will be in some stable release.</p>
<p>[6:05] The second thing is about border radius, and you might be thinking, &#8220;What is there to know about border radius? I know everything about border radius. I&#8217;ve done rounded corners.&#8221; Well, yeah, I&#8217;m pretty sure you&#8217;ve used border radius to do rounded corners and maybe you&#8217;ve actually done this, as well, using two lengths to have different vertical and horizontal radiuses.</p>
<p>[6:31] The problem with doing ellipses in this way is that it works fine when the dimensions are fixed, but what happens if the content changes? Usually, when we make a website, we don&#8217;t know the exact content in advance. It&#8217;s usually dynamic, so what happens if you try to resize this ellipse? Let&#8217;s try to do that.</p>
<p>[6:54] You can see the resulting shape is horrible. It doesn&#8217;t even have a name. I don&#8217;t know what to call this thing. It&#8217;s ugly as hell. What do we do to actually make it re-size properly and still stay an ellipse? It turns out, we can actually use percentages in border radius. They define the vertical and horizontal radius at the same time, and that horizontal one depends on the width and the vertical one depends on the height.</p>
<p>[7:26] Essentially, what 50% means is horizontally, give me 50% of the width and vertically, give me 50% of the height so when we re-size this, it&#8217;s fine. It works great. It&#8217;s a true ellipse. We don&#8217;t see any straight edges or nothing.</p>
<p>[7:45] This actually has pretty good support. There are some glitches in browsers, but essentially, the latest version of every browser supports it. Opera used to have a problem with it before version 11.5. Even though it parsed it and it allowed it, the percentages used to depend on the window dimensions.</p>
<p>[8:10] I don&#8217;t know who thought of that. It was really horrible, but I&#8217;m so glad they fixed it. I reported it two years ago, and they fixed it after two years &#8212; yay! Well, to be fair, they usually fix bugs more quickly than that, I don&#8217;t want to bash Opera or anything. They&#8217;re great.</p>
<p>[8:33] Multiple outlines, I&#8217;m sure you&#8217;ve all used border or the outline property if you want to do two borders at once, but what happens if you want more? You can&#8217;t have two borders, you can&#8217;t have two outlines, so what happens in this case? Usually, you have to use multiple HTML elements, which kind of sucks.</p>
<p>[9:00] Before I show you how to do that with pure CSS, let&#8217;s talk about something else which is kind of relevant. Here is a basic box shadow without any offset. You can hardly see it, I&#8217;m sure. It doesn&#8217;t show very much. That&#8217;s because it has a blur of five pixels, which makes it very not visible. I can show it to you if I give it some offset &#8212; like this &#8212; and now you can see it. We actually didn&#8217;t want it to have any offset, so it&#8217;s not very visible.</p>
<p>[9:36] What we can do to make it more visible is there&#8217;s a fourth length in the box shadow definition called spread. This length enlarges or shrinks the shadow by the length you specify. For example, by default it&#8217;s zero, but you can specify one pixel, and now it&#8217;s one pixel bigger on every side. Let&#8217;s make it even bigger. You can see how it gets enlarged. Of course, this also applies to inset shadows.</p>
<p>[10:08] This is the default, this one. And then, we can start enlarging it or even make it bigger with a negative spread, which doesn&#8217;t show much here, but it will show if we move it a bit. Can you see that now it&#8217;s much smaller? This actually solves the problem that I see posted on stack overflow so frequently. I think there are 50 questions that ask the same thing, &#8220;How do we do a shadow that&#8217;s on just one side?&#8221;</p>
<p>[10:43] Well, that&#8217;s how we do a shadow that&#8217;s just on one side, with a spread value. We just have to move it and position it properly. It&#8217;s not perfect here. I have to make it a bit bigger, kind of like this, and then move it a bit to the top, but I&#8217;ll get there. That&#8217;s how you do this effect. And, yes, it&#8217;s quite useful.</p>
<p>[11:11] You might be wondering what do shadows have to do with what I&#8217;m discussing. Well, let&#8217;s get back to the original case where we had no offsets, and let&#8217;s give it a positive spread and make the blur zero. What do we have here? We have an outline essentially. We have something that works like an outline. We can even make the widths different on every side by moving it &#8212; like this.</p>
<p>[11:44] Essentially, we can use box shadow to fake outlines as long as the blur is zero and the spread is positive. Why can we do multiple outlines with box shadow? Because we can have unlimited box shadows. We can just add another one, and it will still show great.</p>
<p>[12:06] Let&#8217;s add a red outline, for example. We can add unlimited outlines. For example, in this case, I have four outlines. You might be thinking, &#8220;OK, I might be using a shadow property to add outlines, so what do I do if I actually want to add a shadow as well?&#8221; You can add a shadow as long as you give it at least this big of a spread, so that otherwise, it would be covered by the outlines you have.</p>
<p>[12:46] Let&#8217;s add a shadow with five pixels offset and the blur, five pixels. Remember, it needs this spread. Let&#8217;s make it red, and it needs a comma here. Here it is. If we want to make it even bigger, like it actually had a spread itself, we can just increase the spread even more like this.</p>
<p>[13:15] This is supported very well, at least in browsers that support box shadow. I&#8217;m not aware of any browser that supports box shadow and not that. I think some really old versions of Safari didn&#8217;t support multiple box shadows, but they&#8217;re not significant anymore.</p>
<p>[13:37] Another case that you probably used an overlay of some sort at some point. For example, if you want to create a model window and you don&#8217;t want the user to click on anything else because you want them to interact with your model window. You create an overlay that covers the whole thing, and it&#8217;s semi-transparent, and you put it on top of all your content except the model window.</p>
<p>[14:03] When the user tries to click on something else except the model window, it can&#8217;t, because his clicks are captured by the overlay. In this case, that effect is very useful, that every element captures mouse clicks and hovers and everything.</p>
<p>[14:24] Sometimes, we just use things decoratively and overlay them over other things, and we don&#8217;t want them to capture mouse events, we don&#8217;t want them to capture mouse-overs and clicks. For example, do you remember this old home page of Twitter that used to have this kind of like marquee of trending topics? On both edges, it had these little gradients, for example, here and here, and they were purely for styling purposes.</p>
<p>[15:01] They look quite nice because they make this fade out effect, but they introduce a problem. If you mouse-over these links in the center, you can see that they become white. However, if you mouse-over links that are in one of the edges &#8212; like here, for example &#8212; nothing happens because your mouse-over is captured by the gradients.</p>
<p>[15:24] Let&#8217;s see how big these gradients are. If we highlight them &#8212; they&#8217;re these parts. In these parts of the header, we couldn&#8217;t click or mouse-over links. How did they solve it? There&#8217;s this property called pointer-events, and it came from SVG. However, some browsers allow us to use it on HTML content.</p>
<p>[15:49] Essentially, this value, when used on HTML, it has two values, auto and none. Auto is the default behavior that the element captures mouse clicks, hovers, and everything. But if we give it the value of none, it&#8217;s like it doesn&#8217;t exist as far as the mouse is concerned.</p>
<p>[16:10] Let&#8217;s try hovering over a link again. As you can see, it works fine. Our pointer changes to a hand, the link gets highlighted, and if we tried, we could actually click on it. This is useful in yet another case. For example, assuming we wanted to create styled select menus, and we&#8217;ve actually applied all of our nice CSS3 on this select menu, and it would look nice if it wasn&#8217;t for this ugly arrow.</p>
<p>[16:41] We add a pseudo element to its label that adds an arrow on top of it, and now it looks the way we expected. I think it looks nicer than the default, but that&#8217;s just my opinion. If we try to click on this arrow, nothing happens. Of course, nothing happens because the arrow captures our click. It doesn&#8217;t go through the menu. If we click here, the menu opens, but if we click here, nothing. This is because the pointer-events is at its default value, which is auto. If we make it none, it starts working now, the menu opens, and it works perfectly like a select menu.</p>
<p>[17:26] The problem with pointer-events is that it&#8217;s not supported in every browser. Every browser supports it in SVG, but on HTML, it&#8217;s only supported by Firefox and WebKit. And an even bigger problem is that if we try to detect it to actually do something when it&#8217;s not there, like not include the arrow, for example, the default detection method that we usually try for detecting CSS properties doesn&#8217;t work.</p>
<p>[17:57] Usually, for detecting CSS properties, we check if the camel case version of the property is in the style object of some element. But, in this case, it&#8217;s a no-go. Why is that? Because in some browsers, like Opera, because they support the pointer-events property on SVG, they recognize it and they already have it on style elements, even though it won&#8217;t work on HTML.</p>
<p>Up to a while ago, this used to be an unsolvable problem, &#8220;How do we detect pointer-events?&#8221; It&#8217;s actually in the undetectable list that modernizer keeps. However, this clever guy called Martin [indecipherable 18: [18:20] 37] came up with a detection method, which essentially tries something and checks if it worked.</p>
<p>[18:42] He creates a dummy element, of course. He first tries the straightforward method only in one way. If it&#8217;s not there, it means it&#8217;s not supported, which makes sense. If it&#8217;s not there, it can&#8217;t be supported. If it is there, it doesn&#8217;t mean it is supported, but if it&#8217;s not, it&#8217;s not supported.</p>
<p>[19:01] If it is supported, he tries something else. He sets the property to a value that&#8217;s recognized and then to a value that shouldn&#8217;t be accepted, and checks afterward. It appends that the dummy element to the body because any element needs to appended to the document to have a computed style. Then, he gets the pointer-events property from the computed style and checks if it&#8217;s auto, and that removes the dummy element and returns what happened.</p>
<p>[19:34] He tested that thing in multiple browsers and it turned out, it worked. We can use that to add the class to the body element and do style changes if it&#8217;s not there, for example, include the arrow if it&#8217;s supported, not include the arrow if it&#8217;s not supported.</p>
<p>[19:48] Also, there&#8217;s a rudimentary peripheral we could do in JavaScript about this method. We could make a function that kind of simulates what pointer-events does, and the general idea is this. Don&#8217;t copy/paste this code, but it&#8217;s the general idea. You hide the element that got clicked and you don&#8217;t want it to receive pointer-events. You get the coordinates of the mouse click or the mouse-over, and then you get which element is at those coordinates. That&#8217;s why we hid our original element because if it still was there, we would just get that.</p>
<p>[20:25] After we found which element is there, we show our element again. We stop the event in any way. If we were actually using jQuery, like I&#8217;m doing in this example, we would also call a stop immediate propagation to not have any other event handlers get called. Then, we trigger the event on the object that was underneath.</p>
<p>[20:45] It&#8217;s not perfect, and I was actually not sure if I should show it because in most cases, you want to do things that can&#8217;t really be done with JavaScript. You can&#8217;t open a select menu with JavaScript by just sending a click event there. It doesn&#8217;t work this way. In some cases, I guess it could be useful.</p>
<p>[21:10] How many of you are tab people and use tabs when writing code instead of spaces? Great! We&#8217;re a lot. Kudos to all of you, and the ones that you use spaces should be ashamed. The ones of you that do the right thing and use tabs have probably noticed that when you post code snippets on your blog, for example, they look really ugly. Why is that? Because, for some reason, people that made browsers didn&#8217;t like tabs, so they made them huge to look ugly. We usually resort to converting our nice little tabs into spaces.</p>
<p>[21:57] However, in CSS3, we can actually control the size of the tab character by using the property tab-size. It&#8217;s the full value, of course, this horrible eight, which we can actually now control it and make it whatever we want. You usually would want to use four, but you can actually specify any value, even zero to completely remove indentation. But please don&#8217;t do that!</p>
<p>[22:25] If you&#8217;re a spaces person, this could still be useful for you. You could make it 999 and remove any code that uses tabs from the page. That&#8217;s actually the only example they have on MDN. I don&#8217;t know why. Was the property created for that? I hope not!</p>
<p>[22:49] Tab size is supported by Opera and Firefox. Unfortunately not by IE or WebKit yet, but it degrades very gracefully I think. You just get the default sizing. Yes, the code won&#8217;t look as pretty, but it will be readable.</p>
<p>[23:14] I&#8217;m sure you&#8217;ve all used this pseudo class, this CSS3 pseudo class, usually for zebra striping or styling like every third element differently, like I am doing here. I guess you know that the way it works is usually by setting &#8211; that the end gets different values starting from zero to infinity. The results that make sense get selected.</p>
<p>[23:40] For example, three x 0 = 1, so the first element gets selected, three x one = 3, so + 1, it&#8217;s 4, and so on. You probably also know that we have this last-child pseudo class that does exactly the same thing, but it starts counting from the end.</p>
<p>[24:04] You might also know, although you might not be able to think of many use cases, of a class called only-child that only selects elements that don&#8217;t have any siblings. For example, here, it didn&#8217;t select anything, but let&#8217;s start removing elements until we only have one, and now it got selected.</p>
<p>[24:23] This could actually be a very, very useful pseudo class if it wasn&#8217;t so restricted, if it didn&#8217;t only select elements that didn&#8217;t have any siblings, but it selected elements that had an exact number of siblings, whether they were before them or after them. For example, you want to select all the list items, but only if the list has five items in total. How do you do that?</p>
<p>[24:47] Let&#8217;s think of it as a first step to make only-child more general &#8212; let&#8217;s think a bit of what it consists of. Only-child doesn&#8217;t give us any functionality we didn&#8217;t already have with the other structural pseudo classes. Only-child is just this, it can be written as this, a first-child that&#8217;s also a last-child. Isn&#8217;t that what an only-child is? We can start by making the last-child pseudo class a bit more general.</p>
<p>[25:19] For example, let&#8217;s try this. Because essentially, what last-child is nth-last-child(1). We can change this to (2). Then, what does this do? It selects the first element only, but only if the total number of siblings are two. If we have three, nothing gets selected. If we have one, nothing gets selected, but if we have two, the first element gets selected.</p>
<p>[25:46] That&#8217;s almost what we wanted, but not exactly, because we wanted to select all elements. We didn&#8217;t want to select only the first one. That&#8217;s very easy at this point, because we just take the same thing and just use the sibling selector to select everything after it. As long as we can target the first one, we can target them all. Now, we effectively target all of the elements, but only if &#8211; and only if &#8211; the total count is two. If it&#8217;s one, nothing gets selected.</p>
<p>[26:23] We can even make it a bit more relaxed and only select elements if their total count is at least five. Remember how we do at least with these pseudo classes? It&#8217;s n + the number we want. Why? Because n starts from zero, so 0 + five = 5, one + five = 6. So it starts from five and goes all the way. It selects everything from five and afterward. Now, it will match all the elements as long as their total count is at least five. Now, no matter what I add, they still get matched.</p>
<p>[27:00] This is useful in a number of different cases because it kind of works like a media query for the DOM. It&#8217;s supported by every browser that supports CSS3 selectors, and CSS3 selectors were the first things to get supported. Of course, IE is a bit of a party-pooper here. They&#8217;re only supported by IE9 and after.</p>
<p>[27:25] Let me show you a bit of a practical example of this technique, one of the many cases it can be used. Assume you&#8217;re making a color palette application, like color for example or color lovers. These applications allow you to have defined color combinations. In this case, I&#8217;m not going to select the colors myself. That would be a bit too complex of a demo for a slide. They&#8217;re predefined. I&#8217;ll just add more colors by clicking addcolor.</p>
<p>[27:55] When I have two colors or one color, these controls look fine, but when I add the third color, they start looking bad. What can I do in this case? I can hide the text. If there are three or more, I use the same technique to hide the text. Now, they look fine again. The user doesn&#8217;t really need the text after this point because if he pressed those buttons two times, he already knows what they do.</p>
<p>[28:26] Let&#8217;s keep adding colors. They look fine at this point, but at some point, we&#8217;ll have problems again. We actually have the same problem. What do we do in this case? Well, I think it&#8217;s time to give up on the bright floating and just float both of them on the same side. We float all of them on the same side if the elements are at least nine. Now, it looks kind of better. Of course, it could look even better. We could put them in the center and make even more changes, but I wanted to keep this simple. Then, we can keep adding colors, and it will look fine forever.</p>
<p>[applause]</p>
<p>Lea: [29:18] Is that for the thing I&#8217;m going to present or for what I presented before? OK. Thank you very much. I&#8217;m sure most of you had some client at some point or a boss that wanted custom check-boxes or custom radio buttons, and they really insisted because they didn&#8217;t understand that those aren&#8217;t meant to be styled even in 2011.</p>
<p>[29:45] So you probably had to resort in some JavaScript solution with some dev, hopefully, with a top index of zero, so it was still accessible. But, some dev that if you clicked it, it kind of changed and it kind of emulated a check-box or a radio button. But the thing is, you can do the same thing with Purity SS.</p>
<p>[30:11] Here we have a default check-box. That&#8217;s just the default check-box that the browser renders. And the first step of this technique by Ryan Seddon, that, he&#8217;s an amazing guy, he came up with this, not me. First idea is to hide the check-box. And, actually I&#8217;m not sure if this is the best way to hide it because I headed a job with Derrick Featherstone yesterday, and it turned out that that&#8217;s not the best way to hide it accessibility-wise.</p>
<p>[30:42] It&#8217;s probably to use a text-indent of -900 or something or hide it another way like visibility hidden, maybe. Anyway, you hide it in a way that still makes it focusable. That&#8217;s what you should keep in mind. Don&#8217;t use display none. It should still be focusable. And we&#8217;re using this prefix here, root, because we only want this root to apply in browsers that support CSS3 selectors because we&#8217;re going to use CSS3 selectors afterward.</p>
<p>[31:15] And if it wasn&#8217;t supported, it means that browsers would in IE8 for example would hide the check-box, but it wouldn&#8217;t do the other things. So the user just wouldn&#8217;t have a check-box. The thing is we want regular check-boxes in IE8 because that&#8217;s what its users deserve, and we want nice-styled check-boxes in other browsers.</p>
<p>[31:40] The next step is to use the before pseudo-element of the label that&#8217;s after the check-box and add something. In this case I&#8217;m using a symbol, but that&#8217;s not really a good idea for a multiple of reasons. I&#8217;m just using a symbol here to keep things, to keep the demo simple. First of all, if you&#8217;re using a unicode symbol for this, it means that on Windows it might not show up. Many unicode symbols don&#8217;t show in other environments, in other browsers, in other operating systems.</p>
<p>[32:09] And also, some screen readers will actually pronounce this symbol which I don&#8217;t think you want to. It&#8217;s better to use an image and you can use different images for different states. It&#8217;s essentially the same idea. And this is the core of this technique. We&#8217;re using the checked pseudo-class to style, to change the styling only when the check-box is checked. And what&#8217;s the difference between the checked pseudo-class and the check, if we use the attribute selector for check?</p>
<p>[32:40] The attribute selector for check, that just selects check-boxes that were preselected when the HTML document was loaded, whether they are selected now or not. But the checked pseudo-class is dynamic and it only applies to check-boxes or radio buttons. Everything I&#8217;m saying also applies to radio buttons. It applies to check-boxes that are currently checked.</p>
<p>[33:02] So, essentially, now we can actually use it already like a regular check-box. I&#8217;m clicking it here now and it&#8217;s checked. I&#8217;m clicking it again and it&#8217;s unchecked. And, of course, it still works with the label. And let&#8217;s give it a bit of a focus style to make it better for keyboard users. And now, I&#8217;m focusing on it with the keyboard, and you can see it gets wide. It gets the focus style in.</p>
<p>[33:30] And, if I press the spacebar, it gets checked. If I press the spacebar again, it gets unchecked. So, it&#8217;s perfectly keyboard accessible. It&#8217;s even better than those JavaScript workarounds, because in most cases they don&#8217;t care about keyboard users. And it&#8217;s just done with a few lines of Purity SS, no JavaScript, whatsoever.</p>
<p>[33:55] The support for the check pseudo-class is pretty good, too. It&#8217;s supported by every latest browser. The only thing that probably should concern you is IE8. Apart from that, every used browser currently supports it.</p>
<p>[34:16] Also, I guess you know that CSS2 gave us a few cursors to allow us to change the cursor to show different interactions. And these were the cursors we had on CSS2. And that&#8217;s why I made my cursor bigger, so that you can see this. You&#8217;re all probably already familiar with these cursors, so I&#8217;m not going to get into detail for them.</p>
<p>[34:45] But the thing is that CSS3 gives us a bunch of other cursors as well because Web applications have advanced and now we need to represent interactions that we didn&#8217;t need to before. We have this non-cursor that hides the cursor and that&#8217;s not only useful for tricks and pranks. That&#8217;s actually useful for real, legitimate use cases. For example, in games where you use the cursor to control a character on the screen and you don&#8217;t want the users to be confused with their actual cursor, or in videos or in things like that.</p>
<p>[35:19] There&#8217;s also this cursor which I think it only works on OSX. It&#8217;s to show that there&#8217;s a context menu. We didn&#8217;t use to have context menus back then, but now we do and a cursor for showing that is useful. This is for resizing cells and tables like, for example, spreadsheet applications, vertical text. It&#8217;s kind of obvious what it does.</p>
<p>[35:40] Aligns and copy are for dragging something and representing like it&#8217;s supposed to become a shortcut or copy. And I think no drop and especially not allowed are the most useful cursors, because they allow you to show the user in yet one more way that something is impossible.</p>
<p>[35:59] For example, many designers use styling that&#8217;s not very clear that an element is disabled, a button is disabled, for example. Then the user tries to click it and they&#8217;re like, &#8220;Why doesn&#8217;t this work?&#8221; And this cursor allows you to provide, even an additional cue that this button is not meant to be pressed right now. Who would think that a button is supposed to work if you moused over it and you got this thing?</p>
<p>[36:29] There&#8217;s also a col-resize and row-resize which might seem like they&#8217;re only useful for tables, like spreadsheet applications and such, but they&#8217;re actually very useful for dragging any kind of horizontal or vertical divider.</p>
<p>[36:43] For example, I was recently doing a border image application to allow people to graphically control a border image declaration and drag the dividers over the image. I haven&#8217;t released it yet. I used the col-resize and row-resize cursors to drag the dividers over the image. They&#8217;re much better than the generic move cursor.</p>
<p>[37:09] There&#8217;s also this one, which I don&#8217;t think is very useful, and zoom-in and zoom-out, which can be useful in a number of different applications, although they don&#8217;t have the same level of support that others do. For example, in Firefox they need prefixes.</p>
<p>[37:25] To sum up the level of support for these things, WebKit has the best support. It supports all of them. Firefox supports almost all of them, but like I said, it requires prefixes for zoom-in and zoom-out, which is quite uncommon for cursors. The no-drop cursor is the same as not-allowed, which I don&#8217;t think is very important, but it still conveys the same message.</p>
<p>[37:52] Opera and IE don&#8217;t support a few of them, but I think it&#8217;s not very important because it degrades very gracefully. You just see the default cursor, and you can even provide fallbacks, like cursor move, for example, and then cursor row-resize, and the browsers that understand row-resize will use that. The browsers that don&#8217;t will use move.</p>
<p>[38:20] Yes, you&#8217;ve all used gradients to do something like this, which is a very, very simple gradient from black to gray. I guess you know that you can use angles as a first parameter to move it in different angles. I guess you also know that you can use color stop positions to move these colors.</p>
<p>[38:47] For example, in this case if we specify 20% for the first color and like 80% for the second then… Let&#8217;s make it vertical to make it even more obvious. Then we have black on 20% of the width, gray on the other 20% of the width, solid gray, and on the middle 60%, we have a gradient.</p>
<p>[39:09] We actually shrunk the gradient and we gave it a bit more solid color. Let&#8217;s keep moving those color stops closer to each other. Now our gradient is only 60% of the width. You can see it shrinking. Can you, actually? I hope you can. You can see it shrinking.</p>
<p>[39:32] Now we have 40% black and 40% solid gray, and the gradient is only at 20%. We can keep doing this and moving them even closer, and even closer.</p>
<p>[39:45] What happens when they actually meet? It just continues moving in this trend. Now we start having a line that kind of becomes blurry. When they are exactly at the same point, we don&#8217;t have a gradient anymore. We only have a gray color and a black color, and that&#8217;s it. We can even change where the black stops and the gray begins by changing these positions.</p>
<p>[40:11] The thing you should keep in mind is that when two color stops are in the same position, you don&#8217;t see a gradient anymore, you only see an abrupt change from one to another. Even at this simple state, this gradient is still useful.</p>
<p>[40:27] For example, we can use it to replicate the four columns effect without any images. I guess you know the four columns technique, where you use a background image to show that some columns have a height of 100%. Now, you can just use gradients for that instead of images.</p>
<p>[40:53] If we combine them with other CSS3 background properties, like for example background-size, we can create even more interesting effects.</p>
<p>[41:03] Let&#8217;s move back to 50% so that they are both equal. Let&#8217;s use background-size 100 pixels. As you can see, now we have stripes with just CSS gradients. No images whatsoever. We can even remove this to make horizontal stripes.</p>
<p>[41:23] Now you might be wondering, &#8220;Yeah, OK. Horizontal, vertical stripes are kind of useful but, usually, when I use stripes on the web they are not horizontal or vertical, they are diagonal. They are usually these 45 degree diagonal stripes.&#8221;</p>
<p>[41:37] And yes, we can actually do that with CSS gradients as well. For example, our first thought would probably be to use 45 degrees here, but as you can see that won&#8217;t work, because the gradient is rotated inside every tile. It&#8217;s not the whole background that gets rotated. But we can use the same technique we use in Photoshop when we create diagonal stripes, and just have every stripe twice, instead of having every stripe just once in the tile.</p>
<p>[42:13] Let&#8217;s get back to our gradient. We start from 25%. We use gray at the exact same position. We have to use every color twice to create the width of the stripe. Silver at the same position, and then, again, silver to show the stripe width, and then gray at the same position, and then gray.</p>
<p>[42:48] At this point, I would be done, but I&#8217;m using Firefox, and Firefox on Mac OS has this bug where it needs this last color stop. Normally, we wouldn&#8217;t need a last color stop, just like we don&#8217;t need the first color stop here &#8211; but Firefox needs it, so we need to add it just in the Moz version.</p>
<p>[43:10] You might be thinking, &#8220;Yeah, OK, that&#8217;s useful, but it&#8217;s a bit too big of a code. You specify every color three or four times.&#8221; And yes, there is an easier way to do it. It has its advantages and disadvantages. For example, it would be harder to change the background size. Now you can change the background size like this, just by changing two values. But then, with some effort I&#8217;m going to show next, it&#8217;s going to be a bit harder.</p>
<p>[43:38] There&#8217;s a function you can use that&#8217;s called repeating-linear-gradient. This function just takes the color stops you specify and repeats them indefinitely on both sides. Essentially, now, you need to specify everything in pixels, because the width of the stripe is here.</p>
<p>[44:02] Let&#8217;s make stripes that are like 30 pixels wide. Let&#8217;s remove the other color stops because they&#8217;re kind of confusing. Essentially, in this case, we only need four color stops. That&#8217;s it. Every color is specified two times in this gradient.</p>
<p>[44:26] If we want to change the size, that&#8217;s the problem. We have to edit it three times. Of course, the exact start and end doesn&#8217;t matter, just the relative offsets. For example, if this was 30 pixels, it would still work, we would just have to offset all of them by 30 pixels, but it would still work fine.</p>
<p>[44:49] Do we have time? No. OK. That&#8217;s it. CSS gradients are supported by, essentially, every modern browser. Opera doesn&#8217;t support radial gradients, which can also be used for a number of different effects, like for example creating polka-dot patterns.</p>
<p>Actually, I&#8217;ve created this gallery with many different patterns that you can create with CSS gradients and it&#8217;s &#8211; just a moment. You can find it on http: [45:08] //lea.verou.me/css3patterns. It displays many different kinds of patterns that can be created with this technique, and combining it with other CSS3 background properties. Many people have contributed to it. You can see their names if the pattern is not mine. For example, Tab Atkins who was also giving a talk today, I think, or Divya, which is also giving a talk here, and many, many other nice people.</p>
<p>[46:09] Getting back to browser support, Firefox supports them since Firefox 3.6. There are very few issues, not too important, like the one I showed, or that it doesn&#8217;t support explicitly sized ellipses and radial gradients. IE 10 supports them as well. Opera only supports linear gradients, and WebKit also supports them, but on Safari only since the 5.1.</p>
<p>[46:34] Older versions of WebKit used to support this proprietary version of gradients. Also, if you want to use gradients for the iPhone, you still have to use that horrible proprietary version, which is called WebKit-gradient. It uses the same function to create both radial and linear gradients.</p>
<p>[46:59] For our last trick today, let&#8217;s move a bit to Opera. How many times have you used the bottom-right background-position, only to be disappointed because your background was sticking at the edges of the box and there was no way to move it so that it follows the padding, for example, that you have?</p>
<p>[47:28] CSS3 extended the definition of background-position, so that we can specify offsets that aren&#8217;t just from the left top corner, but are from every corner. How did they do that? By allowing us to include four values in background-position. Bottom-right is a perfectly legit CSS2 background-position definition, but CSS3 allows us to specify also some offsets &#8212; like this, for example.</p>
<p>[47:59] As we increase them, the background moves. That&#8217;s exactly what designers have been wishing for ages. However, the problem with that is that the CSS3 background-position is only supported by IE and Opera. Yes, I know you&#8217;re shocked, but WebKit and Firefox don&#8217;t support everything.</p>
<p>[48:26] What can we do in this case? Is it a lost cause? Is our only way to just use a fallback and the CSS3 background-position? Actually, no. It turns out that for the most common use case of this, there&#8217;s an even better way &#8212; even if CSS3 background-position was supported.</p>
<p>[48:45] Here we have a padding of 40 pixels and, essentially, we just want this background image to follow that padding. What can we do? There is a property that controls where an image starts from, where a background image starts from, and it&#8217;s called background-origin.</p>
<p>[49:04] Its default value is padding-box, which means that the element starts from the padding box, but if we change this to content-box, the element moves to start from the content box. The padding box is outside it, so now it follows the padding, and we can actually change the padding in one place.</p>
<p>[49:25] If we were using the CSS3 background-position, then we would have to change it in three places, so this is even better, so let&#8217;s not get too sad that background-position isn&#8217;t supported, because background-origin is supported by every browser.</p>
<p>[49:43] Just for a laugh, since I&#8217;m done now, here&#8217;s a browser scorecard for the future, as I showed. I&#8217;m pretty sure it will be surprising for some, because WebKit isn&#8217;t first, Opera isn&#8217;t last, and actually, a while ago WebKit used to be last. It just climbed back up to the top because it now supports balancing transitions, so it supports nine things instead of eight.</p>
<p>[50:14] How many of you were surprised by this ranking?</p>
<p>[pause]</p>
<p>Lea: [50:21] I expected more. OK. It&#8217;s question time now. Just, before you ask, I usually get the question, When will my slides be published? They&#8217;ll be published today or tomorrow, hopefully. I frequently get the question about what did I use for the slides. I used a slideshow framework I coded last year, and some plugins that I coded this year for the editable regions, and everything &#8211; you can find it at this URL.</p>
<p>[50:54] Are there any other questions?</p>
<p>[pause]</p>
<p>[applause]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kabayview.com/css3/lea-verou-css3-secrets-10-things-you-might-not-know-about-css3-fronteers-2011/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Pull Custom Google Analytics Data with PHP</title>
		<link>http://www.kabayview.com/site-analytics/how-to-pull-custom-google-analytics-data-with-php</link>
		<comments>http://www.kabayview.com/site-analytics/how-to-pull-custom-google-analytics-data-with-php#comments</comments>
		<pubDate>Fri, 11 Nov 2011 12:46:18 +0000</pubDate>
		<dc:creator>Lynda Damiata</dc:creator>
				<category><![CDATA[Site Analytics]]></category>

		<guid isPermaLink="false">http://www.kabayview.com/?p=1016</guid>
		<description><![CDATA[October 27th, 2011 by Jake Rocheleau &#124; onextrapixel.com :: Google runs a very tight Internet media company offering outstanding resources to their users. Google Docs is perfect for online collaboration and document sharing. Gmail is a pristine example of how a Web e-mail interface should look. And their home page search functionality clearly wins out <a href='http://www.kabayview.com/site-analytics/how-to-pull-custom-google-analytics-data-with-php'> [read more]</a>]]></description>
			<content:encoded><![CDATA[<p>October 27th, 2011 by <a title="Posts by Jake Rocheleau" href="http://www.onextrapixel.com/author/jake-rocheleau/" rel="author">Jake Rocheleau |<br />
</a><a href="http://www.onextrapixel.com/" target="_blank">onextrapixel.com</a> ::</p>
<p>Google runs a very tight Internet media company offering outstanding resources to their users. Google Docs is perfect for <strong>online collaboration and document sharing</strong>. Gmail is a pristine example of how a Web e-mail interface should look. And their home page search functionality clearly wins out over all rival competition.</p>
<p style="text-align: center;"><img class="size-full wp-image-1017 aligncenter" title="google-analytic-data" src="http://www.kabayview.com/wp-content/uploads/2011/11/google-analytic-data.jpg" alt="" width="580" height="360" /></p>
<p>And when it comes to tracking website analytics and visitor stats it seems Google yet again offers some incredible functionality. <a href="http://www.google.com/analytics/">Google Analytics</a>is a free tool which automatically tracks visitor data from any website you choose. And with their backend API it&#8217;s possible to pull data directly from your account into a new web application. It seems the features are endless!</p>
<p>We&#8217;ll be constructing a small data table pulling page views from a website. The table will sort visitors based on browser type <em>(Firefox/Safari)</em> and Operating System <em>(Windows/Macintosh/iPhone)</em>. Within the script there are config options to change if you wish to view older dates, skip by 1 week at a time, or change domain names. Understand that API development is fairly simple, but you should have a rudimentary understanding of PHP development techniques.</p>
<h2>Setting Up our Testing Server</h2>
<p>First off we&#8217;ll be working with a basic PHP wrapper library. This simply means instead of coding our own library to connect into Google Analytics and pull account data, we can use a library written by somebody else. The Electric Toolbox is a development blog which features a <a href="http://www.electrictoolbox.com/google-analytics-api-and-php/">reliable PHP wrapper</a> for pulling data out of Analytics.</p>
<p>Now before we go unpacking files it&#8217;s important to also ensure your development environment can handle cURL events. Put simply, cURL is a plugin addition to the PHP library which features a set of functions used to fetch remote data. In other words cURL will grab HTTP data from the Analytics API without any custom work required. As the old saying goes &#8220;<em>Why reinvent the wheel?</em>&#8220;.</p>
<p>I haven&#8217;t used a <a href="http://www.mamp.info/en/index.html">MAMP setup</a> so I&#8217;m not sure the exact steps to enable cURL. But if you are running Windows I recommend using <a href="http://www.wampserver.com/en/">WAMP</a> as your all-in-one server package, and the odds are good MAMP will behave in a similar fashion. After install startup the server and you&#8217;ll notice a small meter icon in your taskbar. <strong>Left-click the icon and select PHP -&gt; PHP Extensions -&gt; php_curl</strong> which should be checked. If it&#8217;s not click it now and restart your server to apply changes. Using a prepackaged server environment will save you a lot of time testing local scripts.</p>
<p style="text-align: center;"><img class="size-full wp-image-1018 aligncenter" title="wamp-graffiti-pavement" src="http://www.kabayview.com/wp-content/uploads/2011/11/wamp-graffiti-pavement.jpg" alt="wamp graffiti" width="580" height="300" /></p>
<p>If all of this works then congratulations! You should be all set to move along and we can start coding in PHP. So unzip the archived set of PHP wrapper libraries we just downloaded and open the folder. Copy the <code>analytics_api.php</code> file and move this into a new directory in your server root. I have named this folder <strong>analytics</strong>.</p>
<h2>Install the PHP Wrapper</h2>
<p>Open whatever text editor you&#8217;ll be using to code this script. Create a new PHP page and save it into the same directory you just made, alongside the copied <code>analytics_api.php</code> file. You can name this new file whatever you&#8217;d like. But I have chosen <code>index.php</code> to keep up with standards.</p>
<p>You can download the entire project source code to work with if that&#8217;s easier. I&#8217;ll be breaking down my example code piece-by-piece so we may understand it a little better. To begin we have 2 lines setting an include and Content-Type header.</p>
<div>
<div><code>require_once</code><code>(</code><code>'analytics_api.php'</code><code>);</code></div>
<div><code>header(</code><code>'Content-Type: text/html'</code><code>);</code></div>
</div>
<p>&nbsp;</p>
<div>
<p>We need to include our analytics_api.php file so we have access to the API library. Inside this file are all the functions needed to pull out page views, settings, account information, etc. The Content-Type header just lets the browser know we are looking to output text in plain HTML. This part isn&#8217;t too exciting so let&#8217;s move onto the configuration area.</p>
<h2>Config Variables</h2>
<p>Most of the configuration settings I have placed above all page output. These are used to control the settings for your Analytics account and what type of information you wish to pull out. First off you need to include 3 important data settings. <code>$login</code> should contain your Google E-mail account login, along with your password right below it.</p>
<div>
<div><code>// Config info</code></div>
<div><code>$login</code> <code>= </code><code>''</code><code>; </code><code>// youraccount@gmail.com</code></div>
<div><code>$password</code> <code>= </code><code>''</code><code>;</code></div>
<div><code>$id</code> <code>= </code><code>''</code><code>; </code><code>// example - ga:1234567</code></div>
<div><code>$startdate</code> <code>= </code><code>strtotime</code><code>(</code><code>'2011-06-28'</code><code>);</code></div>
<div><code>$enddate</code> <code>= </code><code>strtotime</code><code>(</code><code>'-1 day'</code><code>);</code></div>
<div><code>$filters</code> <code>= </code><code>array</code><code>();</code></div>
<div><code>$filters</code><code>[</code><code>'Firefox'</code><code>] = </code><code>'ga:browser=@Firefox'</code><code>;</code></div>
<div><code>$filters</code><code>[</code><code>'Safari'</code><code>] = </code><code>'ga:browser=@Safari'</code><code>;</code></div>
<div><code>$filters</code><code>[</code><code>'Windows'</code><code>] = </code><code>'ga:operatingSystem=@Windows'</code><code>;</code></div>
<div><code>$filters</code><code>[</code><code>'Macintosh'</code><code>] = </code><code>'ga:operatingSystem=@Macintosh'</code><code>;</code></div>
<div><code>$filters</code><code>[</code><code>'iPhone'</code><code>] = </code><code>'ga:operatingSystem=@iPhone'</code><code>;</code></div>
<div><code>$metric</code> <code>= </code><code>'ga:pageviews'</code><code>; </code><code>// alternatively use 'ga:visits' for uniques</code></div>
</div>
<p>&nbsp;</p>
<div>Next you&#8217;ll see a variable labeled as <code>$id</code>. This will contain your Google Analytics web ID set to the syntax of <code>ga:xxxxxxxxxx</code> without the quotes. To find this number you&#8217;ll need to access your Analytics account and find the website you wish to pull data from. Click <strong>View Report</strong> and in the top URL address bar you should notice an ID number. Add this after the <code>ga:</code> prefix and all of this goes into the <code>$id</code> variable for later.</div>
<p></p>
<div><img class="size-full wp-image-1019 aligncenter" title="google-analytics-gaid" src="http://www.kabayview.com/wp-content/uploads/2011/11/google-analytics-gaid.jpg" alt="google analytics" width="580" height="300" /></div>
<div>
<p>&nbsp;</p>
<p>The next 2 settings hold the start and end dates. Starting date may be anything you&#8217;d like, while the ending date is always set to one day before the most current. We do this since Google doesn&#8217;t have a full data report for 24 hours until the day has concluded, so this shaves off a bit of loading time.</p>
<p>Now our filters will be used to pull out unique data from within Google&#8217;s servers. The list is quite expansive and includes a lot more data than just browsers and OS. But for the scope of this tutorial we&#8217;ll be testing with the 5 array variables set in my example. You can read up a bit more on the data API from <a href="http://code.google.com/apis/analytics/docs/gdata/gdataReferenceDataFeed.html">Google Code docs</a> online.</p>
<p>And finally the <code>$metric</code> setting will set which type of numbers we&#8217;re pulling for traffic data. Options include page views, uniques, bounces, clicks, time on site&#8230; anything used to measure statistics. Check out Google&#8217;s <a href="http://www.google.com/support/analytics/bin/answer.py?answer=99118">full metrics chart</a> to get an idea of the options. We&#8217;re sticking with page views since these are solid numbers which can give us an idea of the popularity ratio for browsers and OS&#8217;.</p>
<h2>Looping Through Data</h2>
<p>If you have taken a look at the example code you&#8217;ll notice there&#8217;s some basic CSS and other styling options. But we&#8217;ll be skipping ahead right into the core logic of our PHP application. In this next segment of code we&#8217;re looking to create a new instance of the Analytics API and pull account data, then output what we need into HTML.</p>
<div>
<div><code>$api</code> <code>= </code><code>new</code> <code>analytics_api();</code></div>
<div><code>if</code><code>(</code><code>$api</code><code>-&gt;login(</code><code>$login</code><code>, </code><code>$password</code><code>)) {</code></div>
<div><code>    </code><code>if</code> <code>(</code><code>strlen</code><code>(</code><code>$id</code><code>) == 0) {</code></div>
<div><code>    </code><code>$api</code><code>-&gt;load_accounts();</code></div>
<div><code>    </code><code>exit</code><code>;</code></div>
<div><code>    </code><code>} </code><code>else</code> <code>{</code></div>
<div><code>        </code><code>$api</code><code>-&gt;load_accounts();</code></div>
<div><code>        </code><code>$last</code> <code>= </code><code>count</code><code>(</code><code>$api</code><code>-&gt;accounts) - 1;</code></div>
<div><code>    </code><code>foreach</code> <code>(</code><code>$api</code><code>-&gt;accounts </code><code>as</code> <code>$i</code> <code>=&gt; </code><code>$row</code><code>) {</code></div>
<div><code>        </code><code>$isFirst</code> <code>= (</code><code>$i</code> <code>== 0);</code></div>
<div><code>        </code><code>$isLast</code> <code>= (</code><code>$i</code> <code>== </code><code>$last</code><code>);</code></div>
<div><code>    </code><code>if</code><code>(</code><code>$id</code> <code>== </code><code>$row</code><code>[</code><code>'tableId'</code><code>]) { </code><code>echo</code> <code>'&lt;h3&gt;Account Name: '</code> <code>. </code><code>$row</code><code>[</code><code>'title'</code><code>] . </code><code>'&lt;/h3&gt;'</code><code>; }</code></div>
<div><code>    </code><code>}</code></div>
<div><code>}</code></div>
</div>
<p>&nbsp;</p>
<div>The first operation we perform is to set <code>$api</code> as a new object. This initiates our Analytics class and we now have access to all internal functions. Going with this, we can use an if/else clause to check if the login information provided will work. We call the <code>$api-&gt;login()</code> function and pass in the e-mail username and password from above. Assuming this passes we now move into another set of if/else logic.</div>
<div>
<p>If we can login but can&#8217;t find any ID <em>(meaning you have no Analytics data)</em> we simply exit the app with your account data loaded. Otherwise we still load your account data, but now we can loop through your Analytics profiles to find which ID matches the one given in your config settings. Once we meet a matchup the title data is echoed onto the page in a set of <code>h3</code> tags.</p>
<p>If you were paying close attention you may notice our original <code>if{}</code> conditional hasn&#8217;t been closed yet. This is because we&#8217;re still processing the logic from the account login. If we succeed with logging in first we output the analytics profile title. But next we need to output a small table containing our page views for each filter. The code below is the complete finished block of code from above, resting on a final <code>else{}</code> clause to output an error message if login authentication fails.</p>
<div>
<div><code>$from</code> <code>= </code><code>$startdate</code><code>;</code></div>
<div><code>$n</code> <code>= 0;</code></div>
<div><code>echo</code> <code>'&lt;table id="analytics"&gt;'</code><code>;</code></div>
<div><code>while</code> <code>(true) {</code></div>
<div><code>    </code><code>$till</code> <code>= </code><code>strtotime</code><code>(</code><code>'+2 days'</code><code>, </code><code>$from</code><code>); </code><code>// update number here for amount of days skipped for each pull</code></div>
<div><code>    </code><code>if</code> <code>(</code><code>$till</code> <code>&gt; </code><code>$enddate</code><code>) </code><code>break</code><code>;</code></div>
<div><code>    </code><code>$n</code><code>++;</code></div>
<div><code>    </code><code>if</code><code>(</code><code>$n</code><code>%2 == 0) { </code><code>echo</code> <code>'&lt;tr&gt;'</code><code>; }</code></div>
<div><code>    </code><code>else</code> <code>{ </code><code>echo</code> <code>'&lt;tr&gt;'</code><code>; }</code></div>
<div><code>    </code><code>echo</code> <code>'&lt;td&gt;'</code> <code>. </code><code>date</code><code>(</code><code>'Y-m-d'</code><code>, </code><code>$from</code><code>) . </code><code>'&lt;/td&gt;'</code><code>;</code></div>
<div><code>    </code><code>foreach</code> <code>(</code><code>$filters</code> <code>as</code> <code>$filter</code><code>) {</code></div>
<div><code>        </code><code>$data</code> <code>= </code><code>$api</code><code>-&gt;data(</code><code>$id</code><code>, </code><code>''</code><code>, </code><code>$metric</code><code>, false, </code><code>date</code><code>(</code><code>'Y-m-d'</code><code>, </code><code>$from</code><code>), </code><code>date</code><code>(</code><code>'Y-m-d'</code><code>, </code><code>$till</code><code>), 10, 1, urlencode(</code><code>$filter</code><code>));</code></div>
<div><code>        </code><code>$mainfilteritem</code> <code>= </code><code>explode</code><code>(</code><code>"=@"</code><code>, </code><code>$filter</code><code>);</code></div>
<div><code>        </code><code>echo</code> <code>'&lt;td&gt;'</code><code>;</code></div>
<div><code>        </code><code>echo</code> <code>$mainfilteritem</code><code>[1] . </code><code>' - '</code><code>;</code></div>
<div><code>        </code><code>echo</code> <code>((int)</code><code>$data</code><code>[</code><code>$metric</code><code>]);</code></div>
<div><code>        </code><code>echo</code> <code>'&lt;/td&gt;'</code><code>;</code></div>
<div><code>    </code><code>}</code></div>
<div><code>        </code><code>echo</code> <code>"&lt;/tr&gt;"</code><code>;</code></div>
<div><code>        </code><code>$from</code> <code>= </code><code>strtotime</code><code>(</code><code>'+1 day'</code><code>, </code><code>$till</code><code>);</code></div>
<div><code>    </code><code>}</code></div>
<div><code>    </code><code>echo</code> <code>'&lt;/table&gt;'</code><code>;</code></div>
<div><code>} </code><code>else</code> <code>{</code></div>
<div><code>    </code><code>echo</code> <code>"login failed."</code><code>;</code></div>
</div>
<p>&nbsp;</p>
<div>
<p>Our <code>$from</code> variable is set to the starting date from earlier. <code>$n</code> is set to 0 so we may pull a <code>while{}</code> loop resulting in each table row, moving forward by 3 days each time. This can be seen directly after our while command where the <code>strtotime()</code> function is set. You may update the value from <code>+2 days</code> to whatever you&#8217;d like. If you want to include data from every single day just hide this line from the code, since every run through we also call <code>$n++</code> by 1 degree.</p>
<p>Just keep in mind that Google can only handle so many server calls. It&#8217;s wise to cache your data or store it in a database if you plan on pulling analytics for every single day in a row. But for our small application jumping every 3 days works perfectly. Now we can move on to the next segment of logic which picks apart the metrics data.</p>
<p>First we are checking if <code>$n</code> is divisible by two(2). This is solely for aesthetic feel, since I have designed a zebra stripe pattern on the table layout with CSS. But moving past this we are first outputting page content into a portion of our table holding each date. Running a <code>foreach()</code> loop we can use another function from our library called <code>$api-&gt;data()</code>. Inside we pass a few parameters such as Analytics ID and metrics data, and we get out a small array of information.</p>
<p>In our next variable we set another array <code>$mainfilteritem</code>. This can be used to store information for all of our filters which we output in every table row. If this concept seems confusing just check our <strong>live demo example</strong> below to see how this table comes to form. The <code>foreach</code> loop inside the while loop creates dynamic data on each row many times over. And we close off the loops by ending each table row and proceeding forward by 1 day until we hit the most current data.</p>
<h2>Conclusion</h2>
<p>There are so many types of applications you can build upon with Google Analytics. Their API has been carefully crafted to run over many programming languages, and PHP is just one out of the group. And with PHP we can build fully-scaled web applications to display all kinds of visitor tracking data.</p>
<p>&nbsp;</p>
</div>
</div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.kabayview.com/site-analytics/how-to-pull-custom-google-analytics-data-with-php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

