Article Archives

Autofill City & State from Zip Code with Ziptastic

Most address fields on web forms ask for city, state, and zip code (or city and post code, outside of the US). But as us nerds often lament, city and state are redundant with zip code. Or at least they can be inferred from a correctly entered zip code. That's the kind of thing computers are good at. What we need is a proper API to cough up that information for us on demand.

(more…)

ShopTalk Episode 16

Dave and I were joined by Ian Stewart, a Theme Wrangler at Automattic for WordPress.com (he's probably thinking about WordPress themes right this very minute). We talked about WordPress multisite, training clients in WordPress, database syncing, team productivity, and more.

ShopTalk Episode 15

Dave and I were joined by Happy Cog front enders Jenn Lukas and Allison Wagner and we talk about coding styles, memorization, and the classic "what should we learn next?" This episode was sponsored by the online time tracking tool Harvest.

Fighting the Space Between Inline Block Elements

I've seen this come up a couple of times lately on Twitter and then an interesting Dabblet so I figured it would be an important thing to document.

Here's the deal: a series of inline-block elements formatted like you normally format HTML will have spaces in between them.

In other words:

<nav>
  <a href="#">One</a>
  <a href="#">Two</a>
  <a href="#">Three</a>
</nav>
nav a {
  display: inline-block;
  padding: 5px;
  background: red;
}

Will result in:

Often highly undesirable

We often want the elements to butt up against each other. In the case of navigation, that means it avoids the awkward little unclickable gaps.

This isn't a "bug" (I don't think). It's just the way setting elements on a line works. You want spaces between words that you type to be spaces right? The spaces between these blocks are just like spaces between words. That's not to say the spec couldn't be updated to say that spaces between inline-block elements should be nothing, but I'm fairly certain that is a huge can of worms that is unlikely to ever happen.

Here's some ways to fight the gap and get inline-block elements sitting directly next to each other.

Remove the spaces

The reason you get the spaces is because, well, you have spaces between the elements (a line break and a few tabs counts as a space, just to be clear). Minimized HTML will solve this problem, or one of these tricks:

<ul>
  <li>
   one</li><li>
   two</li><li>
   three</li>
</ul>

or

<ul>
  <li>one</li
  ><li>two</li
  ><li>three</li>
</ul>

or with comments...

<ul>
  <li>one</li><!--
  --><li>two</li><!--
  --><li>three</li>
</ul>

They're all pretty funky, but it does the trick.

Negative margin

You can scoot the elements back into place with negative 4px of margin (may need to be adjusted based on font size of parent). Apparently this is problematic in older IE (6 & 7), but if you don't care about those browsers at least you can keep the code formatting clean.

nav a {
  display: inline-block;
  margin-right: -4px;
}

Skip the closing tag

HTML5 doesn't care anyway. Although you gotta admit, it feels weird.

<ul>
  <li>one
  <li>two
  <li>three
</ul>

Set the font size to zero

A space that has zero font-size is... zero width.

nav {
  font-size: 0;
}
nav a {
  font-size: 16px;
}
Matt Stow reports that the font-size: 0; technique has some problems on Android. Quote: Pre-Jellybean does not remove the space at all, and Jellybean has a bug whereby the last element randomly has a tiny bit of space. See research.
Also note, if you're sizing fonts in ems, this zero font size thing can be an issue, since ems cascade the children would also have zero font size. Rems would be of help here, otherwise any other non-cascading font-size to bump it back up.
Another weirdness! Doug Stewart showed me that if you use @font-face with this technique, the fonts will lose anti-aliasing in Safari 5.0.x. (test case) (screenshot).

Just float them instead

Maybe they don't need to be inline-block at all, maybe they can just be floated one way or another. That allows you to set their width and height and padding and stuff. You just can't center them like you can by text-align: center; the parent of inline-block elements. Well... you kinda can but it's weird.

Just use flexbox instead

If the browser support is acceptable to you and what you need out of inline-block is centering, you could use flexbox. They aren't exactly interchangeable layout models or anything, but you might get what you need out of it.

See

Example on CodePen:

Triangle With Shadow

You probably already know you can make triangles with CSS. But what if you want to put a shadow behind it? Unfortunately the classic border trick doesn't change the shape of the element, it's just a visual trick. Let's look at a couple alternative solutions.

(more…)

Saving the Day with Scoped CSS

Today's post is by Arley McBlain (@ArleyM), a front end developer in Burlington Ontario at Thrillworks.

Over the last couple years HTML5 and CSS3 have rocked our worlds and the way we approach common website issues. Every few days it seems there is some new fangled snippet or approach that is a game changer. Today might just be another one of those days (kind of).

One little known feature of HTML5 is Scoped CSS. It's an attribute for style blocks that may change the way we tackle certain styling challenges in the future.

The implementation for scoping is simple. Let's look at some code on an otherwise unstyled page where all text is the default black:

<div>
  <style scoped>
    h1 { color: FireBrick;   }
    p  { color: SaddleBrown; }
  </style>
  <h1>This is an H1 in a scoped div. Regardless of global styles the text should be "FireBrick".</h1>
  <p>This is a paragraph in a scoped div. The text should be "SaddleBrown".</p>
</div>

<p>This is another paragraph, that will unaffected by the scoped style and remain black.</p>

The style block with the scoped attribute will overwrite the global styles generally found in the head (whether in a style block or linked stylesheet), but only on the sibling/descendent elements inside the same parent. In this example, everything inside the wrapping div is going to get some new heading and paragraph coloring. As w3.org puts it "If the scoped attribute is present, then the user agent must apply the specified style information only to the style element's parent element (if any), and that element's child nodes."

This is amazing! While all other text on the page may be black, within this div we can style freely without worrying about changing the styles of similar elements anywhere else on our site. This can be a very powerful tool.

Why is this cool?

"But Arley," you say, using a conjunction to begin a sentence, "Why not just use a class or ID on that div and style like #foo h1 and #foo p? Isn't this just organized inline styles?" There are a number of occasions I can think of when scoped CSS is a decent option under certain circumstances:

  • It may be desirable to keep the CSS of a particular interactive element together with the HTML. If the element in question is unique on the site (like a complex slider for example), there is no advantage to caching it with global styles.
  • Keeping the CSS with the HTML for organization may have value however.
  • When working with a team it can be a great way to allow for simultaneous development of various areas of the site without worrying about the state of the global CSS - I can see this as a short term solution.
  • If your article is getting aggregated by another site it's possible to customize styles on another website that would otherwise be beyond the reach of your global stylesheet.
  • If you enable tags in the comment section of your site you can give your readers the ability to style their... nevermind this is probably a terrible idea.
  • For use in widgets on third-party sites where the CSS is unknown and the in-widget styles shouldn't affect anywhere else. Although being able to reset the styles within the widget is the other half of that battle.
  • Finally (and most exciting to me), Scoped CSS is ideal for working within Content Management Systems where you have much less flexibility for adding unique markup to common templated areas, or no access to the existing stylesheets.

I would like to talk about the CMS advantages in more detail.

Working with a CMS

When we build a site in a CMS we are building constraints to ensure reusability of elements and templates, as well as maintaining consistency across the site. CMS are the perfect tool to let someone way less nerdy than you create and manage content without fear of breaking any site components. One limitation of a CMS can be the inability to do one-off tweaks for unique areas.

I had this problem working in an enterprise level CMS. Based on original comps and scope of the site we built the CMS to have a consistent uniform look and feel. A need for more flexibility rose a few months after launch: the addition of a second more verbose language, and special campaigns were introducing new challenges for styling.

