<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
 
        <title>ode - a simple personal publishing platform for the web</title>
        <link>http://ode-is-simple.com/home/off-topic/rob/thoughts/on-life/</link>
        <description><span class="emphasize">Simple</span> means that you know how it works.</description>
        <language>en</language>
        <docs>http://blogs.law.harvard.edu/tech/rss</docs>
        <generator><!-- name="generator" content="ode/1.2.1" --></generator>
        <managingEditor>rob@ode-is-simple.com (Rob)</managingEditor>
        <webMaster>rob@ode-is-simple.com (Rob)</webMaster>
 
		<atom:link href="http://ode-is-simple.com/home/index.rss2" rel="self" type="application/rss+xml" />


        <item>
            <title>End of the year 'state of the project' post</title>
            <link>http://ode-is-simple.com/home/news/about_ode/noteworthy_dates/state-ofOde-2012-12</link>
            <description><![CDATA[ <p>I've done this for the past couple of years and think it's a tradition worth continuing so let's get to it...</p>

<p>The state of our project is strong.</p>

<p>When I take a moment to think about the things that genuinely excited about, and happy with, and also those things that I'm discouraged about, the only thing(s) that have me feeling down are my own failings. Simply put, I would like to have done more, and released more, by now. But everything else is all very positive, e.g. the underpinnings of the project, it's continued relevance and potential, the way that I feel about the the time I've spent working on it.</p>

<p>A couple of years old now, and Ode seems to me to be every bit as interesting as it ever was. In fact, if anything the developments in technology, and web technologies specifically, have turned out to be far more favorable for our little project than I might have guessed. The web is only getting better, and more than almost any other project like it, Ode lives and dies by core web technologies. The strength of the project is tied to the strength of the web itself, and these days no technology looks more promising than the open web. (That's how I see it anyway.)</p>

<p>From the beginning, I wanted Ode to serve as a platform for learning, but not learning about Ode for its own sake so much as learning about web design and development, programming more generally, and the web itself. By making Ode as simple as possible, the focus shifts to the truly interesting stuff &#8212; everything you wanted to know before you were aware this project existed. Rather than complicate or obscure the learning process the way a monumental platform like Wordpress does, Ode keeps us focused on what matters.</p>

<!-- jumper:jump -->

<p>If you were to spend a year working with Ode, and then decided to move on to another platform, virtually everything you learn here would translate. What's more, because you spent a year working with Ode, you'd have developed the skills you need to make that transition to that next platform (whatever it might be). Whatever else they might have going for them, that is certainly something that can't be said of hugely popular hosted services from Twitter to Facebook to Tumblr to Wordpress.</p>

<p><a href="http://www.w3.org/2012/12/html5-cr" title="HTML5 declared feature complete">HTML5 is clearly the future of the web</a>, and that's absolutely fantastic! Setting aside all of the fancy things that can be done using the new, <strike>as yet unsettled</strike>,  APIs, HTML5 greatly simplifies markup by getting rid of a lot of the unnecessary clutter and introducing useful new elements. I especially like <a href="http://coding.smashingmagazine.com/2011/08/16/html5-and-the-document-outlining-algorithm/" title="Article at smashingmagazine.com">the new explicit document outlining algorithm</a>.</p>

<p>All of that is especially great for Ode. The idea of creating sites and writing posts in a text editor, and managing our files directly, hasn't made so much sense since static sites were the norm. Today with Ode we have access to all of the capabilities of the modern web with the simplicity of static sites. But more than just that, collectively we all share a better understanding of web technologies and how to use them effectively today and so they're actually easier to learn and to use than ever before. And for the first time, standards and best practice approaches are becoming more firmly entrenched than the resistance to them.</p>

<p>Beyond HTML, CSS, and Javascript, there any number of fantastic web services, frameworks, and other technologies out there. Among many others, we have robust libraries like <a href="http://jquery.com/" title="Official site at jquery.com">JQuery</a> that make simplify Javascript, making it more efficient to write and smoothing over compatibility issues. There are preprocessors like <a href="http://sass-lang.com" title="Official site at sass-lang.com">Sass</a> and <a href="http://lesscss.org" title="Official site at lesscss.org">LESS</a> that are expanding what we can do in ways that are 100% compatible with the open web. There's just a lot of really great stuff out there. And when I say 'we' I mean all of us, not just the few with deep pockets.</p>

<p>By the way, don't feel like you need to be an expert on everything. Start with HTML and CSS and see where that takes you. These technologies are tools, there to use if you need or want to. Think of them that way and not as a an overwhelming, and ever changing collection of things that to be collected and you'll be much happier. Always remember that learning is a continuing process, not a destination.</p>

<p>Right now, at the end of 2012, there is even a lot discussion about native apps for mobile devices giving way to web apps. As web technologies mature, it only makes sense. After all, the web comes closer to the promise of 'write once, run anywhere' than any other platform ever has. (Sorry Java, but I hate you.) On the other hand, mobile apps like Flipboard, Pulse, and others bring our content to mobile device users via those native apps, and on even footing with even the largest content providers.</p>

<p>Another great example of what's gone right this year is rise to prominence of <a href="http://daringfireball.net/projects/markdown/" title="Official site at daringfireball.com">Markdown</a>. The uptake of Markdown has been nothing short of phenomenal. That suggests to me that writing with plain text using lightweight markup is something that people want to do. Markdown wouldn't be a hot topic if everyone were satified with web forms featuring basic formatting using toolbars. From personal experience, the more I use use a text editor to write posts, and then jump from posts to working on themes and writing code, the more natural it feels. (The more awkward everything else seems by comparison).</p>

<p>By the way, I have my own ideas about how to improve Markdown. I hope to implement them soon in a new syntax I'm calling 'unmarkup' which is very similar to, and largely compatible with, Markdown.</p>

<p>I'm even hopeful that we're seeing longer form content and independent (self-hosted) sites coming back into fashion. Twitter is having trouble with its developers and savviest users who are increasingly being forced to confront the many problems inherent in building on top of someone else's closed platform. <a href="http://www.mercurynews.com/business/ci_22218042/instagram-changes-its-rules-and-angers-users" title="Article at mercurynews.com">The same could be said about Instagram this week</a> (and sooner or later every other closed platform for that matter).</p>

<p>What's more, the value of long-form, thoughtful, and informative content is made obviously apparent when compared to the silliness of many currently popular 'social' services. You only need to see a supposedly legit journalist stand in front of a camera and read a tweet once to understand just how absurd it is to reduce the world and human interaction to 140 characters or less.</p>

<p>Probably the simplest way I can put it is to say that this year is ending better than it started. That's not bad at all.</p>

<p>As far as Ode itself is concerned...</p>

<p>The next release is going to be a good one. I have learned a lot from discussing the project with you over the past year. Based on those discussions, the changes and additions are natural improvements over what we have now. Beyond ode.cgi there are any number of addins and themes I want to make. Rather than these ideas getting stale, after sitting for a long time in some cases, I'm more excited about them than ever.</p>

<p>I've all but completed a major reworking on the default theme, which I'm planning to use and evolve as a design pattern for a series of themes going forward. I'm hoping it will turn out to be my own little front-end template eventually, not dissimilar to something like <a href="http://html5boilerplate.com" title="Official site at html5boilerplate.com">HTML5 Boilerplate</a>, minus the popularity of course ;). I'd love to see us build on and improve this pattern together. I've also been playing with <a href="http://twitter.github.com/bootstrap/" title="Official site at twitter.github.com">Bootstrap</a> quite a bit and can easily see a second series of Bootstrap based themes. That in turn could lead to still more similar things.</p>

<p>For what it's worth I think Bootstrap is a good thing, but ultimately more trouble than it's worth in a lot of ways. But that it exists, and that I can go through it, make sense of it all, and form my own opinions, says a lot about both Bootstrap and the web itself. </p>

<p>I'm as happy as I ever was about the decision to base Ode on Perl, and have absolutely no problem recommending it as a first language for anyone new to programming. 2012 even brought us an update to '<a href="http://shop.oreilly.com/product/0636920018452.do?green=DA55B360-1BC9-5920-0D2A-53BA78324A1F&amp;intcmp=af-mybuy-0636920018452.IP" title="Book page at oreilly.com">Learning Perl</a>' (the unofficial guide to Perl for Ode), as well as the next book in the series, '<a href="http://shop.oreilly.com/product/0636920012689.do?green=DA55B360-1BC9-5920-0D2A-53BA78324A1F&amp;intcmp=af-mybuy-0636920012689.IP" title="Book page at oreilly.com">Intermediate Perl</a>'.</p>

<div class="notation">Learning Perl is all you need to know to understand ode in it's entirety. That won't change with the next release.</div>

<p>Gee, thinking about it for a moment, it's fair to say that Ode had a much better year than I did. I suppose that makes sense, it's more useful than I am.</p>

<p>Ode is healthy, and if only in a small way I think we're all better off for it. Even if most of us don't really care. That reminds me of a line from an episode of <a href="http://en.wikipedia.org/wiki/Futurama" title="Entry at Wikipedia 2012-1219, 3:58p EDT">Futurama</a> titled '<a href="http://en.wikipedia.org/wiki/The_Why_of_Fry" title="Entry at Wikipedia 2012-1219, 3:59p EDT">The Why of Fry</a>':</p>

<blockquote>
  <p>Fry: "I'm just as important as him." <em>pause</em> "It's just that, the kind of importance I have ... it doesn't matter if I ... don't do it."</p>
</blockquote>

<p>Thanks to everyone who has contributed to this project in any way. If you've read this to the end that almost certainly includes you.</p>

<p>Here's hoping I'm writing another one of these about about the same time next year.</p>

<p>Cheers, Rob.</p>
 ]]></description>
            <pubDate>Wed, 19 Dec 2012 17:57:00 EST</pubDate>
            <guid>http://ode-is-simple.com/home/2012/12/19/17/57/00/</guid>
        </item>


        <item>
            <title>Because it's against the laws of thermodynamics, that's why</title>
            <link>http://ode-is-simple.com/home/off-topic/rob/technology/misc/entryopy-andIT</link>
            <description><![CDATA[ <p>I work in IT, and it is often <strike>shocking</strike> depressing to me the way people deal with, or more to the point don't deal with, their technology.</p>

<p>I don't expect people to know everything there is to know about technology.</p>

<p>For one thing I don't know everything there is to know, and I spend a lot of time doing this stuff. For another, it's my job to help people to deal with their technology -- the logical assumption being that they need help.</p>

<p>However, I do expect people to be able to apply their general knowledge to issues related to IT.</p>

<p>For example let's think about entropy.</p>

<p>One of the four fundamental laws of thermodynamic systems - the Universe is a thermodynamic system - entropy is closely related to <a href="http://en.wikipedia.org/wiki/Entropy_(order_and_disorder)" title="Entry at wikipedia.org">order and disorder</a>.</p>

<p>Things tend to decay, i.e. become more disordered, unless energy is expended to maintain order.</p>

<p>With regards to IT, this can be interpreted to mean that technology must be monitored and proactively maintained or it will degrade and eventually fail. (In the same way that you must have your car serviced or clean your home.) You have the choice of either managing it or suffering through any number of problems that are usually disruptive, frequently expensive, and occasionally catastrophic.</p>

<p>You are not allowed to have an opinion about this. That is, you cannot rationally hold the opinion that you do not have to manage technology and there will be no problems as a consequence.</p>

<p>Well let me put that another way... If you want to argue about this, it's not me that you'll be arguing with, it's either the laws of physics, or God, if you believe in that sort of thing. Either way, it's not an argument that you are likely to win. (I have nothing to do with it. It was like this when I got here.)</p>

<p>If you're struggling with the concept of entropy then lets pick a closely related concept, time. Not managing IT and expecting it to go well, is like betting on the losing side in a sporting event after it has already been played and then acting surprised at the outcome.</p>

<p>Some things are simply not a matter of opinion.</p>
 ]]></description>
            <pubDate>Thu, 25 Oct 2012 22:01:08 EDT</pubDate>
            <guid>http://ode-is-simple.com/home/2012/10/25/22/01/08/</guid>
        </item>


        <item>
            <title>Windows 8 and Microsoft Surface are just about here and -- it's going to be messy.</title>
            <link>http://ode-is-simple.com/home/off-topic/rob/microsoft/windows8/windows8-is-a-messSurface-too</link>
            <description><![CDATA[ <p>Like a lot of people, I see Windows 8 as a big mess. (More on this in a bit.) But the folks at <a href="http://http://gizmodo.com" title="Gizmodo homepage at gizmodo.com">Gizmodo</a> aren't those people.</p>

<p>In June they declared Microsoft "<a href="http://gizmodo.com/5889659/microsoft-is-the-most-exciting-company-in-tech-hands-down" title="Post at gizmodo.com">the Most Exciting Company in Tech, Hands Down</a>" and in another post, written immediately after the Microsoft introduced the Surface tablet, and they pronounced "<a href="http://gizmodo.com/5919521/microsoft-surface-just-made-the-macbook-air-and-the-ipad-obsolete" title="Post at gizmodo.com">Microsoft Surface Just Made the MacBook Air and the iPad Look Obsolete</a>", summarizing what they had just seen (but never touched much less used) as:</p>

<blockquote>
  <p>Beautiful and functional and simple and honest.</p>
</blockquote>

<p>What I saw was a pretty typical tablet in terms of hardware but with a kickstand and a perfectly flat keyboard integrated into the cover that looked like it would be a nightmare to type on (and not such a great cover either). And for some reason, it would be WiFi only, making it a device that would be only occasionally connected. If you don't consider lack of cellular data as an option a serious omission, then what about GPS? This thing does not include GPS hardware. Lack of cellular connectivity and GPS make Surface more akin to the iPod Touch than the iPad. (Google's Nexus 7 lacks cell connectivity but OF COURSE includes GPS.)</p>

<p>So Gizmodo loved it and I didn't get it.</p>

<p>Fast forward to today, and they've posted their review of Surface. So what did they think of the most exciting device in recent memory from the the most exciting technology company in the world?</p>

<p>Let's find out, by reading some of what they have to say in their post titled, "<a href="http://gizmodo.com/5953866/microsoft-surface-rt-review-this-is-technological-heartbreak" title="Post at gizmodo.com">Microsoft Surface RT Review: This Is Technological Heartbreak</a>"</p>

<!-- jumper:jump -->

<blockquote>
  <p>Microsoft tantalized us with a tablet that made the iPad look stale. Its snap-on keyboard made all laptops look immediately old fashioned. </p>
</blockquote>

<p>Seriously? A snap-on keyboard is all it takes to make modern laptops, awesome technological achievements that they are, seem old fashioned?? An f'ing snap-on keyboard? WTF!</p>

<blockquote>
  <p>The laptop is about as far advanced as one can imagine.</p>
</blockquote>

<p>Agreed.</p>

<blockquote>
  <p>The MacBook Air and a horde of ultrabook clones are hitting a brick wall in terms of form and physics.</p>
</blockquote>

<p>Hmmm... people have been saying this about everything related to computers for a very long time now, from CPUs to some of the earliest mainstream laptops.</p>

<blockquote>
  <p>The tablet, likewise, isn't exactly pushing civilization forward; it's still fundamentally a luxury device, a delightful toy for reading email on the couch or watching Netflix on an airplane.</p>
</blockquote>

<p>I basically disagree with this.</p>

<p>For one thing tablets have introduced the idea of cell service without oppresive long term contracts. That's not exactly 'pushing civilization forward', but what kind of standard is that? It certainly pushes the state of mobile tech forward. The Kindle introduced Whispernet providing always on cellular connectivity without the user directly dealing with the a cell carrier. Apple's iPad introduced cellular data service that could be activated/deactivated on a month to month basis with no contract and managed directly on the device itself. Those were at the time and still are pretty radical ideas.</p>

<p>More than that, I see the tablet as the realization of something very much like, and in many ways superior to, the fictional '<a href="http://en.wikipedia.org/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy_(fictional)" title="Entry at wikipedia.org">Hitchhiker's Guide to the Galaxy</a>'. In fact, if we were capable of exploring the universe, it would essentially be that device, except that a tablet is more functional than a simple interactive reference book.</p>

<p>In fact the more I think about it, and considering the potential to impact everything from education and health care to the way we explore and experience the world around us and interact with other people, I do think that tablets have the potential to push civilization forward. (They haven't yet, but it took the computer a while too.) Surface on the other hand has the potential to snap on and off the keyboard. </p>

<p>OK now I'll just stick to quotes from the article without interjecting so much. They do a good enough job criticizing Surface/Windows RT, and I've been critical enough of Gizmodo already...</p>

<blockquote>
  <p>After the initial delight of an evolved tablet wears off, you'll groan—because Surface brings the appearance of unity, but it's really just the worst of both worlds. Instead of trading in your laptop and tablet for Surface, a cocktail of compromises that fracture the whole endeavor, you'll miss them both urgently.</p>
</blockquote>

<!-- blockquote break -->

<blockquote>
  <p>Want to use Surface RT as a laptop? Sorry, the Touch Cover is a letdown.</p>

<p>...it only approximates a real keyboard—the buttons are pressure activated, barely buttons at all, and spaced in such a way that typos are inevitable and constant.</p>

<p>You'll feel clumsy. You'll write slowly. I tried writing this review on the Surface, but I would've missed my deadline by a week.</p>
</blockquote>

<!-- blockquote break -->

<blockquote>
  <p>The trackpad, sludge-like and jerky, is even worse—particularly galling compared to the super-smooth touchscreen—and unlike the keyboard, will never get better with practice.</p>
</blockquote>

<!-- blockquote break -->

<blockquote>
  <p>The Touch Cover also approximates, dismally, the sturdiness of a laptop: thanks to the cloth-like floppiness of the thing that's necessary for making it easy to open and close, it can't support itself on anything but a flat, rigid (apologies) surface. You can't type on your lap, like laptop. It's hard to imagine what a design solution out of this would have been, but that's Microsoft's job, not ours.</p>
</blockquote>

<!-- blockquote break -->

<blockquote>
  <p>Perhaps most galling is the Touch Cover's $100 addition to the Surface's already pricy $400 base MSRP ... Microsoft also offers a Type Cover, that promises actual physical keys instead of the flattened solution, but that will add critical bulk to your Surface experience—along with an extra $130.</p>
</blockquote>

<p>OK now I have to interject. People are complaining pretty loudly about the $329 base price of the iPad mini, so much so that <a href="http://appleinsider.com/articles/12/10/24/apple-exec-phil-schiller-defends-329-entry-price-of-ipad-mini" title="Post at appleinsider.com">Apple marketing exec Phil Schiller felt the need to defend it's pricing</a>. Yet the price of Surface with keyboard is $500.00. That's the version that runs Windows RT, which is, according to early reviews, a half baked tablet OS. For less than that you could get an iPad mini with LTE cellular connectivity ($459.00), which of course includes GPS -- as really all mobile devices that support 3rd party apps should, so many potentially useful mobile apps depend on it.</p>

<p>By the way, the base price of the Windows 8 version of Surface is $999.00.</p>

<p>I'll finish with the most damning part of the review...</p>

<blockquote>
  <p>But it's Windows on Surface RT that's the greatest letdown of all, the lethal letdown, because it's not Windows 8, but Windows RT. You can't tell the difference by looking at them, but you certainly will once you use it. Windows RT is underpowered (everything opens and syncs slightly too slowly), under-functional (you cannot install a single app that's not available through the Windows RT app store, which offers a paltry selection), and under-planned (the built-in apps can't feel like Lite versions of something better).</p>
</blockquote>

<p>We'll see how it sells, but regardless it's pretty obviously difficult to make any sense out of.</p>

<p>In fact it reminds me a little of RIM's Blackberry Playbook which they tried to sell as a device that would do everything (including run Android apps), but did nothing especially well, and which consumers never could quite wrap their heads around.</p>

<p>Who knows, it wouldn't be the first successful mess. Hollywood is full of them. Hey maybe they'll get Lindsay Lohan or Britney Spears to promote the thing. We just need a tag line for the ad campaign -- how about 'dysfunction at work'?</p>

<p>I've been saying this same thing about Surface since it was first announced. In fact I've been saying this since the Windows 8/Windows RT strategy was first made public. I even wrote a post about this that I never put online. Let's see what I had to say about this back in June in an unpublished post titled...</p>

<h3>Microsoft seems intent on confusing the hell out of everyone</h3>

<p>Microsoft really needs someone to help them with branding and positioning their products. Normally I wouldn't say that's such a big thing. But that's only because no one else seems to screw it up quite like MS, and recently it's taken a sharp turn for the worse. I'm referring to Windows 8.</p>

<p>At about the same time Microsoft will be releasing 3 entirely different products all called, at one point or another, Windows 8:</p>

<ul>
<li>Windows 8 the desktop OS</li>
<li>Windows 8 the tablet OS</li>
<li>Windows 8 the phone OS</li>
</ul>

<p>And that's just the beginning of the confusion. There is a considerable amount of overlap between these entirely different operating systems.</p>

<p>For one thing they are targeted at the same <em>and different</em> hardware. Also the way they function is both similar and different. It's hard to know which is worse, the differences or similarities.</p>

<p>The clear differences may cause users to dislike Windows 8 in comparison with other flavors of Windows 8, as there will inevitably be pros and cons associated with each.</p>

<p>It will be confusing, and more than a little annoying, to be forced to switch among different ways of doing the same thing based on which device you happen to be using -- and this is not just a problem across categories of device, but also across different models within the same device category!</p>

<p>But at least the clear differences will be apparent. It's the similarities that may prove to be more disorienting.</p>

<p>Where the UIs are similar they are not the same. Subtle differences among seemingly identical elements, including UI controls, can be all but indistinguishable from reproducible bugs from the user's perspective.</p>

<p>I understand that Microsoft is attempting to tailor their UI to different platforms to provide the best possible experience for each, rather than awkwardly try to force the same controls, behaviors, and appearances across what are very different platforms - phone, tablet, and desktop.</p>

<p>You could convince me that's the right approach, and pretty easily. But if that's the idea than why is Microsoft pushing the Metro UI across all of these devices? And that argument does nothing to explain why all of these products called Windows 8.</p>

<p>Why not Windows Tablet, Windows (desktop), and Windows Phone?</p>

<p>Microsoft should be clearly differentiating between these products, while still promoting the integration among them. After all, they have had no small amount of success doing this with Windows and the xBox, without calling the xBox OS Windows 7, or Windows Vista, or Windows 8 (or for that matter Windows anything).</p>

<p>So Gizmodo has declared Microsoft the most exciting company in technology at the moment. That may or may not be true, but I doubt that is going to translate into success for their new products.</p>

<h3>Speaking of Microsoft tablets and naming confusion...</h3>

<p>Microsoft just recently officially announced two new tablet devices, both called 'Surface', both 10.6" tablet devices, and both running Windows 8. OK, so they sound pretty similar. You might assume that the key differences would be the specs of the devices themselves. Well you'd be only partially right.</p>

<p>Yes the specs are quite different, but a key reason is that they have almost nothing in common, though you would easily confuse them if they were sitting side by side on display at a retail store (as they will be soon). One will run Microsoft's tablet OS, Windows RT, and the other will run Windows 8, the desktop OS. Pricing hasn't been announced, but best guesses seem to be that former will sell from anywhere between $200 - $700 and the latter will be priced close to $1000 and intended to compete with ultrabooks.</p>

<h4>Applications are another point of confusion.</h4>

<p>The desktop OS, and so one of the Surface tablets <em>but not identical looking other Surface tablet</em> will run desktop Windows apps, and Metro apps, whereas the Windows RT tablet will run only Metro apps. And Windows Phone 8 won't run either Metro or desktop apps. </p>

<p>If that's not enough, there will be two software stores across these platforms. Windows Phone has it's own bundled store called 'Marketplace' which is similar to Apple's 'App Store' and Google's 'Play' for Android. No problem there. There will also be a 'Windows Store' for downloading Metro apps, which again run on both Windows RT and Windows 8. Windows 8 users will be able to download and install Metro apps via the Windows Store (exclusively), but not desktop apps, and Windows RT users can't run desktop apps at all.</p>

<h4>Isn't Surface already a thing?</h4>

<p>As if that all weren't confusing enough, you may remember that Microsoft already has a product called Surface. It's a giant sized touch UI based platform for interactive tables and wall displays. <a href="http://seattletimes.nwsource.com/html/microsoftpri0/2018473291_microsofts_old_surface_tablet_the_ginormous_coffee.html" title="Article at seattletimes.com">That still exists, and is now called PixelSense</a> for some reason. I guess Microsoft thinks these new devices seem <em>surface-ier</em>, except they don't. The name of much more fitting for a device that is intended to be integrated into tabletops and walls (you know - surfaces).</p>

<p>PixelSense is an unusually generic sounding name. In fact it seems more like the name of a digital animation studio, or maybe a custom rendering app used by an animation studio.</p>

<p>Renaming existing products and then immediately reusing the name for an entirely different products; Establishing Windows RT as the Microsoft tablet OS and then basing one of the first in-house Microsoft tablets on Windows 8 (not RT); Running the Metro UI as the default interface across desktop, tablet, and phone platforms, despite the fact that the underlying operating systems are not the same -- It's as if their intentionally trying to cause confusion in the market.</p>

<h3>We'll see how that goes for them.</h3>

<p>Considering how badly Vista did, and how successful the still relatively new Windows 7 has been (not to mention XP which well over a decade later still accounts for a significant portion of the Windows installed base), I'd say that their going to struggle with Windows 8 on the desktop.</p>

<p>Windows Phone hasn't met expectations in terms of sales, despite being well liked by users and well received by the media. I don't see how an improved but similar Windows Phone 8 fixes that problem since Windows Phone 7.5 was so well liked.</p>

<p>That Microsoft is abandoning Windows Phone 7 users with this update, including the Nokia Lumia 900, which it's probably safe to say has been the most talked about Windows Phone device in the US to date, is not going to help. That decision probably makes a lot of sense, but it doesn't instill/loyalty.</p>

<p>If the rumors of a Google tablet are true, and the device sells for anything close to $200 as some have suggested, then the announced surface devices are already in trouble, and so is Windows RT.</p>

<p>An aggressively priced tablet from Google running the newest Android OS will dominate the market along with the iPad. That will force Amazon to respond to keep it's already successful Kindle Fire device in play, and Microsoft will struggle to establish itself.</p>

<p>I'll tell you one thing. Those keyboards aren't going to be the thing that sets surface and Windows RT apart (at least not in a positive way).</p>

<div class="notation">That's the end of the post I wrote in June before all of this played out. How did I do? Well not to toot my own horn, but reading this through now I seem like a genius.</div>
 ]]></description>
            <pubDate>Thu, 25 Oct 2012 20:33:08 EDT</pubDate>
            <guid>http://ode-is-simple.com/home/2012/10/25/20/33/08/</guid>
        </item>


        <item>
            <title>Thought for the day Oct 22, 2012</title>
            <link>http://ode-is-simple.com/home/off-topic/rob/thoughts/on-technology/thought-for-the-day2012-1022</link>
            <description><![CDATA[ <p>The solution you don't understand today will be the problem you can't solve tomorrow.</p>
 ]]></description>
            <pubDate>Mon, 22 Oct 2012 21:14:06 EDT</pubDate>
            <guid>http://ode-is-simple.com/home/2012/10/22/21/14/06/</guid>
        </item>


        <item>
            <title>I've been down on Apple lately but...</title>
            <link>http://ode-is-simple.com/home/off-topic/rob/apple/news-and-announcements/ive-been-down-onApple-lately-but</link>
            <description><![CDATA[ <div class="notation"><p>This is a rambling post that has nothing to do with Ode. You have been warned. I have no idea why I wrote this post. But here it is.</p>

<p>Let's say it's because with the Web (and Ode) I can. Actually that's a very good reason. (To be continued.)</p></div>

<p>...for the past month or so, let's say since a little while after the release of the iPhone 5, I'm feeling good about them again. It's not that I've changed my mind about my previous complaints.</p>

<p>I think their App Stores (iOS and Mac) are truly awful things -- and with the release Windows 8/Windows RT and the arrival of the Windows Store we see that model being firmly extended. (No it's not true that the best technologies or business models win. You don't need to look any further than cable tv for evidence of both.)</p>

<p>The latest version of the Mac OS Mountain Lion is should be a crime as far as I'm concerned.</p>

<p>Maybe nothing demonstrates just how lost they are more than their <a href="http://www.fastcodesign.com/1670760/will-apples-tacky-software-design-philosophy-cause-a-revolt" title="article at fastcodesign.com">'tacky' skeuomorphic software design'</a>. By the way, contrary to what some may believe, this 'recent trend' is really a revival of an idea long ago rejected as fundamentally flawed.</p>

<p>( <a href="http://www.forbes.com/sites/timworstall/2012/09/12/the-real-problem-with-apple-skeuomorphism-in-ios/" title="Artcile at Forbes.com">Another article about skeuomorphism and Apple</a> this one from Forbes. )</p>

<p>But maybe the worst thing of all is the way they tie features like iCloud (and <a href="http://support.apple.com/kb/HT4753?viewlocale=en_US&amp;locale=en_US" title="Knowledgebase article at apple.com">Auto Save and Versions</a> before it) to the App Store, i.e. prohibiting developers from incorporating these features into their apps unless sold exclusively through the App Store. (Just one of many ways Apple has turned what used to be a relatively open community into a members only club.)</p>

<p>So then what's to like?</p>

<!-- jumper:jump -->

<p>Well mostly what people aren't talking about (at least until tomorrow).</p>

<p><a href="http://www.apple.com/appletv/" title="Official AppleTV site at apple.com">AppleTV</a> (Apple's media streaming box), <a href="http://www.apple.com/airplay/" title="Official AirPlay site at apple.com">Airplay</a> (their wireless streaming suite of protocols), and <a href="http://www.apple.com/icloud/" title="Official iCloud site at apple.com">iCloud</a> (their cloud services platform) are together a near perfect solution for shuttling content between devices both at home and away. It's great to use in practice... just really well done. Having said that, iTunes is limited by the available content. This isn't Apple's fault any more then Google, Amazon, Roku, Hulu, or any of the other distributors. As long as cable and satellite are allowed to dictate what everyone else can do, any competing service is going to be severly limited. (These are people problems not technology problems.)</p>

<p>( Note: I still think cloud storage services, including the iCloud document features aren't fully baked, and I abhor the changes Apple has made to its apps in deference to iCloud. )</p>

<h3>I find that I'm looking forward to tomorrow's iPad mini event like I haven't any other in recent memory.</h3>

<p>I think Apple has positioned itself very well with this one. I say that for two reasons:</p>

<ul>
<li>The announcement itself, and the circumstances surrounding it.</li>
<li>What Microsoft is doing at the same time. ( Hint: Windows 8 is a mess and Surface isn't particularly compelling. )</li>
</ul>

<div class="notation">I know I'm sounding like an Apple fanboy here. I'm not. Probably like you, I'm trying to negotiate a path through an increasingly complex, compromised tech landscape, both as a consumer who uses Apple products and an IT professional who doesn't. To be honest I think moves by both Apple and Microsoft are giving Linux an opportunity that hasn't existed before now.</div>

<h4>The timing on this event is perfect.</h4>

<p>Of all of the times to announce new shiny technology products, this is the best.</p>

<p>People always talk about the importance of the back to school shopping season, but I don't buy it (no pun intended).</p>

<p>People who are buying then are buying because they need to, not because they want to. It's worth noting that this is one of the very few times Apple will sweeten the pot by offering extras with the purchase of products.</p>

<p>What's more, people are dealing with a lot of expenses all at the same time. And college kids are shopping with their parents who, I imagine, aren't particularly interested in spending more money for things they'll never use.</p>

<p>Just as importantly, people are busy enjoying themselves in the Summer, or they want to be. It's not a time when we're sitting around looking for any excuse to to buy something just to break up the monotony (unless we're talking about kids in high school and grade school kids, but they have very little purchasing power).</p>

<p>On the other hand, by mid Oct everyone is settled in for the long haul that lasts to the beginning of Spring.</p>

<p>Remember what it felt like during maybe the second and third months of school after the excitement and nervousness wore off and the routine kicked in? It seemed like the school year would last forever. I think that's so ingrained that most of us still feel it to some extent.</p>

<p>Also, many potential customers are starting to think about the holidays, and by the holidays I mean spending descretionary money with reckless abandon for no good reason.</p>

<p>Finally all of those college kids are at school now, still spending their parents money, but without the interference of the parents.</p>

<p>It's like a perfect storm of consumer motivation: inclination meets the expectation to spend, and opportunity.</p>

<p>And this year the economy is looking up. People might be nervous about the upcoming election, but increasingly we've learned to deal with nervous anticipation by seeking out distraction.</p>

<p>Oh yeah, and they're going to have a phenomenal next quarter that will keep their momentum going well into next year. </p>

<h4>Beyond the timing, the products expected, particularly the iPad mini, make perfect sense.</h4>

<p>Apple, along with Google and others, have gotten people used to the idea of choosing between:</p>

<ul>
<li><p>A relatively expensive, relatively large iPad available with cellular data, and the hundreds of thousands of apps available on the iOS App Store</p></li>
<li><p>A more affordable, smaller Android tablet like the Nexus 7 that lacks the premium Apple brand (not that I necessarily agree that there is something special about Apple, but others certainly seem to), few of which support cellular connectivity, or the hobbled consumption-oriented tablets from Amazon and BN.</p></li>
</ul>

<p>Note: I have been for the most part disappointed by tablets from everyone else. I'd make an exception for Google's Nexus tablet, but I don't understand why the Nexus is a WiFi only device.</p>

<p>As someone who spends a lot of time struggling with public WiFi, I feel comfortable saying that a WiFi only device may be mobile all the time, but can really only be considered connected when at home or in the office.</p>

<p>Years ago Amazon released a Kindle which included <a href="http://en.wikipedia.org/wiki/Whispernet "Article at wikipedia.org - redirects to kindle entry">Whispernet</a> allowing every user to download books wherever they were (well you know what I mean) via cellular networks, without signing up for service with a cell carrier. They boasted,</p>

<p>"<em>no annual contracts, no monthly fees, and no hunting for Wi-Fi hotspots</em>".</p>

<p>That was a vision of what mobile connectivity could be.</p>

<p>Here we are more than 3 years later, and devices like the Nexus tablet are WiFi only. It just doesn't make a lot of sense to me.</p>

<p>I'm no fan of cell service providers or long term contracts. But Apple with the iPad has demonstrated the it is possible to sell a device capable of cellular data at a reasonable cost, purchased on a month to month without a contract, directly on the device itself.</p>

<p>Anyway, with those expectations firmly seated, Apple is delivering a more affordable 7 inch device with cellular connectivity and access to the iOS App Store.</p>

<p>It's a good strategy executed very well.</p>

<p>And let's not forget that unlike the competitors Google and Amazon, Apple enjoys cushy margins on hardware in addition to the 30% they take from the sale of every paid app, and all of the other money these devices generate for them.</p>

<h3>Speaking of the the iPad, it's another reason why I have to give Apple credit.</h3>

<p>It's just an amazing device.</p>

<h3>I for one also agree with the decisions they've made with the iPhone 5</h3>

<p>Starting with the decision to call it the iPhone 5, not 'the New iPhone' or anything else <strike>clever</strike> unnecessarily confusing.</p>

<p>For one thing, I think the size and format of the device is incredibly smart. Android devices like the Galaxy S III are certainly pretty, but the more I see them, the more they start to look a little cartoonish. Given that there are already phones so large, at well over 5 inches, that people have taken to calling them 'phablets' (a portmanteau of phone + tablet), the Galaxy Note as an example, it's pretty clear that competing for the title of biggest phone makes no sense.</p>

<p>I could go on and on about this but other people have said plenty about the iPhone so I'll stop myself.</p>

<h3>I mentioned that Apple looks better when compared to what Microsoft is doing...</h3>

<p>...with Windows 8, and their Surface tablets. I think I'll save that for a separate post at this point. Although I should say what Microsoft is doing with Windows 8, Windows RT, Windows Phone 8, Surface with Windows RT, and Surface with Windows 8. It's like they're purposefully trying to confuse people.</p>
 ]]></description>
            <pubDate>Mon, 22 Oct 2012 17:49:47 EDT</pubDate>
            <guid>http://ode-is-simple.com/home/2012/10/22/17/49/47/</guid>
        </item>


        <item>
            <title>How-to: Button style links (A nice little design element)</title>
            <link>http://ode-is-simple.com/home/documentation/how-to/design-snippets/links/how-to-button-style-links</link>
            <description><![CDATA[ <h3>The humble hyperlink is an amazing thing.</h3>

<p>When I think of innovation and the web, the hyperlink immediately comes to mind. Having said that, I am well aware that the concept did not originate with the World Wide Web. In fact the hyperlink as an idea has an interesting history that, if I'm not mistaken (and wikipedia seems to agree with me), stems indirectly from an article written for Atlantic Magazine in 1945 (1945!) by Vannevar Bush titled "As We May Think". </p>

<div class="notation">
<p><a href="http://en.wikipedia.org/wiki/Vannevar_Bush" title="Entry at wikipedia.org (2012/0917 1:23 EDT)">From wikipedia:</a></p>

<p>Vannevar Bush ( /væˈniːvɑr/ van-nee-var; March 11, 1890 – June 28, 1974) was an American engineer, inventor and science administrator known for his work on analog computers, for his role as an initiator and administrator of the Manhattan Project, for founding Raytheon, and for the memex, an adjustable microfilm viewer with a structure analogous to that of the World Wide Web. In 1945, Bush published As We May Think in which he predicted that "wholly new forms of encyclopedias will appear, ready made with a mesh of associative trails running through them, ready to be dropped into the memex and there amplified".[1] The memex influenced generations of computer scientists, who drew inspiration from its vision of the future.</p>
</div>

<p>Probably the best thing I will discover today is that the original article, <a href="http://www.theatlantic.com/magazine/archive/1945/07/as-we-may-think/303881/" title="Article at theatlantic.com">As We May Think</a>, is available online, and at theatlantic.com no less. That's wonderful to see. Since it is readily available, I'll tell you that it's well worth reading. There may be no better juxtaposition of just how far we've come technologically, and yet how little little progress we've made on the crucial issue as information management.</p>

<p>From the beginning of the article:</p>

<blockquote>
  <p>Of what lasting benefit has been man's use of science and of the new instruments which his research brought into existence? First, they have increased his control of his material environment. They have improved his food, his clothing, his shelter; they have increased his security and released him partly from the bondage of bare existence. They have given him increased knowledge of his own biological processes so that he has had a progressive freedom from disease and an increased span of life. They are illuminating the interactions of his physiological and psychological functions, giving the promise of an improved mental health.</p>

<p>Science has provided the swiftest communication between individuals; it has provided a record of ideas and has enabled man to manipulate and to make extracts from that record so that knowledge evolves and endures throughout the life of a race rather than that of an individual.</p>

<p>There is a growing mountain of research. But there is increased evidence that we are being bogged down today as specialization extends. The investigator is staggered by the findings and conclusions of thousands of other workers—conclusions which he cannot find time to grasp, much less to remember, as they appear. Yet specialization becomes increasingly necessary for progress, and the effort to bridge between disciplines is correspondingly superficial.</p>

<p>Professionally our methods of transmitting and reviewing the results of research are generations old and by now are totally inadequate for their purpose. If the aggregate time spent in writing scholarly works and in reading them could be evaluated, the ratio between these amounts of time might well be startling. Those who conscientiously attempt to keep abreast of current thought, even in restricted fields, by close and continuous reading might well shy away from an examination calculated to show how much of the previous month's efforts could be produced on call. Mendel's concept of the laws of genetics was lost to the world for a generation because his publication did not reach the few who were capable of grasping and extending it; and this sort of catastrophe is undoubtedly being repeated all about us, as truly significant attainments become lost in the mass of the inconsequential.</p>
</blockquote>

<p>Wow. 2012 let me introduce you to 1945. I think you two have a lot in common.</p>

<h3>Organizing information is hard.</h3>

<p>It has been a a topic of interest for me, and a preoccupation, for a long time. At this point I can fairly quickly assess why almost any strategy will not work.</p>

<p>Somewhat related to this, the app store model(s) of software distribution that we seem so enamored with today absolutely SUCK, as do most if not all of the discovery schemes implemented as part of content/media distribution platforms (iTunes, amazon, Google's Play, Hulu, Netflix, and any number of others). For one thing popularity is a poor substitute for adequate organization and discovery -- no more than a crutch really.</p>

<p>The hyperlink, and systems that utilize it, stand out as promising in a uniquely practical way I think.</p>

<p>The hyperlink is a simple mechanism that can be utilized in any number of ways. One that allows the structure of a document to emerge through use. A large hyperlinked document is essentially both a repository of information and a purpose-built/best-fit information application.</p>

<p>The wiki stands out as an innovation that is underutilized to the point that it really defies explanation.</p>

<p><em><strong>Aside:</strong> I've yet to find a task management app that works well, and I've also yet to see one that supports hyperlinking and on-the-fly creation of linked entries. I think it's very likely that when I see one of those, I'll also be looking at the other.</em></p>

<p>As you can tell I think pretty highly of the hyperlink. That being the case I've wanted to write a post (maybe a series of posts) celebrating this most <strike>basic</strike> fundamental aspect of the web.</p>

<h3>OK enough with the build up (well maybe just a little more)</h3>

<p>I'll start by explaining how to create a simple button style link like the 'Download the Current Release' link you see above the posts on this site. You may have noticed that this style of boxy button has come into widespread use of of late (after decades of what I consider to be overly styled 3D-ish capsule buttons of one form or another). And this trend isn't just limited to the web. Among other uses, it's the hallmark of Microsoft's new Windows 8 aesthetic.</p>

<p>This time I think everyone has gotten it right.</p>

<!-- jumper:jump -->

<p>Not only are these buttons attractive looking, they're also super flexible and  simple to create. Using standard HTML and CSS we can make many different unique looking buttons, even before resorting to things like gradients and 3D effects (though you can do a lot of that too using similar techniques).</p>

<p>Note: I want to be clear that what I'm describing is creating buttons for normal hyperlinks, not styling buttons used with forms. In the case of forms I think it makes sense to keep the styling to a minimum, letting the visitor's platform dictate how various elements look and behave.</p>

<p>A typical HTML hyperlink is inline text set off in a different color and/or underlined, the combination of which makes it easy to identify the text as a link.</p>

<p>You probably know that there are various states for hyperlinks, all of which can be styled using so called 'pseudo-classes'. These pseudo-classes are:</p>

<pre><code>a:link
a:visited
a:hover
a:active
</code></pre>

<div class="notation">
<p>Important: For the styles to work as expected they must be defined in the order listed above: link --> visited --> hover --> active)</p>
</div>

<ul>
<li><p>:link - dictates the look of a link by default, i.e. when none of the other states apply.</p></li>
<li><p>:visited - dictates the appearance of a link after it has been clicked (or after the target has otherwise been visited)</p></li>
<li><p>:hover - dictates the appearance of the link when a visitor hovers the cursor over the link text in a traditional desktop web browser</p>

<p>It's important to note that hover styles do not work with multitouch interfaces used on modern mobile devices (iOS, Android, etc). It's just not possible to hover with these touch UIs. For this reason hover state styles should be considered supplemental at this point.</p></li>
<li><p>:active - dictates the appearance of the link as it is clicked.</p>

<p>Styling the active state can sort-of make up for lack of a hover state on mobile device browsers. This active state determines what the link will look like after the link is clicked and before the browser navigates away to the target. For some designs, making the styles of the active and hover states the same can work well.</p></li>
</ul>

<p>Here's <a href="#" title="Demo link to nothing">an example of a text link as styled at this site</a> (That one doesn't actually link to anything. This one is a link to the document "<a href="http://www.w3.org/TR/html401/struct/links.html" title="Official doc at w3c.org">Links in HTML documents at w3c.org</a>" just in case an example of a working external link is useful to you).</p>

<p>Here is the associated CSS:</p>

<pre><code>a:link {
  border-bottom: 1px solid #c6c6c6; /* Light grey */
  color: #3972d6; /* Med blue */
  text-decoration: none;
}

a:visited { 

  border-bottom: 1px solid #c6c6c6; /* Light grey */
  color: #3972d6; /* Med blue */
  text-decoration: none;
}

a:hover {

  border-bottom: none;
  background-color: #D2E1FA; /* Med light pale blue */
}


a:active { ; }
</code></pre>

<p>That's looks pretty good I think. (I actually do like the link styles I use here for the most part.) So why do we need something else?</p>

<p>Well, sometimes it's just nice to have a little variety. Also, some links seem to beg for the button treatment, a link to a downloadable file for example. Finally, I find that when I have a group of links together in a list, they can sort of look wimpy. Here's an example of what I'm talking about.</p>

<ul>
<li><a href="#" title="Demo link to nothing">these links all</a></li>
<li><a href="#" title="Demo link to nothing">don't go anywhere</a></li>
<li><a href="#" title="Demo link to nothing">They're just an example</a></li>
<li><a href="#" title="Demo link to nothing">I'm varying the text</a></li>
<li><a href="#" title="Demo link to nothing">So that repetition of identical</a></li>
<li><a href="#" title="Demo link to nothing">text doesn't confuse</a></li>
<li><a href="#" title="Demo link to nothing">the point I'm trying to make</a></li>
</ul>

<p>I like the look of links when they're inline <a href="#" title="Demo link to nothing">like this</a>, <a href="#" title="Demo link to nothing">and this</a>, <a href="#" title="Demo link to nothing">and this</a>, but not in a list (as above).</p>

<h3>Now (finally) let's create a button style link.</h3>

<h4>Part 1: The HTML markup for a button style link.</h4>

<h5>Step 1.1</h5>

<p>We'll start with a normal looking text link, like so:</p>

<pre><code>&lt;a href="http://www.w3.org/TR/html401/struct/links.html" title="Links in HTML documents at w3c.org"&gt;Links in HTML doc&lt;/a&gt;
</code></pre>

<h5>Step 1.2</h5>

<p>Now let's assign that a class which we will use whenever we want a link to look like a button. The name 'button' seems like an obvious choice:</p>

<pre><code>&lt;a href="http://www.w3.org/TR/html401/struct/links.html" title="Links in HTML documents at w3c.org" class="button"&gt;Links in HTML doc&lt;/a&gt;
</code></pre>

<p>That's it.</p>

<p>Nothing tricky there. All we need to do to create a button style link in our posts is add the button class to a link.</p>

<p>This how-to is really all about the CSS. The good news is that we only need to write that CSS once and then we can use it anywhere we want.</p>

<h4>Part 2: The CSS for a button style link.</h4>

<h5>Step 2.1: Let's start with the empty selectors</h5>

<p>I've already said that links are styled using the pseudo-classes: link, visited, hover, active. We want to create special versions of those for our button class:</p>

<pre><code>a.button:link { }
a.button:visited { }
a.button:hover { }
a.button:active { }
</code></pre>

<h5>Step 2.2: Now for a bit of housekeeping/tidying up</h5>

<p>These button style links are very different from our standard text links. We don't want the text link styles to interfere with our button links, so I'm going to start by resetting all of the rules I have set up for 'normal' text links. I tend to want to do these things in ways that are easily portable/adaptable from one site to the next.</p>

<p>Here that means that I'm going to reset the attributes that are likely to be defined for text links. That way I can dump these button styles into any theme and know that they'll work as-is (or at worst that I'll have only a very small amount of work to do).</p>

<p>What attributes are those?</p>

<p>Well think about a text link. What do they look like? Often though not always the following are styled:</p>

<ul>
<li><p>text-decoration</p>

<p>This attribute can take on a number of different values but is most often used to underline the link text.</p></li>
<li><p>border</p>

<p>Frequently rather than applying an underline using text-decorarion attribute a bottom border is used instead (with text-decoration set to none). Using a bottom border gives a designer more flexibility. For example, with the text-decoration property the underline is always the same color as the text itself (the value of the color attribute) but a bottom border can be any color. As another example, when using a border (and not text-decoration) it's possible to set the thickness of the line under the link text. Simiarly there are other reasons to use the border attribute to achieve an underline effect.</p></li>
</ul>

<p>I think that should just about do it.</p>

<p>There are other attributes that we will want to set for our button including (among others):</p>

<p>color, background-color, font-family, and font-size.</p>

<p>But we don't need to worry about resetting those, because we will want to set all of them for our buttons. The thing about the couple of attributes we are resetting is that we are very unlikely use them when designing a button style link (text-decoration for example). So if we don't reset them the style will show through when we don't want it to. When we know we will be using an attribute here, we don't need to bother with the reset. The color attribute is a good example.</p>

<p>What color would we even associate with a reset -- white, black? We will almost certainly want to set the color of our text with a button style link, so that stand out from, and complements, our background color, so we don't need to reset it (and arguably couldn't even if we wanted to).</p>

<p>So let's reset those attributes for a.button:link.</p>

<pre><code>a.button:link {
  text-decoration: none
  border: none

}
</code></pre>

<p>I'm also going to reset these same attribute for the other pseudo-classes. In practice this probably isn't necessary. Typically the bulk of the styling for links is done on the :link pseudo-class, with the others defining changes from the default link state. However, I have personally set both the text-decoration and border attributes for visited, hover, and active states in the past. So I'm going to include the reset on all of them initially. When incorporating this snippet into a given theme, you could certainly go trhough and remove the unneeded rules.</p>

<p>Applying those reset rules to all of the pseudo-classes gives us:</p>

<pre><code>a.button:link {

  text-decoration: none
  border: none
}

a.button:visited {

  text-decoration: none
  border: none
}

a.button:hover {

  text-decoration: none
  border: none
}

a.button:active {

  text-decoration: none
  border: none
}
</code></pre>

<h5>Step 2.3: A start</h5>

<p>Now we can get on to actually styling our button.</p>

<p>Think about what a button looks like. It looks like a block (a region) of color, text in the middle (centered horizontally and vertically), sitting some distance away from the edge of the area defined by the background color. (At least that's what the button looks like that I'll be creating.)</p>

<p>Here's the start of the CSS:</p>

<pre><code>a.button:link {

  text-decoration: none
  border: none

  background-color: #286ebb; /* Strong bright blue */
  color: #fff; /* White */
  padding: 20px;
}
</code></pre>

<ul>
<li><p>background-color</p>

<p>The background color is a strong blue. I like labeling the colors I use in CSS with comments so I'm reminded of what they are when looking at the stylesheet in a text editor. I can never remember what #286ebb looks like otherwise.</p></li>
<li><p>color</p>

<p>Because I'm defining a dark background color I want to use a light color for the text. I'm using white.</p></li>
<li><p>padding</p>

<p>Finally, I've added 20px of padding all the way around. I want to center the text 20 pixels from the top and bottom, left and right.</p></li>
</ul>

<p>Am I done?</p>

<p>No, there are a couple of other things to consider.</p>

<h5>Step 2.4: The display attribute and more</h5>

<p>First remember that text links are inline elements. It probably doesn't make sense for a button to appear in the middle of a line of text, at least not a button with 20px of padding. I want my button style links to stand on their own, the way that block elements do. So maybe I should set the display attribute to 'block', like so:</p>

<pre><code>display:block;
</code></pre>

<p>The problem with block in this case is that block elements take up 100% of the width of the container by default. So if I make my button display like a block element, I'll end up with a have a very wide button (a little more than 500 px given my current theme). That might be a useful thing to have but in this case it's not what I want. So I have to make a change.</p>

<p>I could explicitly set the width of the button, like so:</p>

<pre><code>display:block;
width: 200px
</code></pre>

<p>That will give me a button that's exactly 240px wide.</p>

<p>Why 240px not 200px?</p>

<p>Because I've already set 20px of padding on the left and right, and 200 + 20 + 20 = 240.</p>

<p>That might be what I want. Let's say I had a bunch of buttons, and I wanted them to be exactly the same width. In that case explicitly setting the width might be a good thing to do. The text will wrap when it runs out of room, making the button bigger vertically (by default).</p>

<p>But this in case I think I want the button to automatically resize to contain the text. I don't want to have to worry about constantly futzing with the width of my buttons. So block won't work.</p>

<p>Fortunately there are other options. I'm going to use table, as in:</p>

<pre><code>display: table;
</code></pre>

<p>That value will 'make the element display as a table would'. In specifically interested in two aspects of the way that tables display:</p>

<ul>
<li><p>The element will expand to accomodate width of the text</p></li>
<li><p>I can center the button if I want to by setting the value for both margin-left and margin-right to auto.</p></li>
</ul>

<p>The answer to the question you may have is, no. The question being, is it wrong to use the value table with the display attribute when the content isn't tabular data?</p>

<p>We shouldn't shouldn't use HTML to structurally mark up content up as a table when it is not actually a tablular data, that's true. But when using the display property we don't have to worry about the same issues. The value of the display attribute is purely presentational. It's widely considered to be perfectly OK.</p>

<p>You don't have to take my word for it. Instead I'll refer you to this post by Rachel Andrew, author of a couple of books on CSS and pro web designer, titled "<a href="http://www.digital-web.com/articles/everything_you_know_about_CSS_Is_wrong/" title="Article at digital-web.com">Everything You Know About CSS Is Wrong</a>".</p>

<p>From the article:</p>

<blockquote>
  <p>Hang on… Aren’t Tables for Layout Wrong?</p>

<p>Perhaps you’re feeling slightly uncomfortable about the example we’ve just seen—after all, haven’t web standards advocates like myself been insisting for years that you shouldn’t be using tables for layout?</p>

<p>The table element in HTML is a semantic structure: it describes what data is. Therefore, you should only use the table element if the data you are marking up is tabular—for example, a table of financial information. If it would normally be stored in a spreadsheet on your computer, it probably needs marking up as a table in HTML.</p>

<p>The table value of the display property, on the other hand, is simply an indi­cation of how something should look in the browser—it has no semantic meaning.</p>
</blockquote>

<p>Let's keep building up the style for our button.</p>

<p>I said I wanted to set display to table, and I think I will center these button style links. That will give us the following:</p>

<pre><code>a.button:link {
  text-decoration: none
  border: none

  background-color: #286ebb; /* Strong bright blue */
  color: #fff; /* White */
  padding: 20px;
  display: table;
  margin-right: auto;
  margin-left: auto;

}
</code></pre>

<p>Now we're getting somewhere.</p>

<h5>Step 2.5: font-family and font-size</h5>

<p>I'd also like to be able to set a custom font and font size. The font we choose will really help give our button links their own personality. Of course that personality should go along we with the overall look of your site. I'm going to use the same font I use for the headers. For this theme that means 'Droid Serif', which is available to be licensed (free of charge) as part the collection at <a href="http://www.google.com/webfonts" title="Official site at google.com/webfonts">Google Web Fonts</a>.</p>

<p>You can set font using the 'font-family' attribute, the value of which is a comma separated list of names, like:</p>

<pre><code>font-family: 'Droid Serif', Georgia, Palatino, 'Times New Roman', Times, serif;
</code></pre>

<p>I'll set a font size as well using the 'font-size' attribute.</p>

<p>Adding those those to our ruleset gives us:</p>

<pre><code>a.button:link {
  text-decoration: none
  border: none

  background-color: #286ebb; /* Strong bright blue */
  color: #fff; /* White */
  padding: 20px;
  display: table;
  margin-right: auto;
  margin-left: auto;
  font-family: 'Droid Serif', Georgia, Palatino, 'Times New Roman', Times, serif;
  font-size: 1.3em;
 }
</code></pre>

<h5>Step 2.6: Just one more thing (border-radius)</h5>

<p>As I've said I really like the simple look of blocky square buttons, but rounded rectangles are nice too. And because I want to make these simple button style links as flexible as possible, let's add the rules required for rounding the corners.</p>

<p>To do that we use the 'border-radius' attribute, passing it as many as four values in the order:</p>

<p>top-left, top-right, bottom-right, bottom-left</p>

<p>If only one value is provided, it's used for all corners. If 2 values are used the first controls the top corners and the second the bottom corners.</p>

<p>Is that really all there is to it? Not quite...</p>

<p>border-radius is fairly new. Though it is fairly well supported now, earlier vendors supported the attribute using their own prefixed version.</p>

<p>Among the prefixed versions that are or were in use are:</p>

<pre><code>-o-border-radius /* Opera */
-moz-border-radius /* Mozilla browsers */
-webkit-border-radius /* Webkit browsers (Safari, iOS Safari, Android browser) */
</code></pre>

<p>What are these?</p>

<p>Prefixed versions are often used while a proposed standard attribute is being worked on. The idea is that a browser vendor can maintain it's implementation using the prefixed version, and then when the standard is finalized (or close to being finalized), implement it using the standard name, support both names for a while, and then eventually drop support for the prefixed version.</p>

<p>Many newer attributes have been implemented in this way.</p>

<p>A quick check of the border-radius attribute at the website <a href="http://caniuse.com/#search=border-radius" title="Official site at caniuse.com">When can I use...</a> and we can see that the only prefix version(s) still showing on the compatibility table is '-webkit' which is required for older versions of iOS Safari and the Android browser. (If you click the 'Show all versions' link in the top left corner of the table you'll also see '-moz'.)</p>

<p>Given how aggressively Apple deals with updates for it's iOS platform, we probably don't need to worry about a version of iOS Safari 3, soon to be 4 versions out of date. The last version of the Android browser that lacked support for border-radius w/o the -webkit was 4 versions ago. <strong>A bigger concern is Internet Explorer.</strong></p>

<p>Though IE9, the current version, does support border-radius, no previous version does (with or without prefixes). Given that IE is the browser that tends to drag the most when it comes to users updating (though Microsoft is working on this), that's a pretty significant issue... or is it?</p>

<p>Keep in mind that all we're doing here is rounding the corners of our buttons.</p>

<p>Browsers that do not recognize the attribute will simply ignore it. Visitors using those browsers will still see and be able to interact with our button links, they'll just miss out on a little embellishment. This falls well within the bounds of progressive enhancement, which is generally considered best practice. From the wikipedia entry for progressive enhancement:</p>

<blockquote>
  <p>Progressive enhancement is a strategy for web design that emphasizes accessibility, semantic HTML markup, and external stylesheet and scripting technologies. Progressive enhancement uses web technologies in a layered fashion that allows everyone to access the basic content and functionality of a web page, using any browser or Internet connection, while also providing an enhanced version of the page to those with more advanced browser software or greater bandwidth.</p>
</blockquote>

<p>So, after all that, I'd recommend that you go ahead and use the border-radius without any of the prefixes.</p>

<div class="notation">
<p>If you ever do use the vendor prefixed versions of CSS attributes it's important to always place the standard version last. That way, it will always override the nonstandard prefixed implementations.</p>
</div>

<p>So adding that to the mix, with a nice subtle 5px value gives us:</p>

<pre><code>a.button:link {

  display: table;
  margin-right: auto;
  margin-left: auto;
  border: none
  border-radius: 5px;
  background-color: #286ebb; /* Strong bright blue */
  padding: 20px;
  text-decoration: none
  font-family: 'Droid Serif', Georgia, Palatino, 'Times New Roman', Times, serif;
  font-size: 1.3em;
  color: #fff; /* White */
}
</code></pre>

<p>(I've reordered the ruleset a little bit for no reason other than personal preference.)</p>

<p>And that should do it.</p>

<h5>Step 2.7: Finally, let's have a look at our button style link</h5>

<p><a href="http://www.w3.org/TR/html401/struct/links.html" title="Links in HTML documents at w3c.org" class="button">Links in HTML doc</a></p>

<p>That looks pretty good if I do say so myself. :) And if you don't like it, you can just play with the CSS until you do.</p>

<p>Notice that it behaves exactly like a regular text link in a lot of ways. The cursor changes to reflect the fact that it's a link for one thing. Also, the title attribute is displayed as usual when we hover over the link. Sad that we lose that info with multitouch UIs. :( Also note that the entire button is clickable, not just the text. Not only is that very button-ish, it also provides a nice big target for clicking -- great for prominant links and/or touch screen interfaces on mobile devices.</p>

<h3>Conclusion</h3>

<p>The completed version of the HTML markup and CSS styles are as follows:</p>

<h4>HTML</h4>

<pre><code>&lt;a href="http://www.w3.org/TR/html401/struct/links.html" title="Links in HTML documents at w3c.org" class="button"&gt;Links in HTML doc&lt;/a&gt;
</code></pre>

<h4>CSS</h4>

<pre><code>a.button:link {
  display: table;
  margin-right: auto;
  margin-left: auto;
  border: none
  border-radius: 15px;
  background-color: #286ebb; /* Strong bright blue */
  padding: 20px;
  text-decoration: none
  font-family: 'Droid Serif', Georgia, Palatino, 'Times New Roman', Times, serif;
  font-size: 1.3em;
  color: #fff; /* White */

}

a.button:visited {
  text-decoration: none
  border: none

}

a.button:hover {
  text-decoration: none
  border: none

}

a.button:active {
  text-decoration: none
  border: none

}
</code></pre>

<p>Notice that I've added all of the rules to the link pseudo-class leaving the others alone, with the exception resetting the text-decoration and border attributes. We certainly could add some rules to the others. For example we could very easily animate our buttons a little just by changing the color or opacity of the button for the :hover and :active states. That would be a nice touch.</p>

<p>Even without that though, I think these button style links are a nice addition to a site (especially when used for downloads, and lists of links).</p>

<p>You can easily customize these links in a number of ways, including changing:</p>

<ul>
<li>border-radius</li>
<li>background-color</li>
<li>padding</li>
<li>font</li>
</ul>

<p>You can also create multiple button link styles by simply adding additional classes, copying and pasting your first style, and then making a few changes. You'd then be able to quickly pull different button styles out of your bag of tricks anytime you want.</p>

<pre><code>&lt;a href="#" class="button_a"&gt;Button Style A&lt;/a&gt;
&lt;a href="#" class="button_b"&gt;Button Style B&lt;/a&gt;
&lt;a href="#" class="button_c"&gt;Button Style C&lt;/a&gt;
</code></pre>

<p>The hardest part is thinking of class names better than button_a, button_b, button_c.</p>
 ]]></description>
            <pubDate>Thu, 20 Sep 2012 22:06:00 EDT</pubDate>
            <guid>http://ode-is-simple.com/home/2012/09/20/22/06/00/</guid>
        </item>


        <item>
            <title>How-to: Let's make a simple JQuery photo gallery like the one they use at bestmadeco.com [U]</title>
            <link>http://ode-is-simple.com/home/documentation/how-to/photos/photo-galleries/do-it-yourself/bestmadeco-jquery-gallery/bestmadeco-inspired-gallery-how-to</link>
            <description><![CDATA[ <h3>Updates</h3>

<ul>
<li>Updated with some additional info about including the CSS discussed in the post (in response to a comment). ( <a href="http://ode-is-simple.com/home/documentation/how-to/photos/photo-galleries/do-it-yourself/bestmadeco-jquery-gallery/bestmadeco-inspired-gallery-how-to_shy#update1-bestmadeco-gallery-how-to">Jump directly to the update</a> )</a></li>
</ul>

<p>I thought it might be fun (and useful) to look at a very simple JQuery based photo gallery to see just how straightforward it can be to put something like this together.</p>

<p>This is inspired by the photo galleries used at <a href="http://www.bestmadeco.com" title="Official site of Best Made Co.">bestmadeco.com</a> a company <a href="http://www.bestmadeco.com/pages/our-story" title="About us page at bestmadeco.com">founded in 2009 around the idea of making a great axe</a>. They now makes a variety of interesting, nicely designed (by the look of it) products. The site is pretty nice too. Don't be surprised to see a bestmadeco Ode theme at some point in the future.</p>

<p>It's easy to see a finished product or feature and let your imagination get the better of you (especially when part of a big platform like Facebook). Things like this are something that anyone with an interest in web design/development is capable of. And the best part is that there any number of simple, interesting, genuinely useful projects that you can tackle once you find a platform you're comfortable with (<em>ahem</em> :) and make the commitment to learn.</p>

<p>Note: Saying "anyone is capable of putting something like this together" does not mean that you should somehow already know how, or that seeing an example of something is the same as learning how to do it. I hope you grasp the distinction I'm making here (even if I'm doing a pretty bad job with it).</p>

<p>I'll warn you right up front that this is a <a href="http://jquery.com" title="Official site at jquery.com">JQuery</a> script. So some of it is going to look cryptic if you're not familiar with JQuery. That doesn't mean that you can't follow along. I will describe everything that's happening. You can take my word for it that what I'm describing is what the code is actually doing. (I wouldn't lie to you. :) Even if you don't understand the code, I'm sure you'll be able to recognize what I'm describing in the code, at least a little bit. In fact I think you'll be surprised at just how straightforward it is.</p>

<p>Let's jump right into it.</p>

<div class="notation">
Bonus points if you read this post through from beginning to end. Triple bonus points if you implement this yourself and post a link to your gallery in the comments. (Imagine what you could do with triple bonus points. :)
</div>

<h3>Step 1: Assembling the HTML</h3>

<h4>Step 1.1</h4>

<p>First we create a div to hold the gallery itself and associate it with an id. That will allow us to target the gallery in our script (and also style the gallery container in our stylesheets).</p>

<p>I'll call it 'bestmadeco_gallery_ex':</p>

<pre><code>&lt;div id="bestmadeco_gallery_ex"&gt;&lt;/div&gt;
</code></pre>

<p>If you're familiar with HTML at all, you can see there's nothing complicated there.</p>

<h4>Step 1.2</h4>

<p>Next within the container, we're going to set up the gallery manually.</p>

<p>Before I get to that, I'll tell you that this particular gallery will consists of a numbers of photos and corresponding thumbnails (which will by used for navigation). The large photos will each be 500 x 500 px square, because a width of 500px fits nicely within the theme here, and square photos are popular these days. The thumbnails will be 50 x 50 px.</p>

<p>I've generated the images and the thumbnails ahead of time.</p>

<p>Something that's important to understand about development, and design for that matter, is that we generally accomplish complex things by breaking it down into a number of steps.</p>

<p>Our gallery script is used for displaying images we already have. It doesn't resize the images or generate thumbnails anymore than it captures the photos in the first place. That's actually a good thing. It means that it's easy to use this script regardless of the tools we use to capture, edit, resize, and archive our images. The gallery isn't tied to any one platform or single way of doing things.</p>

<p>We could automate the resizing of original photos and creating thumbnails from our large images. In fact that would be really nice. But those would be separate projects. By limiting the scope of what we do at any one time like this, we can keep projects simple (understandable) and manageable.</p>

<p>OK so here a partial list of the assets:</p>

<ul>
<li>photo1__500x500.jpg</li>
<li>thumb_photo1__50x50.jpg</li>
<li>photo2__500x500.jpg</li>
<li>thumb_photo2__50x50.jpg</li>
<li>photo3__500x500.jpg</li>
<li>thumb_photo3__50x50.jpg</li>
<li>...</li>
</ul>

<p>I'm going to organize the file structure as follows:</p>

<pre><code>shared_resources/
  images/
    photos/
      galleries/
        2012/
          08/
            bestmadeco_gallery_ex/
              photos/
                photo1__500x500.jpg
                photo2__500x500.jpg
                photo3__500x500.jpg
                ...

              thumbs/
                thumb_photo1__50x50.jpg
                thumb_photo2__50x50.jpg
                thumb_photo3__50x50.jpg
                ...
</code></pre>

<p>Given that structure, the path to 'photo1__500x500.jpg' would be:</p>

<pre><code>/shared_resouces/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo1__500x500.jpg
</code></pre>

<p>You can of course use any file/folder structure you like. (You can even save your images to a host other than the one you use for your website.) That's entirely up to you. I find that this kind of structure works well and makes it easy for me to find what I'm looking for later on -- even if admittedly it does create paths that are a little long.</p>

<p>With that out of the way, let me describe what the gallery will look like on our webpage.</p>

<p>There will be a single large image displayed within the bestmadeco_gallery_ex div. When the page is first loaded, this will be the 'photo1__500x500.jpg'.</p>

<p>Under the big image, the thumbnails will all be displayed in a row(s).</p>

<p>Something like this:</p>

<pre><code>+---------------+
|               |
|               |
|               |
|               |
|               |
+---------------+
[ ][ ][ ]
</code></pre>

<p>We'll want to arrange it so that clicking on one of the thumbnails will load the corresponding large image, swapping it in place for the one that's already there.</p>

<p>Simple enough right?</p>

<p>There are a couple of additional complications we'll need to deal with. For example, when we click the thumbnail for the photo that's already displayed, we'll want to make sure it doesn't reload. It might also be nice to preload the big images so that people using the gallery doesn't need to wait for them to load when clicking from one thumbnail to the next.</p>

<p>We'll deal these kinds of things as we come to them. For now, I just wanted to give you some sense of where we're going with this.</p>

<!-- jumper:jump -->

<h4>Step 1.3</h4>

<p>So first we'll add the large image. I'm using the id 'featured_image' to mean the image currently being viewed. I don't love that for a descriptive identifier but it's good enough. Maybe 'currently_selected' would be better. Anyway...</p>

<pre><code>&lt;div id="bestmadeco_gallery_ex"&gt;

    &lt;img id="featured_image" src="/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo1__500x500.jpg"/ height="500" width="500"&gt;

&lt;/div&gt;
</code></pre>

<p>That's just a img element. There is nothing special about it.</p>

<h4>Step 1.4</h4>

<p>Now we'll add our thumbnails.</p>

<pre><code>&lt;!-- Gallery container --&gt;

&lt;div id="bestmadeco_gallery_ex"&gt;


  &lt;!-- Large image, only one will be displayed at a time --&gt;

  &lt;img id="featured_image" src="/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo1__500x500.jpg" height="500" width="500"&gt;


  &lt;!-- Thumbnail images, one for each image in the gallery --&gt;

  &lt;!-- thumbnail 1 --&gt;

  &lt;img class="thumbnail" src="/images/photos/galleries/2012/08/bestmadeco_gallery_ex/thumbs/thumb_photo1__50x50.jpg" alt="/images/photos/galleries/2012/08/bestmadeco_gallery_exy/photos/photo1__500x500.jpg" height="50" width="50"&gt;


  &lt;!-- thumbnail 2 --&gt;

  &lt;img class="thumbnail" src="/images/photos/galleries/2012/08/bestmadeco_gallery_ex/thumbs/thumb_photo2__50x50.jpg" alt="/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo2__500x500.jpg" height="50" width="50"&gt;


  &lt;!-- thumbnail 3 --&gt;

  &lt;img class="thumbnail" src="/images/photos/galleries/2012/08/bestmadeco_gallery_ex/thumbs/thumb_photo3__50x50.jpg" alt="/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo3__500x500.jpg" height="50" width="50"&gt;


  &lt;!-- and so on --&gt;

&lt;/div&gt;
</code></pre>

<p>Again, so far this is nothing but pure HTML.</p>

<p>There is one notable, maybe unexpected, thing. I've added the path to the corresponding large photo as the alt text for each of the thumbnails.</p>

<pre><code>&lt;img class="thumbnail" ... alt="/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo3__500x500.jpg" /&gt;
</code></pre>

<p>As you'll see when we get to the script, we take advantage of this arrangement to swap the correct large image when we click on each thumbnail. We need to know which image to load, so we need to keep that info somewhere. For now I've tucked it away as the value of the alt attribute.</p>

<p><strong>It's absolutely worth pointing out that this is really an abuse of the alt attribute</strong>, which is intended to serve an entirely different purpose (and an important one at that).</p>

<p>From the Web Standards Group via a blog post at 456 Berea St titled "<a href="http://www.456bereastreet.com/archive/200412/the_alt_and_title_attributes/" title="Post at 456bereastreet.com">The alt and title attributes</a>]":</p>

<blockquote>
  <p>For user agents that cannot display images, forms, or applets, this attribute specifies alternate text</p>
</blockquote>

<p>The path to some other image, related or not, certainly doesn't fit that prescribed use.</p>

<p>It is not alternative text appropriate to be substituted for the image when the image cannot be displayed. In fact, when the image can't be displayed the this use of the alt attribute could be misleading. Furthermore, if we're using our alt attribute for this, then we can't include a proper alt attribute value. So this is a doubly bad thing. We will probably want to do something else. But for the purposes of this example, we'll stick with what we have.</p>

<p>Why did I start with this? Because it's the way they do it at bestmadeco.com.</p>

<p>Notice that we use the same class for each of the thumbnails, 'thumbnail'. This will allow us to target them together as a group in our script.</p>

<p>(Of course, whenever we need to give two or more elements the same identifier we use the class rather than id attribute, because id must be unique on the page.)</p>

<div class="notation">
<p>Note: For a dynamic site like a blog, it's important to think carefully whenever using IDs. Each page is built on the fly and may include combinations of content that we did not anticipate ahead of time (unless we're careful). We need to be absolutely sure that it's not possible for that same id to appear twice on the same page under any circumstances.</p>

<p>If we want to actually use this gallery script regularly as part of a weblog, we should probably tweak it a little to avoid the potential for problems when two or more galleries appear on the same page.</p>
</div>

<p>Except for some CSS to style our gallery, featured image, and thumbnails, the only thing remaining is the script itself.</p>

<p>(We will probably want to style these galleries at least a little. More about that later.)</p>

<h3>Step 2: Writing the gallery script</h3>

<p>To keep everything grouped together for this example, we'll add the script to the same gallery container (the 'bestmadeco_gallery_ex' div) below the HTML we just wrote. In practice, if this were a script you intended to use frequently, you'd probably want to include it as part of a theme. That way it would be available to you whenever you want to use it. (As already mentioned, in that case you'd also want to tweak it to be a little more generic than it is now so that you could use it over and over again without running into trouble.)</p>

<h4>Step 2.1</h4>

<p>We begin with a script element like so:</p>

<pre><code>&lt;script type="text/javascript"&gt;...&lt;/script&gt;
</code></pre>

<p>This is the way we define and reference all Javascript in HTML.</p>

<p>Because we will be actually writing a script here, we'll put the code between the opening and closing tags. Alternatively, we could just reference a file containing the script in the opening script tag, as the value of the src attribute, something like:</p>

<pre><code>&lt;script type="text/javascript" src="..."&gt;&lt;/script&gt;
</code></pre>

<h4>Step 2.2</h4>

<p>Let's start by preloading all of the featured images (the ones that aren't visible initially) so that visitors won't wait for them when clicking on each of the thumbnails the first time.</p>

<p>You might want to consider leaving this part out.</p>

<p>If we preload the images then visitors won't need to wait for the larger (file)size images to load as they click from one thumbnail to the next. That's the good news.</p>

<p>The bad news about preloading like this is that every visitor will always download all images with the page, even if they never click through the gallery. By just leaving the preloading code out, we can avoid that overhead. It's true that visitors will need to wait for each of the large images to load the first time they click on one of the thumbnails, but you may decide that's preferable. Keep in mind that they'll only need to wait for the images to load the first time they click the corresponding thumbnail. (After that the image will be cached.) On a fast connection the delay from loading just a single 500 x 500 px image (something like 120 KB for a high quality jpeg) might be practically unnoticeable. </p>

<p>Regardless, you should always optimize your images, keeping the file sizes as small as possible (without impacting the quality to the extent that it's noticeable).</p>

<p>Here's the code:</p>

<pre><code>&lt;script type="text/javascript"&gt;


// preload the large images

$('img.thumbnail').each(function() {

    var alt_img_location = $(this).attr('alt');
    $('&lt;img&gt;').attr('src', alt_img_location);

});
</code></pre>

<p></script></p>

<p>We're using JQuery to grab a list of all of the images with the that 'thumbnail' class.</p>

<pre><code>$('img.thumbnail')
</code></pre>

<p>For each, we're going to do something.</p>

<pre><code>$('img.thumbnail').each(function() {

    do something

});
</code></pre>

<p>The something we're going to do is:</p>

<pre><code>var alt_img_location = $(this).attr('alt');
$('&lt;img&gt;').attr('src', alt_img_location);
</code></pre>

<p>For each 'thumbnail' image we get the value of the alt attribute and assign that value as a string to the variable 'alt_img_location'.</p>

<p>Next we assign alt_img_location, which we just defined, to be the value of the 'src' attribute for an img element we're creating right here.</p>

<pre><code>$('&lt;img&gt;')
</code></pre>

<p>The image element we're creating would look something like:</p>

<pre><code>&lt;img src="alt_img_location"&gt;
</code></pre>

<p>Using 'thumb_photo2__50x50.jpg, substituting the path to that photo in place of the variable alt_img_location, it would give us:</p>

<pre><code>&lt;img src="/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo2__500x500.jpg"&gt;
</code></pre>

<p>That's a pretty basic img element without many of the usual attributes. We haven't included title, alt, height, or width.</p>

<p>That's ok.</p>

<p>In fact, though we've created the img element, we haven't added it to the page. That means it won't actually appear on the page, which is what we want. We're preloading the images here. We don't want to make any changes to the page yet. Just creating the element as we've done above is enough to load the image.</p>

<p>It might not look like it, but .each() is a loop.</p>

<p>We start with a list of elements (all img with a the class of thumbnail):</p>

<pre><code>$('img.thumbnail')
</code></pre>

<p>and then we do something to each of those elements:</p>

<pre><code>$('img.thumbnail').each(...)
</code></pre>

<p>That does it for the code that preloads the large images.</p>

<h4>Step 2.2</h4>

<p>Next we want to attach to each of our thumbnail images the function that will actually drive the gallery. We do that by attaching a function to the "click" event of each thumbnail, using <a href="http://api.jquery.com/on/" title="Documentation at jquery.com">JQuery's .on( ) method</a>.</p>

<p>This will make it so the function is triggered when the image is clicked.</p>

<pre><code>// Attach a function to all images with class 'thumbmail'.

$('#bestmadeco_gallery_ex').on('click', 'img.thumbnail', function() {

    do something

});
</code></pre>

<p>Note: I'm actually using the .on( ) method with the containing element (i.e. the div with id 'bestmadeco_gallery_ex') rather than the thumbnails. Why? Because there is only one containing div but there could be any number of thubnail images. It's more efficient to do less attaching and accomplish the same thing.</p>

<p>From <a href="http://api.jquery.com/on/" title="Documentation at jquery.com">the documentation for .on( )</a></p>

<blockquote>
  <p>When a selector is provided, the event handler is referred to as delegated. The handler is not called when the event occurs directly on the bound element, but only for descendants (inner elements) that match the selector.</p>

<p>...</p>

<p>In addition to their ability to handle events on descendant elements not yet created, another advantage of delegated events is their potential for much lower overhead when many elements must be monitored.</p>
</blockquote>

<p>(If you don't know what all of that means, don't worry about it.)</p>

<h4>Step 2.3</h4>

<p>Next, we need to write the code that will be trigged whenever one of the thumbnail images is clicked.</p>

<p>We'll store the current thumbnail image object in a variable called, appropriately enough, 'thumbnail_image_object'. That object is available to us as the symbol 'this'. We know that from the documentation for the .on( ) method. </p>

<p>From <a href="http://api.jquery.com/on/" title="Documentation at jquery.com">the documentation for .on( )</a></p>

<blockquote>
  <p>When jQuery calls a handler, the this keyword is a reference to the element where the event is being delivered; for directly bound events this is the element where the event was attached and for delegated events this is an element matching selector...</p>
</blockquote>

<p>The code for this little bit is:</p>

<pre><code>// Store the thumbnail image object
// as 'thumbnail_image_object'. 

var thumbnail_image_object = $(this);
</code></pre>

<p>Next, we can deal with a little wrinkle.</p>

<p>I've already mentioned that we don't want the script to do anything if the visitor clicks the thumbnail corresponding to the large image already displayed. It's not necessary for one thing. And if we animate loading those large images, it would be obvious that we were loading the image a second time. That probably wouldn't look right.</p>

<p>So how can we determine if the large image corresponding to the thumbnail clicked is the one already displayed?</p>

<p>Remember, I said that the script would copy the value of the alt attribute from the thumbnail image to the value of the src attribute of the corresponding large image. So, if the alt attribute value of the thumbnail being clicked is the same as the src attribute value of the large image on the page now, then we know the large image for the thumbnail clicked is already displayed.</p>

<p>Here's the code:</p>

<pre><code>// Determine if the large image for the
// thumbnail_image_object clicked is
// already displayed. And if so, return from the function
// immediately. (Without doing anything.)

if(thumbnail_image_object.attr('alt') == $('#featured_image').attr('src')) {

    return;

}
</code></pre>

<p>With the exception out of the way, all we have left to do is write the behavior we want the rest of the time.</p>

<p>We'll use a nifty fade effect to transition from the current large image to the one for to the thumbnail clicked. We can do this with <a href="http://api.jquery.com/fadeTo/" title="Documentation at jquery.com">JQuery's .fadeTo( ) method</a>. Actually we'll use .fadeTo( ) twice, once to fade the current large image out, and again to fade the new large image in. </p>

<p>The code:</p>

<pre><code>// Use .fadeTo() with of the current
// #featured_image element to fade out the current image
// and fade in the new one.

$('#featured_image').fadeTo(200, 0, function() { 

    do something

});
</code></pre>

<p>Here we are using .fadeTo( ) with the element identified by the 'featured_image' id (the large image currently displayed).</p>

<p>fadeTo( ) does two things:</p>

<ol>
<li>It adjustments the opacity (the second parameter) of the target over a specified duration (the first parameter).</li>
</ol>

<p>In this case the duration is 200 milliseconds and the opacity is 0. Opacity values are on a scale of 1 to 0, where 0 is completely transparent (unseen) and 1 is completely opaque (visible). So here we're fading out the current image over 200 milliseconds.</p>

<ol>
<li>It lets us set a function that will be called when the fade is complete. So after the specified duration .fadeTo( ) will run the function.</li>
</ol>

<p>What does the function do?</p>

<pre><code>// Copy the value of the alt attribute
// from the thumbnail clicked to the src attribute of the large
// image.

$('#featured_image').attr('src', thumbnail_image_object.attr('alt'));


// Fade in the the updated '#featured_image' after it's finished loading.

$('#featured_image').load(function() { $(this).fadeTo(100, 1); });
</code></pre>

<p>First we set the value of the src attribute for the element identified by the id 'featured_image' to the value of the alt attribute of the thumbnail_image_object, which is a variable we previously assigned the object corresponding to thumbnail image clicked.</p>

<p>Remember that when we added the gallery to the page we set the values of the alt attributes of our thumbnail images to be the path to the corresponding large image. This is where we make the swap.</p>

<pre><code>$('#featured_image').attr('src', thumbnail_image_object.attr('alt'));
</code></pre>

<p>Next we use <a href="http://api.jquery.com/load-event/" title="Documentation at jquery.com">JQuery's .load( ) method</a> with the '#featured_image' element. .load( ) will wait until after the element it's attached to is loaded, and then run the function we pass to it:</p>

<p>If we look closely at that line:</p>

<pre><code>$('#featured_image').load(function() { $(this).fadeTo(100, 1); });
</code></pre>

<p>We see that the function passed to .load( ) is:</p>

<p>function() { $(this).fadeTo(100, 1); }</p>

<p>This is nothing but another use of .fadeTo( ). This time we're fading in to 1 (completely opaque) over 100 milliseconds (rather than fading out to 0 as we did before.)</p>

<p>.fadeTo( ) works on the element it's attached to, which in this case is:</p>

<pre><code>$(this)
</code></pre>

<p>Here the symbol 'this' refers to the element identified with the id '#featured_image'. (We saw this same thing earlier with .on( )).</p>

<p>And we're done. That's all there is to it.</p>

<h3>Conclusion</h3>

<p>The complete script looks like this:</p>

<pre><code>&lt;script type="text/javascript"&gt;

// preload the large images

$('img.thumbnail').each(function() {

    var alt_img_location = $(this).attr('alt');
    $('&lt;img&gt;').attr('src', alt_img_location);

});


// Attach a function to all images with class 'thumbmail'.

$('#bestmadeco_gallery_ex').on('click', 'img.thumbnail', function() {


    // Store the thumbnail image object
    // as 'thumbnail_image_object'. 

    var thumbnail_image_object = $(this);


    // Determine if the large image for the
    // thumbnail_image_object clicked is
    // already displayed. And if so, return from the function
    // immediately. (Without doing anything.)

    if(thumbnail_image_object.attr('alt') == $('#featured_image').attr('src')) {

        return;

    }


    // Use .fadeTo() with of the current
    // #featured_image element to fade out the current image
    // and fade in the new one.

    $('#featured_image').fadeTo(200, 0, function() { 

        // Copy the value of the alt attribute
        // from the thumbnail clicked to
        // the src attribute of the large image.

        $('#featured_image').attr('src', thumbnail_image_object.attr('alt'));


        // Fade in the the updated '#featured_image'
        // after it's finished loading.

        $('#featured_image').load(function() { $(this).fadeTo(100, 1); });


    });

});

&lt;/script&gt;
</code></pre>

<p>I mentioned that we probably want to add some CSS to control the look of the elements in the gallery. Though there is a lot we could do, there is at least one thing we really should do.</p>

<p>If you look at the HTML for the gallery you'll notice that there is no structural markup between the '#featured_image' and the '.thumbnail's. They're all together in the same container (i.e. not segmented into separate divs or something like that).</p>

<p>img is an inline element by default. That means that multiple consecutive images will appear next to each other on the same line, in just the same way that characters and words within a paragraph appear next to each other on the same line. So if our container is wide enough, the thumbnails will appear next to the large image rather than beneath it. That's not what we want. Fortunately, it's an easy fix.</p>

<p>We can just set the value of the 'display' property of the featured image to 'block'. That's all we have to do to ensure that it will appear on it's own with the thumbnails underneath.</p>

<pre><code>#featured_image {
    display: block;
    margin: 0 0 10px 0;
}
</code></pre>

<p>I've also added a bottom margin to create some space between the bottom of the large image and the top of the thumbnails.</p>

<p>I'd also probably add some minimum styling to the thumbnail images. The complete CSS is as follows:</p>

<pre><code>#featured_image {
    display: block;
    margin: 0 0 10px 0;
}

.thumbnail {
    float: left;
    margin: 0 5px 0 0;
    border: 1px solid #413e3e; /* Dark med grey */
}
</code></pre>

<p>One last gotcha. This is another example of a common 'problem' in web design. I've intentionally designed the gallery to make sure we trip over this issue. As you can see in the CSS rule above, I've floated those images to the left. float is a postional property intended to allow content, which might be 'display: block' in nature to flow around the floated element. The easiest example to visualize is the common print layout that features in image to the left or right with text flowing around the image (i.e. an image floated to the left with text appearing to the right of it).</p>

<p>Floats are often used to create a grided layout. Let's say we had a number of elements like this:</p>

<p>[1]
   [2]
   [3]</p>

<p>If we float all of those images to the left they will align themselves as follows:</p>

<p>[1][2][3]</p>

<p>If there the container is 3 of these elements wide, and we have 6 then they'll wrap nicely, like:</p>

<pre><code>[1][2][3]
[4][5][6]
</code></pre>

<p>The elements could be anything really from images to embedded objects and text, to major sections of a layout. That's a very handy thing to be able to do. However there are some complications. A complication is not necessarily a problem. If it behaves predictably, can be worked around and potentially serves a useful purpose or is necessitated by a behavior that serves a useful purpose then I think complication, and not problem, is the correct term.</p>

<p>So what's the complication?</p>

<p>When a containing contains floated elements, the parent height collapses to the top of the the floated content. If the parent contains nothing but floated content, then it will collapse to a height of zero. Put another way, the container doesn't expand to a height large enough to contain floated elements.</p>

<p>Let's say that we have a container with floated content like so:</p>

<pre><code> top-of-container
  [1][2][3] &lt;-- floated content
  [4][5][6] &lt;-- floated content 
  [7][8][9] &lt;-- floated content
 bottom-of-container
</code></pre>

<p>Though the structure of that document will be preserved, the layout will look like:</p>

<pre><code> top-of-container
 bottom-of-container
  [1][2][3] &lt;-- floated content
  [4][5][6] &lt;-- floated content 
  [7][8][9] &lt;-- floated content
</code></pre>

<p>That will cause blocks elements immediately following the container to ride up and flow around the floated content. This behavior is both well documented and predictable.</p>

<p>Typically, when you want content that comes after a floated element NOT to flow around it, you set the clear property for those elements. However does not address the complication of the parent element collapsing. The initial solution was to place an element immediately after the floated elements, inside the container. Something like:</p>

<p><br style="clear:both" /></p>

<p>What's wrong with this? Well... nothing and everything. On the one hand it works fine and doesn't cause any problems. On the other, there is a very strong belief among <strike>some</strike> most designers that this kind of hack-y presentation markup is very bad form -- something to be avoided at all costs. And there are alternatives that work just as well.</p>

<p>The 'clearfix hack' is a general sort of a catch all term for any technique that fixes the problem of the collapsing container without structural markup (i.e. using CSS exclusively). There have been a number of refinements to the technique. It's actually a pretty interesting example of the way that ideas evolve in an open community. Probably the newest technique, and something that might be considered more or less a final soluton is the so called <a href="http://nicolasgallagher.com/micro-clearfix-hack/" title="Blog post about at http://nicolasgallagher.com">'micro clearfix hack'</a> credited to Nocolas Gallagher.</p>

<p>You can grab the CSS at the link above, or for your convenience, here it is:</p>

<pre><code>/**
 * For modern browsers
 * 1. The space content is one way to avoid an Opera bug when the
 *    contenteditable attribute is included anywhere else in the document.
 *    Otherwise it causes space to appear at the top and bottom of elements
 *    that are clearfixed.
 * 2. The use of `table` rather than `block` is only necessary if using
 *    `:before` to contain the top-margins of child elements.
 */
.cf:before,
.cf:after {
    content: " "; /* 1 */
    display: table; /* 2 */
}

.cf:after {
    clear: both;
}

/**
 * For IE 6/7 only
 * Include this rule to trigger hasLayout and contain floats.
 */
.cf {
    *zoom: 1;
}
</code></pre>

<p>Applying the class 'cf' to the containing element, #bestmadeco<em>gallery</em>ex in our example, addresses the issue. How? In the case of modern browsers that support them by using the :before and :after pseudo classes to introduce the required clear attribute. The most of the rest of the fix addresses pecularities of specific browsers. In the case of early versions of IE, an additional 'trick' is required to trigger a 'hasLayout' property, unique to IE, and without which IE will behave differently.</p>

<p>So there you go a more or less complete image gallery. It seems like a lot when you write it all out like this but if you go back and look at just the code itself I think you'll be impressed by just how little there is too it. There's a little HTML, a little of JQuery's unique style of writing Javascript, a little CSS.</p>

<p>All of this is perfectly standards compliant, and it should work great in any browser including mobile devices.</p>

<h3>Going forward</h3>

<p>From this point we could do a number of things from automating the process of resizing our original images and generating thumbnails, to using Ode to build these kinds of galleries for us on the fly.</p>

<p>Imagine being able to include something like the following in our posts and letting Ode (via an addin) build everything we just did on the fly.</p>

<pre><code>[[Gallery path:path/to/gallery-folder]]
</code></pre>

<p>That's certainly doable.</p>

<p>We could also improve the script itself in any number of ways. For example, we could:</p>

<ul>
<li>Change the durations of those .fadeTo( ) calls.</li>
<li>Come up with a better way to deal with storing the paths to the large images.</li>
<li>Add some missing attributes to featured image (like title, which could serve as a simple caption).</li>
<li>Really get fancy with the styling, including maybe adding a proper caption to the large image.</li>
</ul>

<h3>Final thoughts</h3>

<p>There is nothing Ode specific about this gallery. That doesn't mean that Ode isn't helping. Ode is staying out of the way, and so not adding any additional complexity, while also passing along the full potential of the technologies.  </p>

<h3>Did I forget something? Oh yeah...</h3>

<p>You didn't think I'd end without an example did you?</p>

<div id="bestmadeco_gallery_ex" class="cf">

    <img id="featured_image" src="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo1__500x500.jpg" height="500" width="500">

    <img class="thumbnail" src="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/thumbs/thumb_photo1__500x500.jpg" alt="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo1__500x500.jpg" height="50" width="50">

    <img class="thumbnail" src="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/thumbs/thumb_photo3__500x500.jpg" alt="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo3__500x500.jpg" height="50" width="50">

    <img class="thumbnail" src="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/thumbs/thumb_photo4__500x500.jpg" alt="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo4__500x500.jpg" height="50" width="50">

    <img class="thumbnail" src="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/thumbs/thumb_photo5__500x500.jpg" alt="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo5__500x500.jpg" height="50" width="50">

    <img class="thumbnail" src="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/thumbs/thumb_photo6__500x500.jpg" alt="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo6__500x500.jpg" height="50" width="50">

    <img class="thumbnail" src="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/thumbs/thumb_photo7__500x500.jpg" alt="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo7__500x500.jpg" height="50" width="50">

    <img class="thumbnail" src="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/thumbs/thumb_photo8__500x500.jpg" alt="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo8__500x500.jpg" height="50" width="50">

    <img class="thumbnail" src="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/thumbs/thumb_photo9__500x500.jpg" alt="/shared_resources/images/photos/galleries/2012/08/bestmadeco_gallery_ex/photos/photo9__500x500.jpg" height="50" width="50">

<script type="text/javascript">

// preload the large images

$('img.thumbnail').each(function() {

    var alt_img_location = $(this).attr('alt');
    $('<img>').attr('src', alt_img_location);

});


// Attach a function to all images with class 'thumbmail'.

$('#bestmadeco_gallery_ex').on('click', 'img.thumbnail', function() {


    // Store the thumbnail image object
    // as 'thumbnail_image_object'. 

    var thumbnail_image_object = $(this);


    // Determine if the large image for the
    // thumbnail_image_object clicked is
    // already displayed. And if so, return from the function
    // immediately. (Without doing anything.)

    if(thumbnail_image_object.attr('alt') == $('#featured_image').attr('src')) {

        return;

    }


    // Use .fadeTo() with of the current
    // #featured_image element to fade out the current image
    // and fade in the new one.

    $('#featured_image').fadeTo(200, 0, function() { 

        // Copy the value of the alt attribute
        // from the thumbnail clicked to
        // the src attribute of the large image.

        $('#featured_image').attr('src', thumbnail_image_object.attr('alt'));


        // Fade in the the updated '#featured_image'
        // after it's finished loading.

        $('#featured_image').load(function() { $(this).fadeTo(100, 1); });


    });

});

</script>

</div>

<p>Looks pretty good to me. Not fancy or clever, it's just good, honest, useful open web awesomeness :)</p>

<h3 id="update1-bestmadeco-gallery-how-to">Update 1 (2012/0915 7:03 PM EDT): More about CSS</h3>

<p>I'm adding this info in response to a comment from ealthodores which reads in part:</p>

<blockquote>
  <p>... just curious, where have you put the css to style #featured_image and .thumbnail, and for the clearfix hack? I can't find it in any linked stylesheet or inline ... ?</p>
</blockquote>

<p>That's a good question. Let me try to answer it for you.</p>

<h4>Creating a stylesheet</h4>

<p>I recommend you create a separate stylesheet, just a text file called something like 'extras.css' (anything-you-want.css).</p>

<p>You can place the file in a specific theme directory if you intend to use it with just that theme, something like:</p>

<p>.../themes/html-2011_1212/
     date.html
     extras.css
     page.html
     ...</p>

<p>Alternatively, you can put the file in place where you can conveniently link to it from any theme. For when I want to go this route, I have a 'shared_resources' folder the root of my site at:</p>

<pre><code>/shared_resources
</code></pre>

<p>That's where I put images and other resources, including shared styleseheets. It looks something like:</p>

<pre><code>/shared_resources/stylesheets/extras.css
</code></pre>

<p>That works well for me, and so you might want to do something similar.</p>

<p>OK, after you've created it, you can put all of the styles discussed in the post in that extras.css file.</p>

<p>I recommend that you take a moment to label each section so that later on you can easily identify what it does and why you created it. (I also like to include the date in those comments whenever I add a new rule.) Comments in stylesheets are set off by pairs forward slashes and asterisks.</p>

<pre><code>/* comments go here */
</code></pre>

<h4>Linking to the stylesheet you just created</h4>

<p>Now you just need to link that extras.css stylesheet into your theme(s).</p>

<p>There are two ways:</p>

<h5>1. Link it directly to the page theme file</h5>

<p>Look for the link to the existing stylesheet(s) in the head section of the page file. It will look something like:</p>

<pre><code>&lt;!-- External stylesheet(s) --&gt;

&lt;link
rel='stylesheet'
type='text/css'
href='logic_a.css'&gt;
</code></pre>

<p>You want to add a link to the extras stylesheet below it:</p>

<pre><code>&lt;link
rel='stylesheet'
type='text/css'
href='extras.css'&gt;
</code></pre>

<p>More commonly that's all written on a single line like:</p>

<pre><code>&lt;link rel='stylesheet' type='text/css' href='extras.css'&gt;
</code></pre>

<p>Done.</p>

<h5>2. Import it into an existing stylesheet (which is already linked to the theme)</h5>

<p>This way you don't edit the page file at all. Instead, open the existing stylesheet and add the following line somewhere near the top:</p>

<pre><code>@import "extras.css";
</code></pre>

<p>The stylesheet will be read at the point where the import statement appears.</p>

<p>I slightly prefer the second approach myself because it seems like a better way to group the stylesheets and separate them from the structural markup. You can open one stylesheet to see all of the style rules and the import statements. There is just one point of attachment for styles.</p>

<p>(That having been said I don't know that there is any good reason to prefer one over the other.)</p>

<p>Taking a closer look at the import statement.</p>

<pre><code>@import "extras.css";
</code></pre>

<p>The value inside the quote marks should be the path to the stylesheet. It can be relative or absolute. As written, extras.css should be located in the same directory as the stylesheet containing the @import line. That's nice and easy. If I were going to put the file in a separate location, maybe to be shared among multiple themes, I'd use an absolute path, like:</p>

<pre><code>/shared_resources/stylesheets/extras.css
</code></pre>

<p>Making the import statement:</p>

<pre><code>@import "/shared_resources/stylesheets/extras.css";
</code></pre>

<p>Stay away from relative paths unless the imported stylesheet is in the same directory, where it will most likely travel with the associated stylesheet (preserving the relative path). Otherwise you may move one without the other at some point in the future and be left wondering what went wrong. (Or if you don't notice right away, you'll have broken looking pages until you catch the problem.)</p>

<p>Done.</p>

<p>I think that should do it. Again, none of this is Ode specific. It's always nice to spend our time learning/practicing the standard/generally applicable way of doing things. </p>
 ]]></description>
            <pubDate>Sat, 15 Sep 2012 19:23:23 EDT</pubDate>
            <guid>http://ode-is-simple.com/home/2012/09/15/19/23/23/</guid>
        </item>


        <item>
            <title>Apple's Pages word processor is what I used to love about the Mac platform</title>
            <link>http://ode-is-simple.com/home/off-topic/rob/technology/apple/iwork/pages-is-a-great-app</link>
            <description><![CDATA[ <p>I just spent the night finishing up a proposal for a web design project that will probably never see the light of day (or if it does, I will be severely underpaid and humiliated too). So why am I not exhausted and depressed as I wait for a train into the city at 6:30 in the morning (to start a day that will most likely be exhausting and depressing) -- because of Pages.</p>

<p>It is a <strike>fucking</strike> <strike>truly</strike> fuuucccckiiing sweet application that's wonderful to use. It's always been good, right from the first release, but I must not have been paying attention through the little point releases because now it's as close to perfect as any app I've ever used in my entire life.</p>

<p>You want to create text boxes and define how the text flows between them -- no problem. You want to use the app as a standard word processor with text right in the body of the document at the same time. Well why the hell not -- no problem. And guess what... when you drag those text boxes around, the text in the body of the document behaves predictably. See that's what I didn't expect. It's a mind blowing revelation. An app that behaves exactly the way I wanted it to. But that's just the beginning.</p>

<p>You can take those same text box, or a shape, or whatever, and make it inline or take it out of the document flow and float it by clicking a button, and it works beautifully.</p>

<p>You can define the width of a line down to a quarter of a pt, which is just what I needed to made a little header style I wanted. Making it 1 pt would have killed it.</p>

<!-- jumper:jump -->

<p>Did you ever find yourself fighting with a list?</p>

<p>You make a list, and then everything is a list, but you just wanted the parts you wanted to be a list to be a list, and the rest of it paragraphs within the list. You try to fix it, but each return and tab fights you half to death... well Pages was actually helping me out.</p>

<p>Defining a header and footer - right where I thought it would be. Adding a page count, but not on the first page - just tick a box that is sitting right there staring you in the face called something awesomely obvious.</p>

<p>Redefine the style of a header and footer, well of course you just edit it like the rest of the document. F'ing amazing.</p>

<p>Throw in a table, format columns and rows by clicking the columns and rows one at a time or together. Select the whole table and do whatever it would make sense to do to the whole table. Create multiple headers and footers in a table, something you dont think you need until you need it, and there it is. Even the cell borders behaved better than what I'm used to somehow.</p>

<p>I could actually feel myself getting more creative. The table I finished with was better than the table I started to make, because it was too enjoyable not to make it better. I had to stop myself from throwing in a totally unnecessary chart just because I knew it would work great.</p>

<p>Even the print dialog was just fantastic to use.</p>

<p>And when I finished, it's an export to PDF, attach it to an email, and done.</p>

<p>Pages is $15.00! What?!</p>

<p>Not so long ago I bought InDesign just to do stuff I can do in Pages, and for this stuff Pages is way better.</p>

<p>At on time people paid closer to $1500.00 for this sort of thing, except it was nothing at all like this. I think I can honesty say that if I had the money I would gladly pay fifteen-freakin-hundred dollars for Pages. It's unbelievable.</p>

<p>Does anyone care? No.</p>

<p>Instead everyone is giddy over cloud services that work like crap and sync services that are even worse. (By the way, sync is hard and we're not very close to having it solved.) Or we're busying ourselves talking about how important Twitter is. Forget that it's one of the spammiest, ripe for abuse platforms ever <strike>invented</strike> created. (We all owe an apology to email for giving it such a hard time.) Oh yeah, and it's finally dawning on devs that investing in someone else's proprietary platform is maybe not such a good idea. Yes when they say the terms of service can be changed at anytime for any reason whatsoever, that's what they mean.</p>

<p>I've used probably every goofy cool-kid invoicing app out there, and Pages is better. Sure you have to set the invoice up -- exactly one time. But they protest, isn't it great that you can save old invoices and use them as the basis of new invoices? Isn't that awesome about this new service, or app, or whatever? Well the thing is, we've always been able to do that, right up until some first release of a cool-kid service, or app, or whatever took it away.</p>

<p>Imagine how much Apple's stock will go up if they actually figure out how to let people include more than one type of attachment in an email on the iOS platform without jumping in and out of multiple applications. (Here's a hint, check <a href="http://en.wikipedia.org/wiki/File_manager" title="Entry at wikipedia.org 2012/0909 7:41am">the Wikipedia entry for file manager</a>.</p>

<p>What is it about people that we can't appreciate the great things we have because we're too busy chasing after what's next? (I actually think I have a pretty good handle on what it is, but here I just want to ask the rhetorical question.)</p>

<p>Anyway, Pages is a great, great app. That was one of the better nights I've had in a long time. Thanks Pages for making me feel like I'm not crazy. And to whoever works on Pages and iWork at Apple, thanks. If it were up to me, you'd be running the show over there.</p>

<p>I know a lot of people who might be interested in this project have no use for most of what Apple does. I can understand that. But some of what they've done over the years has been great. Not Steve-Jobs-mentioned-at-both-the-Democratic-and-Republican-National-Conventions-within-a-week-nearly-a-year-after-he-died great, but just great to use.</p>

<p>When I was an undergrad in college I wasn't in the CS department. I never even considered it. I didn't know I could do that. I didn't feel smart enough or special enough or something enough. I was in the Classics department studying Latin by day and then up every night with my Mac. It was the first computer I ever owned. We didn't have a lot of money when I was a kid. I used to sign out blocks of time after school on the one PC at the public library once a week.  I bought that first Macintosh computer with my first credit card. I wonder if I've paid it off yet. (That's a joke.) But funny story, I called the credit card company to make sure the charge wouldn't get rejected while I was at the register. I'd never bought something so expensive in my entire life. And then I spent as much time as I could figuring it out. That's what "the computer for the rest of us" means to me.</p>

<p>Updated 2012/0910 4:47pm: I changed a couple of words here and there and corrected a couple of typos, or silly grammatical things. Of course I'm sure you can still find typos, and I'd fail if I turned this in as homework for an elementary English grammar class. But it's better than it was before. :)</p>
 ]]></description>
            <pubDate>Mon, 10 Sep 2012 08:01:15 EDT</pubDate>
            <guid>http://ode-is-simple.com/home/2012/09/10/08/01/15/</guid>
        </item>


        <item>
            <title>Ode - like taking the stairs</title>
            <link>http://ode-is-simple.com/home/news/about_ode/ode-like-taking-the-stairs</link>
            <description><![CDATA[ <p>I often find myself trying to explain this project to myself. Why does it exist? What's the benefit? Who is it for?</p>

<p>It's not doubt in the project so much as it is a reality check. I like to question my previous assumptions. I've found that it's easy to make wrong choices up front with the best of intentions. But those initial mistakes aren't the real issue. A far greater problem is that after we make those initial decisions we stop making unbiased value judgements, as we did in the first place. Instead our thinking from that point on is dominated by rationalizations of what we've already done.</p>

<p>I find analogy to be a very effective tool for putting aside bias and seeing things, even past choices, as they really are. If I can see the similarities between something I'm doing and something else that's good, and about which I do not have strong feelings, then maybe there is reason to suspect that I'm doing good.</p>

<p><iframe width="500" height="410" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://maps.google.com/maps?q=Charles%2FMGH+Station,+Boston,+MA&amp;hl=en&amp;sll=42.36143,-71.06884&amp;sspn=0.016585,0.033946&amp;oq=Charles%2FMGH+station+Boston,+MA&amp;hnear=Charles%2FMGH+Station&amp;t=m&amp;ie=UTF8&amp;hq=&amp;z=14&amp;ll=42.362191,-71.071801&amp;output=embed"></iframe><br /><small><a href="https://maps.google.com/maps?q=Charles%2FMGH+Station,+Boston,+MA&amp;hl=en&amp;sll=42.36143,-71.06884&amp;sspn=0.016585,0.033946&amp;oq=Charles%2FMGH+station+Boston,+MA&amp;hnear=Charles%2FMGH+Station&amp;t=m&amp;ie=UTF8&amp;hq=&amp;z=14&amp;ll=42.362191,-71.071801&amp;source=embed" style="color:#0000FF;text-align:left">View Larger Map</a></small></p>

<p>Well today I had a was walking at the Charles St. subway station near Beacon Hill in Boston and I had a moment of realization. Walking up the stairs to the platform I looked over at the dozens and dozens of people crowding onto the elevator. Next, I looked ahead of me at 3 sections of double-wide stairs separated by handrails and didn't see a single person. A quick turn of my head to look behind me confirmed that I was alone.</p>

<p>That's when it occurred to me that using and working on Ode is like taking the stairs.</p>

<!-- jumper:jump -->

<p>The escalator is easier. But it's also far more complicated. When they break, as they often do, the people who use them everyday are helpless to fix them; both because they don't know how, and because they are prohibited from even trying.</p>

<p>Stairs are more difficult, but the vast majority us are more than capable of them. They are far less complex, and as a direct result of that simplicity, not only are they more understandable, but they also don't break.</p>

<p>Though harder, the effort of taking the stairs is good for us. By choosing to tackle the small challenge of walking up the stairs, we can be fitter and so better able to deal with more difficult challenges which we will undoubtedly encounter. <span class="hl_black">Taking the stairs is preparation for exploring those parts of the world we all share where others haven't put escalators.</span> Just as importantly, out of the crowd, and without the one size fits all automation, we can go at our own pace when we take the stairs.</p>

<p>Both the stairs and the escalator take you to the same place. So there is a choice to make. Do you take the easy, more popular route, or do you go the harder way and realize the benefits that come from it?</p>

<p>Of course I can't answer that question for you, just as I can't tell you if you're better off with this project or something like Facebook (or Wordpress). </p>

<p>When given the choice, I take the stairs.</p>
 ]]></description>
            <pubDate>Fri, 07 Sep 2012 19:26:38 EDT</pubDate>
            <guid>http://ode-is-simple.com/home/2012/09/07/19/26/38/</guid>
        </item>


        <item>
            <title>It has its high points but...</title>
            <link>http://ode-is-simple.com/home/off-topic/rob/thoughts/on-life/life-is-a-humiliating-ordeal</link>
            <description><![CDATA[ <p>...overall life is a humiliating ordeal.</p>

<p>So the good news is that if you feel like that at times -- maybe while trying to learn something new -- it's not just you. The bad news is that this realization doesn't really help in any way. You're still left with no option but to muddle through.</p>
 ]]></description>
            <pubDate>Sun, 02 Sep 2012 21:18:58 EDT</pubDate>
            <guid>http://ode-is-simple.com/home/2012/09/02/21/18/58/</guid>
        </item>


    </channel>
</rss>