My first challenge was to make a larger block of text (fun fact: the rule of thumb for designers when designing for bilingual in Canada is to allow for an extra 50% space when the design will need to be in French!). I looked at my pages, and I looked at my stylesheets: even any tiny change I made would mean hours of testing and QA across the entire site to ensure that no other areas were broken as a result. The ramifications were astronomical! Having no time for this I invented the poor-man's Scoped CSS, or "code block" as it became known. Code Block was technically just wrapping divs with IDs around content, and then having an adjacent style block to make the necessary changes (while this sounds simple, it was a bit outside-the-box for this CMS work). Since this CSS would only apply to this page it made no sense to have these styles bloating up the global styles. It was perfect. The style block would not affect any other area of the site. Bilingual and campaign content became easy to develop and test.

Thankfully Scoped CSS will be even cleaner and easier to implement than my McGyvered solution. There will be no need for special IDs, and in fact the ability to have really simple selectors like "p" will keep your CSS looking very clean.

Getting Practical

Have you ever wanted to make one specific post in your stream stand out in some way? Even if your CMS doesn't allow for coding in the editor, you may still have options thanks to Scoped CSS.

WordPress is an example of a CMS that will limit what code you can enter into the content area. Out of the box WordPress strips a lot of markup out of the wysiwyg editor, and this is actually a very very good thing, as it will clean up any stray code a n00b user may accidentally introduce. Giving users access to enter code into a CMS is to give them access to destroy the site! One too many closing div tags will mean a completely borked layout!

With a little work up front you can create a "Code Block" custom field that will allow you to inject scoped CSS directly into that post. If you really want to get fancy you could employ functionality from a plugin like Custom Field Template to make it easy for even the least savvy user to take advantage of this by making style choices with a simple form!

In the WordPress demo below I have created a Twenty Eleven Child Theme (meaning I'm completely relying on the default WordPress template, except for the three pages I've made small adjustments too). The changes I've made are few and simple (I should probably also mention that at the time of writing there is one other tiny problem to consider, but I'll save that until later). To get Scoped CSS working I simply add a little bit of logic to content.php and content-single.php to look for the custom field "scopedcss" and then to pop that into a style block. I simply put this code within the <article> block of the relevant content loops:

<?php 
  $scopedcss = get_post_meta($post->ID, 'scopedcss', false); 

  foreach($scopedcss as $css) {
    echo '<style scoped>'.$css.'</style>';
  } 
?>

Then in my WordPress post I simply added the custom field "scopedcss" and wrote whatever styles I wanted for this post.

Easy cheezy. If you don't see Custom Fields on your post editor screen, click the Screen Options tab at the top of the screen and make sure the checkbox for them is checked.

Note: if you are interested in this art direction on a per-post basis idea, but aren't ready for scoped styles check out this plugin which gives you the meta box for declaring styles, but they won't be scoped you'll need to be as specific as regular CSS.

A word of warning

My own experience with my poor-man's version of this wasn't all sunshine and daisies; there is one major weakness to this approach and to scoped CSS: organization gets very hard - you end up with styles everywhere! Scoped CSS has the ability to save the day, but if it's at all possible you should use ID selectors and linked stylesheets.

This is one of the major reasons we should avoid inline styles, they're messy, they add to page weight something that maybe should be cached, they're a pain to overwrite, they can complicate troubleshooting, and most importantly they're hard to maintain. Like inline styles, Scoped styles do have their place and can be a powerful tool. Use them wisely.

An even bigger warning

Using scoped styles without a proper polyfill is dangerous. In a browser that doesn't support them, the styles you declare will affect the entire page. Imagine you use a scoped style to use an image replacement technique on the h1 title inside an article on your site. Your logo is also an h1, and thus the logo is also replaced in unsupporting browsers. The result is a reverse-cascading style disaster.

Just be warned. Scoped styles are a very useful idea but the days of use using them without a polyfill are very far off.

A jQuery solution

Due to the lack of native browser support, this would be one disappointing demo today if it were not for this great jQuery Polyfill made by Simon Madine. To get my demo working in WordPress I also:

  1. Enqueued jQuery into my WordPress theme.
  2. Added the following code to the footer of the theme (footer.php in the theme folder).
<script src="<?php bloginfo( 'stylesheet_directory' ); ?>/jquery.scoped.js"></script>
<script>
  $.scoped();
</script>

It works!

Wanna play?

Chrome 20 is the only browser at the time of this writing that is supporting scoped styles. Chrome 20 is currently in Canary, which is a pre-beta release that you can run side-by-side with stable Chrome with no problems. To use it, you'll need to enable a flag, which you do by:

  1. Go to the URL chrome://flags/
  2. Search page for "scoped"
  3. Click "Enable"

There's a bunch of other fun stuff in here too.

Chrome moves quickly, so in around 12 weeks from the time of this writing (Mid-July 2012) Chrome 20 should be stable. Whether the feature will be shipped enabled is another matter (we just don't know yet).

Demos

One day soon Scoped CSS will do all of the amazing things you're seeing in these demos natively in the browser without extra JavaScript. Until then you can dream, read about it on the w3.org here, and check these demos:

Scoped styles, while delivering the functionality above, also will prove very powerful in Web Components, a proposal at the W3C for defining reusable widgets in next generation web apps. Exciting stuff.

Refactoring >14,000 lines of CSS

Eugene Fedorenko talks about how Beanstalk refactored the whole app to use SASS. I'm sure a lot of folks are in this situation right now. You want to use SASS, but you have a big app and it's a big move. Short answer: yes.

The only thing I'd suggest they do differently is use Compass. I've also been involved with big SASS rewrites, none of which used Compass, and I highly regret it as: 1) inconsistent mixins across projects blows 2) those mixin files won't be as well maintained as Compass is.

The CSS3 Experience

Soak in a little An Event Apart without leaving your house. Dan Cederholm (you know, the other banjo playing CSS guy) with an hour talk on responsible and enhancement-based CSS3 use.

On :target

The :target pseudo selector in CSS matches when the hash in the URL and the id of an element are the same.

The current hash of the URL is "voters"
<section id="voters"> 
   Content
</section>
:target {
   background: yellow;
}

While that URL is as it is, that section element will have a yellow background, as per our CSS.

When would you use this?

One possibility is when you want style with "states." When the page has a certain hash, it's in that state. It's not quite as versatile as manipulating class names (since there can only be one and it can only be related to one element) but it's similar. Anything you could do changing a class to change state you could do when the element is in :target. For instance: change colors, change position, change images, hide/show things, whatever.

I'd use these rules-of-thumb for when :target is a good choice:

  1. When a "state" is needed
  2. When the jump-down behavior is acceptable
  3. When it's acceptable to affect the browser history

We'll touch on all these things in this article.

How do you get hashes in URLs?

The most common way is by a user clicking a link which includes a hash. Could be an internal (same-page) link or a fully qualified URL that happens to end with a hash and value. Examples:

<a href="#voters">Go To There</a>

<a href="http://example.com/#specific-part">Go To There</a>

Jumping Behavior

Regardless if it's a same-page link or not, the browser behavior is the scroll the page until that element is at the top of the page. Or, as far as it can if it can't scroll that far. This is rather important to know, because it means exploiting this "stated" behavior is a bit tricky/limited.

For instance, I once tried a variety of techniques to replicate functional CSS tabs, but ultimately decided using the checkbox hack was a better idea because it avoids the page-jumping issues. Ian Hansson at CSS Science has some examples of tabs as well. His third example uses :target, and absolutely positioned elements hidden above the top of the page to prevent page jumping behavior. It's clever, but not really a solution, because that would mean the page would jump upwards should the tabs be down further on a page. The anchors are actually fixed position, meaning they scroll with the page and don't exhibit top-jumping behavior. Extra clever!

A perfect use: highlighting sections

Here's a problem: When a hash-link sends you flying down the page to the relevant section, it will try and make that section snug against the top of the browser window.

But what if there isn't enough room to scroll beneath that section? That section will be visible, but it won't be snug against the top, which can be weird and confusing.

It can be disorienting.

I'm not just making that up. From personal experience, page-jumping links that don't take me to somewhere where was I was linking to is exactly on the top, I get all out of sorts. I find it happens all to often on things like FAQ pages where the linked-to sections often aren't very tall.

So let's solve that!

One historical method was called the Yellow Fade Technique. It was employed by 37 signals in situations where new content is added to the page, and they were trying to draw the user's attention to it. Jonathan Snook ported that idea to CSS and combined it with :target.

Instead of yellow fade, we'll indicate which section the link we just clicked was referring to by nudging it over to the right and flashing a red border. Instead of making you think, here you go:

The structure is a bit of navigation that links to sections by ID:

<nav>
  <a href="#one">1</a>
  <a href="#two">2</a>
  <a href="#three">3</a>
</nav>

<section>
  <div id="one"><h2>One</h2>Pellentesque habitant morbi ...</div>
  <div id="two"><h2>Two</h2>Pellentesque habitant morbi ...</div>
  <div id="three"><h2>Three</h2>Pellentesque habitant morbi ...</div>
</section>​

When the sections become in :target, the scoot over to the right a bit via translateX transform (prevents any weird text wrapping or anything we might get with padding) and a red border flashes on via keyframe animation.

:target {
  animation: highlight 1s ease;  
  transform: translateX(20px);     
}
@keyframes highlight {
  0% { border-left-color: red; }
  100% { border-left-color: white; }
}
section > div {
  border-left: 40px solid white;
  padding: 10px;
  transition: all 0.5s ease;     
  padding-right: 50px;
  margin-left: -20px;    
}

That's all there is too it really. I'd chalk this up under progressive enhancement, if you're worried about browser support. As in, it's just a nice touch, not vital.

View Demo

Fighting the Jump!

Let's say you like the idea of using :target for states but dislike the page jumping behavior, you can change the hash link in a URL without a page jump.

Using jQuery, you could target all hash-links, prevent their default behavior, and use pushState (or replaceState, I suppose) to change the URL (which won't move the page).

$("a[href^=#]").on("click", function(e) {
  e.preventDefault();
  history.pushState({}, "", this.href);
});

You could interchangeably use replaceState there too, which would change the URL without adding an entry to the browser history. Sometimes you might want that, sometimes you might not. At least you have a choice here, which you don't with the default behavior of clicking a hash link, which always adds.

But there is bad news

When the URL changes to a new hash, you'd think the current target would change and new CSS would take effect. It doesn't (tested current WebKit and Firefox at time of this writing). It's a bug.

Theoretically, you could measure and save the current scroll position of the page, let the link move it naturally, then set it back to where it was. But that just sounds so awful I couldn't even bring myself to make a test page for it.

More

On Responsive Images

There is a real need for serving media that is appropriate for the device and circumstance, since we know so little about any particular web request. I recently posted a blog post with so many images on it the page weighed in at 2.29 MB. I should have posted a warning when I tweeted it: "Don't click this if on a 3G network, it probably take forever, just check it out when you get home."

Ideally, all those images I served up could have had a lower-res version of themselves that display on browsers with smaller browser window sizes and/or slower connection speeds. Even in cutting edge browsers, there is no native way to do this yet. So it's a good time to start talking about how we want that to work as web builders. Perhaps we can influence how the spec shapes up.

Let's limit this conversation to inline raster images. As in, the things today served as <img>. As I see it there are three paths we can go.

  1. Create new element that exists just to serve this problem.
  2. Create a new image format designed to solve this problem.
  3. Do nothing, fix our problems with other technologies.

Each of them has advantages and disadvantages. Let's look at each.

Create New Element

The most likely candiate is <picture> as being discussed here in the W3C community. Scott Jehl has a JavaScript polyfill that mimics what it's functionality would be. The syntax would be:

<picture alt="description of image">

  <!-- low-res, default -->
  <source src="small.jpg">

  <!-- med-res -->
  <source src="medium.jpg" media="(min-width: 400px)">

  <!-- high-res -->
  <source src="large.jpg" media="(min-width: 800px)">

  <!-- Fallback content -->
  <img src="small.jpg" alt="description of image">

</picture>

Advantages

  • Mimics other media syntax like <video> and <audio>, which makes sense.
  • The fallback makes it backwards-compatible with browsers that don't support it, which is extremely important. We can't have images that just don't work in older browsers.
  • Gives us web authors the control to show exactly what we want under situations we specify.

Disadvantages

  • It's a whole lot more complicated than <img>. Harder to teach, harder to learn, more code to write. Easy to screw up.
  • Muddies the water of CSS and HTML a bit, by bringing the media query syntax into HTML.
  • Similar issues to why inline styles are bad. Makes future updates more difficult. Not a reusable abstraction.

New Image Format

The impetus behind this blog post came from conversations I with Christopher Schmitt and a blog post he wrote. Christopher is of the opinion that a new image format is the ideal solution.

This new image format would essentially have multiple versions of itself inside of it.

Which image is delivered by a program like a web browser is a determination that can be made by a virtual handshake between the browser and the web server.

So perhaps the file is 800k all together, but within it is four different versions of itself: 500k, 200k, 50k, 10k. Through some kind of standardized set of rules, one of those four images would come across and be displayed by the browser.

Seem like a fantasy? There is already an image format like this called FlashPix, which handles even more drastic versioning. Think new image formats are impossible to implement? WebP is gaining support at a decent pace.

Ultimately the syntax would remain just as it is now:

<img src="unicorn.rpng" alt="fancy unicorn">

I just made up that file extension, but "responsive PNG" would be fine with me.

Christopher likes this approach because

it allows the continued use of the IMG element which is ingrained into the bones, the very marrow, of the Web.

I like that thinking. No need to turn our backs on an element which has worked so well for so long. But of course we wouldn't. There is no need to replace <img>, only build upon it and offer alternatives.

Advantages

  • Keeps the syntax simple. Works the same way it always has.
  • Keeps authoring simple as well. One file, not multiple. Adoption would probably be quicker and more people would actually do it (less people would make 4 versions of every image and hand craft queries to serve them).

Disadvantages

  • Possible loss of control. In order to keep things simple, the image format would do the logic of what exactly gets served. Will it always make the right call? What does it factor in? Parent container width? Network connection speed? Pixel density? A combo?
  • Not backwards-compatible. What happens in browsers that don't support the new format?

Other Technologies

We could certainly lean on JavaScript to help us here. It could help us with the new image format, for one. We would use regular old png's and jpg's in our <img> and hot-swap the src with the new format for a while until the new format has ubiquitous support. A little heavy-handed perhaps, but workable.

And if it can do that, maybe we should just let it solve the entire problem. JavaScript is able to do all the "tests" we likely need it to do (e.g. window size testing, network speed testing), and it could be in charge of swapping our the src of our images with more appropriate ones. The foresight.js by Adam Bradley library is doing that already. Perhaps that is what JavaScript is for and we don't need to interfere.

Think the client-side nature of JavaScript isn't ideal? There are a couple of solutions that bring things server-side.

Adaptive Images by Matt Wilcox is a ridiculously clever solution that using a tiny sprinkle of JS just to measure the current screen size and set a cookie, and then all requests for images are routed through some PHP which determines which version of an image to server, appropriate to screen size.

Sencha.io Src is another solution that is completely JavaScript-free. It does UA sniffing to determine the device and makes the call on what size image to serve up based on that. You simply prefix the src of the image with Sencha's service URL:

<img src='//src.sencha.io/http://mywebsite.com/images/unicorn-hires.jpg' alt="unicorn" />

That's the simplest possible usage, it can get a lot fancier than that. It's a third-party Beta service though, so be aware of the inherit concerns of that (e.g. they go down, your images don't load). I imagine it will ultimately be a paid service.

Advantages

  • We don't rock the boat of standards.
  • No waiting for browsers to catch up on supporting anything new.

Disadvantages

  • Is this just ignoring the problem? Aren't standards supposed to help with real problems?
  • The code needed to do this right is heavy-handed.

Where I Land

Relying on older technology and hacks isn't enough for me, but I can't decide whether I prefer a new format or new syntax. Maybe both? Maybe a hybrid? I feel like the syntax is more likely because there is more discussion about that. A format is a much taller order and I've heard no whispers of active development on anything like that.

It'll be a fun day when I can update this blog post with "official" best practices!

Related

Foresight.js

Speaking of bandwidth media queries, this project by Adam D. Bradley looks promising:

Foresight.js gives webpages the ability to tell if the user's device is capable of viewing high-resolution images (such as the 3rd generation iPad) before the image is requested from the server. Additionally, it judges if the user's device currently has a fast enough network connection for high-resolution images. Depending on device display and network connectivity, foresight.js will request the appropriate image for the webpage.

ShopTalk Episode 12

This week Dave and I are joined by Dave's co-workers and amigo's Trent Walton and Reagan Ray. We talk about cutting edge front end stuff, client services, topics for a graduate thesis, and more. Brought to you by LessMoney and Front End Design Conference, two web conferences running back to back in Florida this July.

The JavaScript “Ah ha!” Moment

A number of years ago we talked about The CSS "Ah ha!" Moment. That is, the moment in which you learned something about CSS that made it click for you and had the feeling of understanding wash over you. For CSS, mine was realizing that every element on the page was a rectangular box that lay themselves out in a particular manner and that I could affect the size, position and contents of those boxes.

Let's do it again, only for JavaScript! If you feel like you have a decent understanding of JavaScript, what was your "Ah ha!" moment? Or are you still waiting for it?

For me, I had never written a line of JavaScript in my life but I picked up the book Learning jQuery and started reading it on a flight. I had the moment when I realized jQuery was essentially a "find something, do something" library. I already knew CSS, and jQuery used CSS selectors for the "find something" part. "Do something" in jQuery can be as simple as "click", "hide", "show", "slideToggle", etc. Even I can do that, I thought, and I rushed to my hotel room and started playing.

Minimum Paragraph Widths in Fluid Layouts

The following is a guest post by Gustav Andersson who has come up with a clever little technique for a text flow problem. I've struggled with this myself in the past, so I'm happy to add this technique to the ol' toolbox. Not mention, yet another one of these.
An example where a floating image leaves only enough space for a very narrow column of text which looks ugly and is broken up be a long word.

An example where a floating image leaves a few orphaned words.

A floating image takes away horizontal space from the text that flows around it. In fixed width layouts, you can check that the space left for the text is enough to create a decent looking column, safe in the knowledge that everyone else will see the same thing.

In a fluid layout, however, you have no such guarantee. If a user views your site on a smaller device, the horizontal space left for the text may only fit a word or two per line. Such a narrow column of text doesn't just look ugly; it is also brittle. A sentence containing a long word will split when the long word moves down below the floating image, leaving behind it dead empty space mid-sentence.

The elusive minimum paragraph width

To solve the problem of too narrow paragraphs, we need a way to implement a minimum paragraph width. If the space left by the floating image is below this width, then the whole paragraph moves down underneath the image.

Same example as above, but with a red border around the paragraph, showing that it extends behind the  image.

The red border is the boundary of the paragraph element.

Intuitively, the following CSS seems to fit the bill:

p {
  min-width: 10em;
  /* For demonstration */
  border: 1px solid red;
}

However, this has no effect. The image floats above the paragraph, and thus doesn't reduce the paragraph's 'official' width. Meanwhile, the text within the paragraph dutifully moves aside to make room for the floating image, and so the problem remains.

The media query solution for known image widths

An example showing how the media query has disabled the floating of the image, and the entire paragraph is underneath.

The Media Query solution works, but requires fixed-width images.

If your images (or other floating content) share a fixed and predefined width, then you can use CSS3 media queries to disable the floating at screen sizes that are too narrow to fit both an image and a text column side by side.

This solution will of course only work on browsers that support CSS media queries. For other browsers, the solution degrades to the original problem.

@media screen and (max-width: 400px) {
  img {
    float: none;
  }
}

General case solution using pseudo element

The media query solution doesn't work when the floating elements have arbitrary widths, nor is it very elegant.

An example of the pseudo-element rule in place, showing a thin green border surrounding the pseudo element. Both the element and the paragraph are below the image.

This example shows the pseudo-element rule in place, showing a thin green border surrounding the pseudo element. Both the element and the paragraph are below the image.

A better solution is to give every paragraph an invisible CSS pseudo-element with the desired minimum paragraph width. If there isn't enough space to fit this pseudo-element, then it will be pushed down underneath the image, taking the paragraph with it.

This solution is supported by most browsers. On older browsers, the solution degrades gracefully to the original problem.

p:before {
  content: "";
  width: 10em;
  display: block;
  overflow: hidden;
  /* For Demonstration */
  border: 1px solid green;
}

The pseudo element's green border is there for demonstration purpose only. It is not required for the solution and you should remove it in your code. The pseudo element will then take no vertical space at all.

Demo & Download

View Demo   Download Files

 

About the Author

Gustav Andersson is the author behind The Modern Nomad, a site exploring nomadic lifestyles which frees people to live and work anywhere, anytime. He is a tango-dancing, steer-wrestling, grammar-loving burner who wants to inspire you to consider a life without an address.


ShopTalk Episode 11

This week Dave and I were joined by Jina Bolton. We talked all kinds of shop, touching on SASS usage and the new upcoming website, semantics, learning, workflow, and more. This weeks show brought to you by LessMoney and Hover.

Content Folding

Less than a year ago, Trent Walton published Content Choreography in which he lamented at some of the difficulties and limitations of responsive layouts.

At times, it seems as though all of the site architecture & planning goes out the window as content reflows.

You have to admit, an awful lot of responsive designs end up being:

  1. Squeeze everything into one column
  2. Push the sidebar(s) to the bottom

*cough* this site does that *cough*

Trent mentioned it may be a more appropriate approach to "interdigitate" content.

Interdigitate

That is, to fold bits of content together into that single column in a more thoughtful or useful manner.

A Practical Example: Ad Folding

Consider a layout at a large browser window size. Two columns. Articles in a wide column on the left, advertisements in a narrow column on the right.

At narrower browser window sizes we've decided to drop down to a single column. This layout is probably done with floats, the most common layout method still today. Unfortunately that probably means setting both columns to 100% wide and letting their source-order determine which is on top. Meaning: push all the ads to the bottom. Probably not ideal. It likely would be nicer to fold the ads into the content.

But how?

There's probably a number of ways to do this. With JavaScript, you could measure the window width and shuffle things around in the DOM. That seems heavy to me, but the browser support would be good. I'd rather lean on CSS for this kind of thing. That's what CSS is (supposed to be) for. The grid layout may hold some possibilities for us, but for this tutorial, let's use the hot-off-the-presses CSS Regions, a contribution by Adobe.

Fair warning: This stuff is super new and subject to change. When I wrote this in March 2012, this demo worked in Chrome. Now in January 2013, it doesn't anymore. Chrome 15-18 had partial support and then it was pulled in 19, although Chrome still reports support of the property.

HTML

<section class="main-content">

  <article> ... </article>

  <div class="ad-region-1">
    <!-- empty, ads flow into here as needed -->
  </div>

  <article> ... </article>

  <div class="ad-region-2">
    <!-- empty, ads flow into here as needed -->
  </div>

  <article> ... </article>

  <div class="ad-region-3">
    <!-- empty, ads flow into here as needed -->
  </div>

</section>

<aside>
   <!-- Fallback content in this flow region, probably clone #ad-source -->
</aside>

<!-- Source of flowing content, essentially hidden as an element -->
<div id="ad-source">
  <a href="#"><img src="ads/1.jpg"></a>
  <a href="#"><img src="ads/2.jpg"></a>
  <a href="#"><img src="ads/3.jpg"></a>
  <a href="#"><img src="ads/4.png"></a>
</div>

Notice the "content" (our ads) are tucked into a <div> at the bottom of the page. Once we set up the CSS regions, the element will essentially be hidden and the content inside it will flow into the regions we tell it to.

CSS

We kick it off by telling our content-holding div#ad-source to flow it's content into a "named flow":

#ad-source {
  -webkit-flow-into: ads;
  -ms-flow-into: ads;
}

I'm only using two vendor prefixes here because that's the only support for now. I'd recommend not using the unprefixed version as this stuff could change in final implementation.

'ads' is an arbitrary name that we just made up. It could be anything, like naming a CSS animation.

Now we set up regions in which for that content to flow. First, into the aside, then into the interdigitated divs between the articles.

aside, [class^='ad-region'] {
  -webkit-flow-from: ads;
  -ms-flow-from: ads;
}

In our case, at wide browser window widths, the aside is large enough to hold them all. At narrower widths, through media queries, we hide the aside, forcing the content to flow into the divs.

[class^='ad-region'] {
  display: none;
  height: 155px;
  width: 100%; /* Weird that this is required */
}

@media (max-width: 800px) {
  [class^='ad-region'] {
    display: block;
  }
  [class^='ad-region']:last-child {
    height: 300px; /* I wish height auto worked */
  }
  aside {
    display: none;
  }
}

Semantics

Soooo yeah, we have some empty elements we're tossing around here. Not super semantic. I'm not sure what this does for accessibility either. I do know that the DOM doesn't change around. All the content, despite where it "flows", is still within the "source" (the element with the flow-into property).

Here's the thing though: regions are layout style agnostic. We're still using floats for layout in this example, but the layout style you use doen't really matter. Regions paired up with the CSS Grids might be much more powerful and more semantic (I just don't know).

Browser Support

CSS Regions is shipping in Chrome 16 through 20, then put under the flag "Enable CSS Regions" in 21-22, and now under the flag "Enable experimental WebKit features" in Chrome 23+. It works in Safari 5.2 (available as dev, or WebKit Nightly). Supposedly it works in IE 10, but I couldn't get it to.

Demo & Download

For your enjoyment:

View Demo   Download Files

Please note the browser support above, it's very limited.

Also note that at some fairly wide browser window widths, the ads in the aside get cut off. I'm leaving it that way to illustrate how regions don't expand in height naturally, you need to account for that yourself.

Update: This demo worked, then was broken, and now works again. I made it work through Adobe's CSS Regions Polyfill. This will need to be revisited again when the spec and browser support settles down.

Browser Detection

This HTML and CSS as is would be pretty sucky in a browser that didn't support CSS regions. There would be this chunk of ads at the bottom of the page randomly. Instead I chucked in a bit of JavaScript (based on this) to test for it and apply classes to the html element reflecting support.

// Generic Testing Function
var supports = (function() {  
   var div     = document.createElement('div'),  
       vendors = 'Khtml Ms O Moz Webkit'.split(' '),  
       len     = vendors.length;  
  
   return function(prop) {  
      if (prop in div.style) return true;  
  
      prop = prop.replace(/^[a-z]/, function(val) {  
         return val.toUpperCase();  
      });  
  
      while (len--) {  
         if (vendors[len] + prop in div.style) {   
            return true;  
         }  
      }  
      return false;  
   };  
})();  
  
// Test
if ( supports('flowInto') ) { 
   $("html").addClass('cssregions');  
} else {
   $("html").addClass('no-cssregions'); 
}

That was we can do stuff like this to make sure the fallback is OK:

#ad-source {
  display: none;
}
.cssregions #ad-source {
  display: block;
  -webkit-flow-into: ads;
  -ms-flow-into: ads;
}

And also, copy the contents of the div#ad-source into the aside, so at least the ads appear there at the widest browser window widths.

This should work, but it is reporting false positives in Chrome since Chrome removed support for it in Chrome 23. You can turn on support though...
  1. Using the browser bar navigate to chrome://flags
  2. If you're running Chrome 21 or Chrome 22, find the "Enable CSS Regions" flag and enable it
  3. If you're running Chrome 23 or newer, find the "Enable experimental WebKit features" flag and enable it.
  4. Restart your browser by clicking the "Relaunch Now" button on the lower left corner.

If you wanted to add this test to Modernizr you'd do:

Modernizr.addTest('regions', Modernizr.testAllProps('flow-into'));

Hopefully they'll add that as an option in future versions.

Things I Wish Were Better

  • I wish you could style content based on what container element it happens to flow into. That might be problematic as a different style in a different container might cause a reflow which pushes it back out of that container causing infinite looping sadness, but maybe there is some kind of solution for that.
  • I wish block level elements would remain block level even with the flow-from property. It's weird you have to set them to width: 100%;
  • I wish height: auto; worked on the region with the last bit of flowed content. I understand most flow regions can't do that because then they would just expand to fit all the content and not continue the flow, but the final region should be able to know what it has left and expand naturally.
  • I wish you could flow-from and flow-into the same element. That way one semantic element could be the source and only if it shrinks or goes away do the other regions get filled.

New Poll: Your Preferred CSS Preprocessor Syntax

There is a new poll up in the sidebar of the site which asks:

What is your preferred CSS preprocessor syntax?

The popular ones are in there, an "other" option in case you use something else (please share in comments), as well as answers for "never tried," "don't like any of 'em," and "no preference."

I realize that not everyone has tried all of them so the end results may be skewed toward general popularity rather than a honest syntax comparison, but that's OK it will still be interesting.

About HTML semantics and front-end architecture

Good read from Nicolas Gallagher. Among the gems:

Class names cannot be “unsemantic”. Whatever names are being used: they have meaning, they have purpose.

When Twitter Bootstrap first came out, I rewrote the compiled CSS to better reflect how I would author it by hand and to compare the file sizes. After minifying both files, the hand-crafted CSS was about 10% smaller than the pre-processor output. But when both files were also gzipped, the pre-processor output was about 5% smaller than the hand-crafted CSS.

Again: the smaller CSS file came out bigger when gzipped.

Shop Talk Episode 10

Dave and I talk shop with Doug Neiner, whom I consider one of the smartest people I know. Doug is on the jQuery team and works for a company based around jQuery, so the topic of JavaScript comes up a lot. But we also talk some CSS, APIs, and a variety of other stuff while answering listener questions. This episode brought to you by Hover (the best place to buy domains) and LessMoney (a conference to make your business better).

Picturefill

Polyfill hero Scott Jehl has a new one for the theoretical <picture> element. The idea behind this new element is to solve the very real need to serve images of the appropriate size based on the browser window size. I'm all for it, but what happens if this exact syntax isn't the one that gets standardized?

How to Create Stunning Effects With 165 Media Queries or Less!

Today's post is by Arley McBlain (@ArleyM), a front end developer in Burlington Ontario, at Thrillworks. Arley recently redesigned his site and it has some pretty neat CSS effects on it. I asked him if he'd like to share some of them and this article is his kind oblige.

Responsive Web Design is the big buzz topic of the industry right now, and with little wonder; serving your site to be visually optimized for different devices and contexts is a brilliant idea. Your site exists to be seen, so why leave anyone out?

Weird RWD Side Effect

One bizarre trend emerging in this new RWD era is desktop-browsing web designers resizing their browsers to watch the break-points change the layout. The average user never sits at their desk repetitively shrinking and expanding the browser window like a mad scientist. Yup, we're all strange. The personal website of someone like you and I likely has this kind of strange browser-resizing user as the target demographic, and most frequent visitor, so why not play to that?

Responsive Text is a relatively new sub-topic that is only just beginning to be explored (Frankie Roberto recently made this post on responsive text). Today I want to talk about changing a headline to create a striking effect using media queries. This effect is created by having many media queries that trigger in short succession. Using this approach there is no limit to the jaw dropping visuals your site can produce.

It Starts With a Personal Project

I recently refreshed my personal site ArleyM.com. There are some "old-school" responsive effects on my front page (loosely based on this responsive framework Chris Coyier tweeted about a few months back) in that the picture of me slides under my first name, but on top of my last name. This is done by having a percentage based position on the image. I figured I would be remiss to not have some other eye catching responsive feature on the site, so I dug back into my experiments. A personal project is the perfect place to do something crazy that you'll otherwise never get the chance to do on client work. I decided to add 'responsive adjectives' shown at the bottom of this image:

"Be Shocking." vs. "Be Weird." - Changing text using an army of media queries.

I call the use of countless media queries "Lark Queries" (The word 'lark' often refers to something done for fun, or playfully, but I also like to think of it as taking a simple concept to an extreme level). Quite simply the user will see different words based on the width of their browser. Many users will never realize that there is anything unusual going on - but when someone checks if the site is responsive, they may be surprised at this uncommon effect.

Creating the effect

There are a couple ways to achieve this. I chose to use CSS for everything. I made a media query breakpoint every 10px from 300px to 1920px, and then a
couple extra break points above that for dual-monitor, and 27" cinema display users. I then used the CSS Content attribute to place the text in the h2. The content attribute isn't supported by IE7, but for my site all versions of IE represent less than 4% of all traffic.

The HTML

Here we have a simple h2 with a parent div to make the selector unique (this isn't something I want on every h2 on my site!).

<div class="row">
  <h2>Be <span></span></h2>
</div>

The empty span is there to allow the CSS to render the content after. If I had to deal with older versions of IE I would actually put a static default word within the span, and only display it as needed using conditional wrappers (as demonstrated in How to Create an IE only stylesheet).

The CSS

@media (max-width: 980px) {
  .row h2 span:after { content: 'Unusual.' }
}

Here's just one line of the many media queries I made (165 in total!). All that changes is the max-width value, and the content value. The media queries were the easy part, thinking of a different word and arranging in order of shortest to longest was really time consuming (Thanks thesaurus.com)!

The result is striking - the text rapidly changes with the shrinking browser. Fun! The Content element automagically adds the new word after the span with every media query breakpoint. It just feels nice to use this handy content attribute for something other than ul bullet points for once!

View Demo   Download Files

It was fun to see the differences this rarely used property has in each browser! For example, only Opera will let you select the content text, or copy / paste it.

Getting into Semantics

They say it's a best practice to keep your content in HTML, your styles in CSS, and your behaviour in JavaScript. So am I breaking some rules by literally using a content property? I don't think so.

You could put all of the content values in HTML and use the media queries to toggle display:none/inline, but if a screen reader or Google ever had the chance to read all of that, the result might not be what you're after! JavaScript could do this job just fine (and with less code if you put all of the content values into an array), but my CSS demo will work even if JS is turned off. I personally find the content property charming as well, not sure why.

I would also argue that this effect does fall more into the style category than real content. It's a bit of a gimmick, so I'm not too worried about semantics for my own project.

So What Next?

Obviously a tiny part of me would die inside every time this code with exact text was used verbatim, so how else could this massive media query technique be used? That's where you come in! I would love to hear some ideas in the comments. Don't let the daunting realization of how much time these would take to do hamper your imagination.

Here are a handful of other ideas I've thought of:

  • Changing colors: The media queries could change color / background-color to shift through the color spectrum, saturation scale, or go through the tints / tones of a color (0to255.com is a good place to get some hex for this). This could happen for a small element like the color of a title, or more extreme: like a full site color scheme change.
  • Faux-Animate an image:* If you could use a high quality DSLR that can rapidly take shots you could create a stunning faux animation effect (image preloading would become key, this RWD effect comes with a high bandwidth cost). There is so much potential here!
  • Changing Focus: It would be amazing if changing the browser size shifted the depth-of-field focus of the images on the page!
  • Go Crazy: With a little JavaScript it should be easy to tell that a browser is resizing, and no longer at the size it was on load. You can mess with those pesky browser resizing designers by having the site go insane on resize! I'm thinking Katamari Ball crazy.
  • User hints: This could actually be used in a practical way to give users cues that they should rotate their phone into landscape. But 'practical' sounds kinda boring next to the other ideas.

As I draw to a conclusion and reflect on this list of things that can be done without being shy of media queries I can't help but feel like we're just looking at the tip of an iceberg. A crazy resizing iceberg.

I'm going to go practice resizing my browser in anticipation!

Update

Sass Loop implementation by Hugo.

ShopTalk Episode 9

Dave and I were joined by Ethan Marcotte and I bet you can guess what we talked about. That's right ShopTalkers, it's a full episode of responsive web design goodness, from the basics to the newer challenges developers are facing in our brave new responsive world. Brought to you by Hover and LessMoney.

LessMoney

I love Allan and Steve from LessEverything. I was just recently at my third trip to LessConf, which is a really fun web startup oriented conference. The fellas are at it again already, throwing a new conference called LessMoney. From them:

LessMoney Conference is a 2-day event where 50 people come together to learn & discuss how to become a more profitable, less stressful business owner or freelancer.

Learn from these two guys who have lots of experience with their own small business, as well as other speakers in the same game. It's June 6th & 7th in my old stomping grounds, the lovely Tampa, Florida.

The Non-Breaking Space Show

Remember those three fellas from the last ShopTalk Show? Those guys are from the new(ish) podcast The Non-Breaking Space Show. Dave and I join them in this episode to talk about preprocessors, Git, and other stuff.

SXSW 2012

I'm headed down to Austin in a few days here for my 2nd SXSW. Hope to see some of you folks there. I'm trying not too have much of a plan, but here's a few things I'm doing:

There is a SurveyMonkey party and a crew of us from Wufoo / SurveyMonkey will be there hanging out. Free food and drinks. RSVP here and come.

My ShopTalk Show cohort Dave Rupert lives down there. We have no official plans but if we're hanging out somewhere for a bit maybe we'll do an impromptu meetup. Follow @shoptalkshow on Twitter for news of that.

The whole BarCamp Tour crew will be there. There is a BarCamp tour panel called 5 Brands Travel the US Inspiring Entrepreneurship where last year's tour will be discussed and how that all went down. Possibly an impromptu Barcamp meetup as well, so follow @barcamptour for that.

I'm am actually going to the conference as well. I've marked a few things I'd be interested in going to see on Lanyrd. I probably won't make all of them but definitely some of them. I mostly marked front endish ones, but I'll very likely go to others that have nothing to do with that. The wide variety of talks is definitely a strength of SXSW that is smart to take advantage of.

CSS Off Results

This year's CSS Off results are in. The Unmatched Style folks have listed out the top 25 entries and will be emailing everyone their results shortly. Congrats to all who entered. It was quite a load on all the judges to get it done and done fairly, but also fun and darn interesting. Three quick things that stood out to me while judging:

  • I think I only saw one or two that didn't use jQuery
  • Maybe only a handful that used Normalize instead of a Reset
  • There are apparently crapload of really good front end developers, why are they so hard to hire?

Designing for Decoder Glasses, Print and Web

The following is a guest post by Michael Buchmiller, the Creative Manager at BlueHornet. Michael used a jQuery plugin I created for a pretty neat application, so I asked him if he'd be interested in sharing the technique as a blog post. This is that story.

The Idea

My company, BlueHornet, was scheduled to give a keynote presentation at the Email Evolution Conference entitled “Email Marketing Trends for 2012,” which would cover a number of the surprising results yielded from a study we had recently conducted. The theme we’d been running with for the rest of our collateral at the conference was “Focus,” and we needed to come up with a leave-behind to give attendees in the audience of the keynote. We had done an infographic a few months back that was received well, and with the new study in hand, another infographic seemed appropriate. But we still needed to tie it in to our theme. The first idea was retro decoder glasses that help bring in to focus parts of the poster. Granted, decoder glasses are usually the first idea, but finally there was a situation where it fit thematically with what we were doing.

For those who don’t know, decoder glasses are much like the old 3D glasses with paper frames and one red gel lens and one blue one. But on decoder glasses, both lenses are the same color, and wearing them enables you to see secret messages… kind of like in the Rowdy Roddy Piper movie, They Live.

With everyone on board, we were off and running. Step One… order the glasses. There were two in stock to choose from… either red or blue lenses. We’re BlueHornet, so this was an easy decision.

The Waiting is the Hardest Part

There wasn’t enough time to finish the project before the conference unless I started immediately. Unfortunately, the decoder glasses wouldn’t arrive for a few more days, and having never designed something with them before, I didn’t know exactly what colors I needed to use or what patterns would work best. So for now I’d start on the design. I thought that advertising illustrations from the 1940s and 50s seemed to be a good match for decoder glasses, so that’s the path I headed down.

I also knew that I didn’t like the patterns used in other decodable designs to hide the messages… most of them are just kind of scribbled messes. I wanted the poster to look sharp even if you weren’t wearing glasses, and for whatever pattern we used to make sense in the design. For this, I wanted to use halftone patterns, which would tie everything together nicely.

I dove in, tackling the big pieces for the poster design first… just working in black and white to box in the shapes and spaces, figuring out how much room for copy we’d have, and how the stats would fit in. I added a quick, temporary color treatment to help the rest of the team see what I was going for, and everyone was still on board.

Decoder Glasses, How Do They Work?

Tuesday morning, the glasses arrive. The excitement of finally having them in hand and the novelty of wearing them around the office quickly wore off as the realization set in… I had to figure out how to design something using them. Being a fan of decoder glasses since childhood, I had a basic understanding of how they worked. Initially anything blue in the design will be dominant and in the foreground, and anything in yellow will be hard to read. But it all changes when you put on the glasses… the yellow design elements become a really dark green when your eyes combine the yellow with the blue from the lenses. These now blackish-green elements are then darker than the blue parts, which makes them pop to the foreground and easy to pick out. Everything that was blue stays blue, or kind of gets washed out. But what shades of blue and yellow work best? What kind of blue patterns will work on top of yellow to make them easy to read with glasses, but nearly impossible to read without them? To solve this, I would need to do some tests.

Testing, Testing… 1, 2, 3.

I knew we wouldn’t be screen printing the posters, so Pantone colors were out. This would all be CMYK, and dealing with color shifts from monitor to printer could be problematic if everything hinges on getting the right shades of blue and yellow for the effect to work. Luckily, I had the luxury of knowing that the final 11” x 17” posters would be printed in-house using our Xerox Phaser 7400 color laser printer, so I could do all of the test runs on the same equipment. I put together a bunch of shades of blue in various patterns on top of text in all sorts of shades of yellow and printed it up. When you look at them with the glasses on, you quickly figure out which ones are working and which are not.

The shade of yellow that worked best on our printer for the parts of the design I wanted hidden was CMYK 0/0/100%/0. Various shades of blue were effective, but I primarily used CMYK 100%/75%/0%/0% which is a rich, royal blue… not too far off from the color of the blue in the lenses. Having a limited color palette also ties in visually with the era of both the decoder glasses and the style of illustration, so I kept it simple.

Through this process, I figured out that using the Adobe Photoshop Layer Multiply attribute… where the yellow overlapped on to the blue pattern to make a green… worked great. Without the glasses, you’d see green where the two colors intersect making it more difficult to read, but with the glasses, both the green and yellow both turned out to be the same color… a greenish black.

In combination with Layer Multiply, I developed a few approaches. One was writing a bunch of words in blue on top of the yellow design. Without the glasses, your eyes focus on the words in blue they can read and it’s very difficult to stop seeing those words and look behind them at the faint yellow message. Another technique was to use a distracting halftone pattern in blue on top of the yellow design. It took some trial and error to figure out the right amount of white to have in the pattern… too much or too little and the yellow piece was easily read without the glasses. And the last technique I found to work was actually putting the vivid yellow message on top of a de-saturated yellow background (like CMYK 0/0/50%/0). This is probably the easiest to figure out without the glasses on, but having it as an option opened up some design treatments.

The key to it all was finding the right balance between being hard to read without the glasses, but still easy to read with the glasses. If it was still hard to read even with the glasses on, that might be great in a situation where secrecy is the top priority, but for our purposes, I didn’t want anyone to be frustrated.

Sometimes the hidden design would be quite legible on my screen, but not at all when I printed it, so you can’t trust your monitor… you really need to print it out and see how it looks with the glasses.

One thing I didn’t anticipate was that knowing the hidden content beforehand helped me decipher it, or at least helped convince me I could read it, when it was by all other account unreadable to the naked eye. To combat this, I leaned on objective co-workers to chime in and let me know what they could or couldn’t read.

Finishing Up the Poster(s)

Now that I knew which colors and treatments worked best, I applied them to the in progress design. It took some trial and error to get everything just right, but it went relatively smoothly. Since we were printing these ourselves and had more statistics than room on the poster, we opted to make a few of the sections variable, so in the end, there were actually three possible iterations. We printed them, boxed them up, and shipped them to the conference. Just as I thought I was done, I was asked a very troubling question…

So now can we put this on our website?

Translation from Print to Web

The coolest part about this poster was interacting with it using the decoder glasses, and without them, it doesn’t really make sense. I knew that to do the design any justice, a web version would have to have some level of participation from the viewer. I spend a lot of time on the web, but hadn’t seen anything exactly like what I was trying to do. I’m sure it’s possible in Flash, but I’m not a big fan of it, and I wanted the end result to work on iPads and Blackberrys. It’s pretty much safe to assume that visitors to our website won’t have their own blue decoder glasses. So that’s out.

Eventually I came up with a concept… a foreground image that was the normal poster, a background image that was the “decoded” version of the poster, and some effect that reveals the background image as you move your mouse around. Dividing the poster in to pieces and having those pieces as image rollovers seemed clunky. And then I thought about an “Image Zoom” treatment I’ve seen on ecommerce sites, which lets you see a product you are looking to purchase in detail by hovering over it. This brought me to CSS-Tricks.com and the “AnythingZoomer.”

The concept behind the Anything Zoomer was the same as mine… two images on top of each other, where the image in the back gets revealed as you hover over it. But instead of using the script as designed, with the small image in front and the large one in back, I’d make both images the same size, but use the “decoded” version in place of the large image in the back.

To actually make the “decoded” version of my design, I just added a layer above the rest of my artwork in Photoshop and filled it with blue (#0100df), and then added the Layer Multiply effect. From there, I tweaked the levels of the original design a bit to make it easier to read when being decoded.

The Code

I’d love to say that my mastery of CSS shined from here on, but the AnythingZoomer worked pretty much right out of the box for my purposes. I changed the default sizes to work with my images, designed the rest of the page around it, but it was pretty straight forward. There was really only one thing I needed to tweak. In the original script, between the small and zoomed in large image, there is a bit of an offset. So when I used my two images that were both the same size, they didn’t line up. Being a bit out of alignment looks great when using the script for its intended use, but for my purposes, I counteracted most of the offset by putting some additional CSS on the “large” class… margin-top:50px; margin-left:50px;

Finished Webpage

Other Applications

So now you are thinking, “Great, if I ever need to make a web version of something to replicate decoder glasses, now I can.” And that’s true. But you are missing the point. This exact same technique and set of code provided by AnythingZoomer could be used in a multitude of ways that have nothing to do with zooming. I hope to use them all at some point, and at first wasn’t sure I should offer them up. But eventually I decided that the internet will be a better place with this sort of thing popping up everywhere.

  • X-Ray
    Foreground image looks normal, and the background image is an X-Ray’d version of the same image. A cartoony treatment like the board game Operation would be sweet. The print version could use a glow-in-the-dark spot color. I’m definitely doing this one.
  • Cross Section
    Similar to the X-Ray, but instead of bones, you’d see the cut-away of what’s inside the foreground image. You’d have the exterior of a car or house, and hovering over it reveals what’s inside.
  • Let’s Make a Deal
    What’s inside box number 2? Just hover over it to find out.
  • Where’s Waldo?
    Foreground image where you are supposed to have to locate a person or object among the masses or clutter. If Waldo isn’t your thing, picture those games in Highlights magazine. The background image could have everything grayed out except for what you are looking for… like an interactive answer key.
  • Night Vision
    Foreground image would be mostly dark, and hard to make out, but the background image is green-tinted like you’d see wearing night vision goggles.
  • Heat Vision
    You’ve seen the Predator movies, right?

Project Details

Initial Print Run: 500 posters
Cost: Decoder glasses ~ $0.30/each; Poster printing was done in-house.

Timeline

Idea: February 9th, 2012
Printed finished posters: February 17th
Web-version launched: February 21st

Places It’s Tempting To Use Display: None; But Don’t

You want to hide something on a page, so:

.hide {
   display: none;
}

But wait! By applying that class to an element you've immediately made that content "inaccessible" by screen readers. You've probably known this forever, but still the poison apple sneaks into our code once in a while.

I don't want to re-hash all the specifics. Your best bet is to read "Now You See Me" by Aaron Gustafson on A List Apart to get an understanding of this if you don't already.

One way to encourage yourself to do the right thing is by creating more appropriate class names. Your regular hide class should position the content off screen, which still leaves it screen reader accessible:

.hide {
   position: absolute !important;
   top: -9999px !important;
   left: -9999px !important;
}

I use !important here because if you've gone to the trouble to add a "hide" class to something, you probably mean it and don't want to think too hard about if the specificity value is strong enough. And if you know that you need to display: none something, the class should help you understand it:

.remember-this-will-NOT-be-read {
   display: none !important;
}

Another option for accessible hiding comes from some Snook research and the HTML5 boilerplate:

.visuallyhidden { 
  position: absolute; 
  overflow: hidden; 
  clip: rect(0 0 0 0); 
  height: 1px; width: 1px; 
  margin: -1px; padding: 0; border: 0; 
}

OK you got it. Easy peasy when you're totally in control of class names and all you do is apply and remove them. But things get a little tricker with JS libraries that apply their own CSS. For instance in jQuery, after you .slideUp(), you'll have a display: none in the inline CSS to deal with. Yes, screen readers run JavaScript and yes, that's still a problem.

Again Aaron Gustafson has us covered there, who suggests applying the accessible class name after the sliding is done and then removing the display: none by sliding it the other direction.

var $button = $('#myButton'),
    $text   = $('#myText'),
    visible = true;

$button.click(function() {
  if (visible) {
    $text.slideUp('fast',function() {
      $text.addClass('hide')
           .slideDown(0);
    });
  } else {
    $text.slideUp(0,function() {
      $text.removeClass('hide')
           .slideDown('fast');
    });
  }
  visible = !visible;
});​

Here's a demo of that:

View Demo

Now we have the tools we need to stop using display: none and start using more accessible "hiding" methods.


FAQ pages

If you're hiding the answer until the question is clicked, hide with an accessible class name. Careful you don't .hide() and then slideToggle(), that's not good enough!



Labels

It's tempting to use placeholder text as a label replacement (especially now with some browsers improved UX of leaving the text until you actually type), but don't display: none or remove the labels. I recently heard a heartbreaking story about a blind girl trying to apply for college and the form had missing labels so she had no idea what to put in what fields. So if you're going to use placeholder text as a label replacement, use an accessible hiding technique for the labels.



Tabs

Just because a panel of content isn't the "currently active" one doesn't mean it should be inaccessible. Hide it with an accessible hiding technique instead. Or, you may not even need to. If all the panels are the same height, you can just flip-flop which ones is visible by adjusting z-index.



@media queries

Turning on Voice Over in OS X and using Safari is a screen reader. Now imagine that Safari window was open to a very narrow width and the page had some @media queries for handling smaller viewports. And say that @media query hides some things with display: none in order to better visually accomodate the space. This could be good or bad for accessibility. Are you hiding a bunch of crap that isn't important to the page? Or are you hiding useful things that a person using a screen reader should have access to like they normally would.


No Expert Here

This entire post is based on the premise that display: none is bad for accessibility. It's not based on my deep and thorough understanding of screen readers and general accessibility. If you have more to add, things to correct, or personal experience to share, please do.

Work for Treehouse

The main site sponsor around here, Treehouse, is hiring new teachers for creating new learning videos. It's not a job for just anybody. You need to know your stuff (PHP & WordPress, Front-End Design, Android, or Business & Marketing), be a good teacher, and be good on camera. You also need to live or be willing to move to Orlando, Florida. If that's you, it's a sweet gig.

icon-closeicon-emailicon-linkicon-menuicon-searchicon-tag