Fixing background “bleed” on elements that use CSS3 border-radius property

It’s kind of funny that I never encountered this problem before… it must just be extra-noticeable because of the colors on this particular website I’m working on. Anyway, I found that the nice buttons I was creating with CSS3 border-radius were displaying an ugly “bleed” of the background dark blue color beyond the edges of the white border. No good.

before

A little googling led to Mike Harding’s solution, a simple background-clip property in the CSS. (Yet another of the preponderance of new properties in CSS3 that I’m finding it harder and harder to keep up with.) If w3schools.com is to be believed, the vendor prefix is unnecessary. Let’s just go with this:

background-clip: padding-box;

Ah, that’s better!

after

Building a centered gallery grid with flexible column count for responsive web pages

It took an untold number of fruitless Google searches and a couple of hours of trial and error to get this to work. I think part of the problem may have been that I simply didn’t really know how to describe what I’m trying to do in a way that would yield good search results. And so, I hope now that I have a solution, sharing it here might help someone else.

The situation: I have a web page that contains a gallery of square images. The page is responsive but the sizes of the images are fixed. I want the page to automatically show as many images across as will fit in the layout on any particular screen, creating anywhere from one to five columns as needed. And, it needs to stay centered.

I got all of this going pretty easily… all except the “it has to stay centered” part. I was able to get it to work if there was only a single line of images, but as soon as they wrapped to multiple lines, the container element went to a full width and the images became left-aligned. It took considerable effort to discover a solution, although that solution itself is embarrassingly simple. I was hung up on a couple of possible approaches that got me nowhere, which probably contributed to the problems I had finding the right way to do it.

So… here we go. We’ll start with an unordered list:

<ul class="gallery">
  <li><img src="image.jpg" alt="" /></li>
  <li><img src="image.jpg" alt="" /></li>
  <li><img src="image.jpg" alt="" /></li>
  <li><img src="image.jpg" alt="" /></li>
  <li><img src="image.jpg" alt="" /></li>
  <li><img src="image.jpg" alt="" /></li>
  <li><img src="image.jpg" alt="" /></li>
  <li><img src="image.jpg" alt="" /></li>
  <li><img src="image.jpg" alt="" /></li>
  <li><img src="image.jpg" alt="" /></li>
</ul>

And here is that embarrassingly simple CSS:

ul.gallery {
  text-align: center;
}

ul.gallery li {
  display: inline-block;
}

OK, that’s not really all of the CSS. Your li tag needs height and width properties, and you may want to give it margin as well. But those values are going to be specific to your project.

CSS snag of the day: images in tables with max-width set, not displaying properly in Firefox

When did Firefox become such a steaming pile?

OK, that’s not how I intended to start this. Just kinda had to get it out there. Anyway, a client brought an unusual bug with their website to my attention today.

Since embracing responsive web design last year, I’ve become quite fond of using this little bit of code to make images resize dynamically to fit their containers:

img {
  height: auto;
  max-width: 100%;
  width: auto;
}

Most of the time this little bit of CSS works magic. But in this particular case, it did not. The client has put together a table on a page to present a set of photos of board members. In most browsers, the table looks great and is fluidly scaling down the images. But in Firefox, we found it was clumsily overflowing its borders, rendering the images at their full sizes.

After working my way through a few surprisingly unhelpful posts on Stack Overflow, I found my way to this, which seemed to hold an only-too-simple answer:

table {
  table-layout: fixed;
}

I don’t know about you, but I never use table-layout. I’ve come to realize there’s a whole realm of CSS that I just basically never touch, because it’s (usually) completely unnecessary to the way I build pages. But every once in a while, these things come in handy. Turns out, table-layout: fixed was exactly what I needed to — BOOM! — fix the problem with the too-large table images in Firefox.

And, suddenly, CSS was magic again.

Responsive Web Design: A Practical Approach (Part One… Again)

With exactly three posts here all summer, the last being nearly two months ago, it might be reasonable to assume this blog had been abandoned. Wrong! I have simply been so busy, building so many responsive websites, that I haven’t had time to gather my thoughts to share in anything longer than 140-character bursts.

“‘Responsive’ websites?” you say, and I hear the internal quotation marks in your voice. Yes. If you don’t know what responsive web design is… well, let’s be honest. You found this post, if you found it at all, when you googled “responsive web design” so I suspect you have at least a passing familiarity with the term. So let’s get started.

(Actually, before we get started, a quick note: astute observers may… um… observe that I wrote a seemingly identical post to this one back in June. And yes, that’s right. But after a summer immersed in this stuff, rather than continuing from there with “part two” it felt better to start over from the beginning with a more in-depth introduction.)

Getting Started, or, rather: How I Got Started

I’ve owned an iPhone for about 4 1/2 years now, and one of the first things I noticed shortly after it became the hottest thing around was that everyone was suddenly creating mobile websites. There were even services created just to help you convert your website into a mobile website. But it was always a separate experience (usually with a domain name that started with m.) and invariably an inferior one.

A lot of websites still do that, and it still sucks. It’s two separate websites, which is bad for users — often content doesn’t make it to the mobile site, and when that happens there’s no easy way to get to it on the desktop version — and it’s bad for site owners — double (or more) the work.

But about a year ago I started to notice a new approach, one that didn’t require two separate websites, and one that, owing partly to how quickly it caught on with the superstars of web design, usually yielded much better looking results: responsive web design (which I will henceforth lazily refer to as RWD). RWD uses CSS3 media queries to detect the window/screen size the page is displayed on, and changes the layout of the page to suit the screen. On the fly. Same page. Same CSS.

So there is no mobile site, no desktop site. There’s just the site. And it looks great on any screen.

In theory.

Of course, this solution is not perfect. But it is better in so many ways — standards compliant, future-proof, user-friendly, easy to maintain — that it is clearly the optimal solution for mobile websites today.

Getting Started (you, this time)

Before you delve into RWD, there are a couple of things you need to know: 1) HTML5 and 2) CSS3. More specifically, you need to embrace the concept of semantic HTML fully, as a well-structured HTML document is essential to the responsive approach.

I assume if you’re thinking about RWD, you’ve long since abandoned table-based layouts, and you probably don’t even remember the <font> tag existed, right? Right. But for RWD to work well you need full separation of your visual design from your document structure.

My personal preference is to take this to an extreme: I never even use <img> tags except in body content. All visual elements of the layout are contained in my CSS, even logos, and I avoid using images wherever possible. By taking full advantage of the visual effects offered by CSS3, and accepting “graceful degradation” in older browsers (or, in reverse, “progressive enhancement” in newer ones) — a topic we’ll get to in a bit — you can create a lean, well-structured site that is ripe for the responsive treatment.

Building Blocks

Nothing starts from nothing. (Whoa, that’s heavy.) And certainly a responsive website doesn’t (or generally shouldn’t) start from scratch. There are three building blocks that I now include in every site I build out:

reset.css

Created by CSS guru Eric Meyer, reset.css is a handy little file that removes all styling, which can vary between browsers, from all HTML elements, allowing you to “reset” the design and start with a clean slate. Just remember that it means you’re going to have to redefine everything — I guarantee your CSS file will eventually contain strong { font-weight: bold; } and em { font-style: italic; } but that’s the price you pay for complete control.

html5shiv.js

Developed (or at least maintained and expanded upon) by Remy Sharp, the purpose of html5shiv.js is to enable support for new HTML5 elements in older, but still widely used, non-HTML5 browsers like Internet Explorer 8 and earlier. You don’t have to use the new tags like <article> and <nav> to do RWD, but it’s fun, and feels like the future.

jQuery

There are a handful of popular JavaScript libraries out there whose goals are generally to 1) standardize inconsistent JavaScript across browsers, and 2) make working with the DOM easier, so you can do cool, standards-compliant, cross-browser compatible animations and interactivity with just a line or two of code. jQuery is arguably the most popular of these, and is my personal favorite. Again, this is not strictly required for RWD, but I use it all the time, and often in ways that enhance the capabilities of my responsive layouts. (One specific example: it’s great as a foundation for resizing complex elements like slideshows… of course, for that matter, it’s great for making the slideshows in the first place.)

Finding Your Break(ing) Point(s)

The grand vision of pure RWD is a fully fluid layout that scales dynamically to any screen size, and a grand vision it is indeed. But we are living in an imperfect world, with many factors to consider.

In my case, I typically work with outside designers. Designers who appreciate and support RWD but are not immersed in its intricacies like I am. And I don’t want them to have to be. So as a hybrid developer-designer, I make use of my somewhat unusual but not especially unique skill set to handle the responsive adaptations for them. They just deliver a “regular” web design to me, I build that out, and then I adapt and scale and shift things around as needed for the smaller screen sizes, doing my best to stay true to the spirit of the original design.

There are two keys to making this approach work:

  1. Get the designs in Illustrator format, not Photoshop. (No, seriously. You’ll find out why in a bit.)
  2. Be prepared to start thinking about break points and accept that a perfectly fluid layout is not in your immediate future.

To understand break points, you need to understand common screen dimensions. You also need to understand the importance of margins to an aesthetically pleasing layout.

For years the target screen size for web design has been 1024×768 which, delightfully, is also the effective resolution of the iPad. (Yes, the newer iPads have a high-resolution “Retina Display” which is 2048×1536, but CSS pixel measurements are “pixel-doubled” on these displays, so you don’t really need to think about high-res too much, except when it comes to images, and we’ll discuss that in a minute.)

So, we can (still) start with 1024×768. But that doesn’t mean your design should be 1024 pixels wide. You need margins, both for stuff like window “chrome” (borders, scrollbars, etc.) and also just to give your content a little breathing room. A commonly accepted standard width to use for web designs is 960 pixels, and I still stick with that.

This can sometimes cause some confusion for designers who are used to the fixed palette of a printed page. Your content can/should go all the way to the edges of that 960-pixel layout, and you still need to think about what comes outside of that area. So it’s good when you’re designing to think of foreground and background. Have an arbitrarily huge background canvas, with a 960-pixel-wide by whatever-pixel-tall box floating top-center over it, where your foreground content will go.

But I digress. We start with 960. That’s our maximum break point. (OK, if your audience is primarily looking at the site on 30-inch displays, you might want to consider an additional larger break point at 1200 or so.) Then we move down from there. I like to think of it like this:

Device/Screen Type Screen Width Content Width #wrapper CSS
Large computer displays (optional) 1280 and up 1200 margin: 0 auto;
width: 1200px;
Computer/iPad (landscape) 1024 960 margin: 0 auto;
width: 960px;
iPad (portrait) 768 720 margin: 0 auto;
width: 720px;
Small tablets/phones Varies Fluid margin: 0 auto;
width: 90%;

The “small tablets/phones” layouts typically collapse to a single column and are the only truly fluid layouts I use; the larger break points go to fixed widths, which makes for easier scaling of columnar content.

Note that I typically follow the convention of placing everything inside my <body> tags inside a <div id="wrapper"> tag, which allows me to apply CSS to the overall page body and separate CSS to the foreground content (what’s inside the “wrapper”).

Occasionally I will split “small tablets/phones” into two separate break points, with small tablets somewhere between 500 and 640 pixels. I may also change the content widths somewhat to suit the specifics of the design.

Mobile-First Sounds Great, but Let’s Be Honest: It’s Really IE8-First

Earlier in the year, Luke Wroblewski took the idea of RWD a step further with his inspired vision for Mobile-First web design. Initially I wholeheartedly embraced mobile-first, but I’ve since reconsidered.

What is mobile-first? It’s RWD, but instead of starting from the desktop layout and using CSS3 media queries to adjust the layout to smaller screens, it starts from the small screens and works its way up. The main benefit of this approach is that it allows you to prevent mobile devices from loading unnecessary assets (images, etc.) that they won’t actually use.

There’s a major downside to mobile-first, however, at least in my experience trying to implement it: there are still a lot of people using Internet Explorer 8 (and earlier), which does not support CSS3 media queries. So unless you create an IE-specific stylesheet (using conditional comments), IE8 and earlier users will be stuck with a strange variation on the phone version of your site.

So after building a few mobile-first RWD sites, I have abandoned that approach, and gone with what could be called an IE8-first approach. I am not really building to IE8. I work primarily on a Mac, and I preview my work in Chrome while I’m developing. But what I mean is I’ve gone back to that standard 1024×768 screen as the baseline for my CSS, with CSS3 media queries for the smaller screen sizes (as well as for print and high-resolution displays, the latter of which is next up).

Getting Retinal

Remember earlier when I said your designs should be in Illustrator rather than Photoshop? Here’s why: high resolution. Sure, you can change resolution in Photoshop too, but… wait, you’re not still slicing-and-dicing, are you? By working with discrete objects in Illustrator, resolution-independent and, when possible, vector-based, you have the maximum flexibility when you render these objects out as 24-bit PNGs with alpha channel transparency. (You are doing that too, right?)

Starting with the iPhone 4, Apple introduced the “Retina Display” which is their marketing term for, basically, screens with pixels too small for you to see. The goal is to achieve a level of resolution on an LCD screen that rivals print. The exact pixels-per-inch varies from screen to screen, and is not really too significant. The key point is that above a certain pixel density threshold, CSS treats all pixel-based measurements as pixel-doubled. As I noted above, although the current iPad screen resolution is 2048×1536, its effective pixel size in CSS is still 1024×768. There is a practical reason for this (if CSS stuck with the actual pixels, all web pages would appear absurdly tiny on such a screen). But there’s also a practical downside: most images on most web pages are now being scaled up in the browser to these pixel-doubled dimensions, resulting in a blurry appearance.

But here’s something really cool: you can specify the display dimensions of an image in CSS, and the browser will scale the image down on-the-fly. This has been the bane of many web developers’ existence for years, where people who didn’t know better would upload a very large, high resolution photo and scale it down in the page, resulting in ridiculous download times as the image slowly drew in on the page.

Used effectively, however, this characteristic provides an extremely easy way to make images high-resolution on displays that support it. By using CSS to scale the dimensions of an image to 1/2 its actual pixel size, the image will display in full resolution on screens that support this.

Of course, doubled dimensions mean quadrupled pixels, and depending on the details of JPEG or PNG compression, the high-resolution images may be more than four times the file size of their standard-resolution equivalents. So it’s nice to, again, use CSS3 media queries to only deliver these high-resolution replacement images to screens that can display them properly. (This will be demonstrated in the full example code below.)

You Say Graceful Degradation, I Say Progressive Enhancement

The matter of graceful degradation and/or progressive enhancement (depending on how you look at it) is tangential to RWD, but it’s something you’re likely to be dealing with as you build a responsive website.

Not all browsers support all CSS3 capabilities, but that doesn’t mean you shouldn’t use them. I’m especially fond of box-shadow and border-radius, and in working with RWD you’ll probably get quite familiar with background-size as well. Remember that most of these newer capabilities will probably need to include vendor prefixes (like -moz- and -webkit-) as well. It’s cumbersome, and will probably be as painful to clean up as <blink> tags in a few years, but for now it’s the way to get things done.

The biggest challenge with progressive enhancement may well be convincing site stakeholders that it’s OK for the site to look (subtly) different in different browsers. Then again, if you’re doing RWD, that should be a given.

So, What Does This Actually Look Like?

As I’ve iterated my RWD approach this summer, I’ve inched closer and closer to a standard template I can use to start a new website. I feel it’s not quite there yet, but my basic CSS file structure is standardized enough that I can share it here. In a subsequent post, I hope to provide a zip download containing a full template file set for creating a new responsive website.

Here’s a rough example of what my typical CSS file looks like. Again, personal preferences dominate here: I like to write my CSS from scratch, and I typically organize it into three sections: standard HTML (basic tags), CSS classes (anything starting with a period), and DOM elements (anything starting with a hash mark).

The idea is that we’re going from general to specific. Within the standard HTML and CSS classes I alphabetize everything, so it’s easier to find things to change them as I go. Within the DOM elements I try to keep everything in the order it actually appears in the HTML structure. (I also alphabetize the properties within each element definition… but that’s just because I’m anal retentive.)

Sample CSS File

/* IMPORT */

@import url('reset.css');

/* STANDARD HTML */

body {
  font-size: 100%;
  line-height: 1.5em;
}

/* CSS CLASSES */

.column {
  float: left;
  margin: 0 5% 1.5em 0;
  width: 45%;
}

/* DOM ELEMENTS */

#wrapper {
  margin: 0 auto;
  width: 960px;
}

#logo {
  background: transparent url('img/logo.png') center center no-repeat;
  -moz-background-size: 250px 100px;
  -webkit-background-size: 250px 100px;
  background-size: 250px 100px;
  height: 100px;
  width: 250px;
}

/* CSS3 MEDIA QUERIES */

/* PRINT */
@media print {

  * {
    background: transparent !important;
    color: black !important;
    text-shadow: none !important;
    filter: none !important;
    -ms-filter: none !important;
  }
  @page { margin: 0.5cm; }
  h1, h2, h3, p { orphans: 3; widows: 3; }
  h1, h2, h3 { page-break-after: avoid; }
  pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
  abbr[title]:after { content: " (" attr(title) ")"; }
  a, a:visited { color: #444 !important; text-decoration: underline; }
  a[href]:after { content: " (" attr(href) ")"; }
  a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
  img { max-width: 100% !important; page-break-inside: avoid; }
  thead { display: table-header-group; }
  tr { page-break-inside: avoid; }

}

/* LARGE TABLETS (UNDER 1024 PIXELS) */
@media screen and (max-width: 1023px) {

  #wrapper {
    width: 720px;
  }

}

/* SMALL TABLETS/PHONES (UNDER 768 PIXELS) */
@media screen and (max-width: 757px) {

  #wrapper {
    width: 90%;
  }

}

/* HIGH-RESOLUTION DISPLAYS */
@media only screen and (-moz-min-device-pixel-ratio: 1.5),
    only screen and (-o-min-device-pixel-ratio: 3/2),
    only screen and (-webkit-min-device-pixel-ratio: 1.5),
    only screen and (min-devicepixel-ratio: 1.5),
    only screen and (min-resolution: 1.5dppx)
{

  #logo {
    background-image: url('img/logo_x2.png');
  }

}

The Test Suite

Of course, all of this work means nothing until we’ve seen what it actually looks like in the web browsers on these different devices. To that end, a decent test suite is essential.

One cool trick about RWD, which is not only useful to dazzle clients when pitching a RWD approach to their websites, but is also helpful for quick testing as you go, is that the responsive approach works simply by making your browser window smaller on a computer. So you can shrink the window down and approximate what the site will look like on a tablet or a phone without actually having one in your hand at all times.

But before you go live, you do need to test it for real on different devices, just like you need to test in different browsers. The table below shows my test suite. It’s not comprehensive, but it’s practical, and it all fits in one small messenger bag.

Device Operating System Browser(s)
MacBook Air Mac OS X Mountain Lion Chrome (latest)
Firefox (latest)
Safari (latest)
MacBook Air
with Boot Camp
Windows 7 Internet Explorer 9
Chrome (latest)
Firefox (latest)
MacBook Air
with Parallels Desktop
Windows XP
(3 separate virtual machines)
Internet Explorer 8
Internet Explorer 7
Internet Explorer 6
Firefox 3.6
Note: I only offer my clients very limited support for IE6.
iPad (Retina Display) iOS 6 Mobile Safari (latest)
Chrome (latest)
iPhone (Retina Display) iOS 6 Mobile Safari (latest)
Chrome (latest)
Samsung Galaxy Player 4
(high-resolution)
Android 2.3 Android web browser

Give Me Something I Can Print!

You may have noticed in the full example CSS above that I included CSS3 media queries for print. The need for decent print output will vary by project — different sites’ audiences may be more or less inclined to print out pages. In general I think of printing out web pages a bit like I think about… well, honestly, I can’t even think of a good analogy. You just shouldn’t do it. But sometimes it has to happen. I won’t be exploring the infuriating nuances of print CSS here, other than to say that if you do need to support printing, the code provided in this sample is a good place to start. (Sadly, although I use it regularly, I neglected to make note of its source. If you know where it’s from, please let me know in the comments.)

Where Do We Go Now?

OK Axl, hang on. I know I’ve dumped a lot on you here to think about, without necessarily providing enough specifics. But that’s kind of the point: in order to do this right, you really need to learn it for yourself and gain the experience of building RWD sites directly. This is what has been working for me but my approach is certainly neither the only nor the best way, I’m sure.

My hope is to follow up this post with a “Part Two” entry this time around, where I get into more of the specifics of an actual example website. In the meantime, experiment and discover! And be sure to check out the entire A Book Apart series, as they provide the conceptual and detailed knowledge needed to get started with this exciting new approach to web design.

Practical responsive web design, part one

I’ve been wanting to write this post for a while, but I’ve been too busy writing code instead. Plus, the techniques are evolving and changing so fast, that by the time I finish a project, the way I built it is already obsolete.

Now, with the Breaking Development Conference in town and a few recent responsive site launches under my belt, it seemed like a good time to write up a summary of what I’ve learned, what I’m doing, and where I think all of this is going.

First, a quick aside. I didn’t attend the conference. I would have liked to, but as an independent developer I never seem able to justify the standard $500-per-day rate most conferences charge. That doesn’t mean the conferences don’t have value; they’re just not for me.

Before we begin

There are a few caveats I want to lay down before I start talking about responsive web design:

This stuff is changing… fast. Anything I write here may become foolishly out of date by the time I hit the “Publish” button. Responsive web design is a work in progress, and there are no rules (yet).

What I’m doing may not be “by the book,” proper-name Responsive Web Design. The book is great, and there are “experts” who have much deeper knowledge of these strategies than I do. But as I said above, there are no rules (yet). I want to describe the practical techniques I am employing on actual live web projects, under often less-than-ideal circumstances.

Every website is different. The company is different. Its audience is different. The content and style and context where it will be viewed are different. The balance between showing off fancy new features on high-resolution tablet displays and supporting corporate IT departments that are still straggling with Windows XP and Internet Explorer 6 will vary. In short, what I am doing may not work for you. But I hope it can give you some ideas that will.

A practical baseline

My goal with responsive design is to get the biggest “bang for my (client’s) buck.” I recently read a about a study that found almost 4,000 different Android devices in a site’s access logs, with many of them only appearing in the logs once. It is not possible to account for all of these variations. And, after its primary goal of providing an optimal user experience across a variety of devices, not needing to account for each of them individually is the second biggest purpose of responsive design. (That’s also, arguably, its biggest practical benefit.) By building on a fluid, flexible structure from the beginning, a site will look good regardless of slight variations in its presentation.

But I’m not starting from scratch. I work with a number of designers who deliver their work to me in a variety of formats (usually Adobe software). They’re tremendously talented, but they don’t all have a full working knowledge of fluid grids and all of the other considerations that go into responsive web design. So my job is largely to translate these “traditional” web designs into something that works, more or less, with a responsive approach.

I’m targeting three basic screen types: computer (desktop or laptop, including iPad in horizontal orientation), tablet (primarily iPad in vertical orientation, but also smaller tablets like the Kindle Fire or the Nook Color), and smartphone (primarily iPhone, but also Android and Windows Phone). Additionally, I am trying to balance a Mobile First approach with support for Internet Explorer 7 and 8. (I am fortunate to be in a position not to need to worry much about IE6 anymore, and IE9 plays well with CSS3 media queries.) In some cases I am also targeting “very large” computer displays, those with a horizontal resolution of 1280 or above, with a scaled-up layout.

So, instead of accounting for 4,000+ different screens, I’m aiming at 3 (or 4) general screen categories. I am also accounting for two basic browser categories: IE 7 and 8, and everything else. (Yes, if you approach it in the right way, it’s really that simple. Almost.)

Fixed, yet flexible

With this “practical baseline” in mind, and working primarily with traditional fixed-width web designs as a starting point, I’ve established break points (widths at which the layout changes significantly) at around 700 pixels (varying by site between 640 and 720); at 960 pixels for the “standard” computer (and horizontal iPad) layouts; and, for the “very large” displays, at 1200 pixels. This allows for a traditional fixed-width web design approach to be used, rather than accounting for a completely fluid layout across all screen sizes. It may sound like a cop-out, but I find it to be a very helpful way to get things done when collaborating with designers who are not living and breathing this stuff the way I do every day.

For screens below my “around 700″ threshold, I drop into a fully-fluid, single-column layout targeted at the smartphone user experience. In these cases there may be other significant changes to the layout, such as collapsing content blocks into expandable buttons, allowing users to quickly see what’s on the page without having to scroll endlessly. (This is not a radical invention of my own… it’s more-or-less how the mobile version of Wikipedia functions.)


In part two, I will get into the details of how I built out a pair of recent websites, including a few code examples, to show how the HTML and CSS fit together, and how I balance the seemingly incompatible worlds of mobile-first and IE8.

My (just-discovered) workaround to the WebKit letter-spacing bug

Update (5/29/2012): Upon working further with the project that formed the basis of this post, I discovered that my solution did not work, or at least, no longer worked. It’s not uncommon as I get deeper into a project with a large CSS file that there are subtle, inadvertent effects of the various CSS properties that get added along the way. Looking back now, I can’t determine for sure whether my solution did once work with the simpler version of the site, and something else I added later counteracted it, or if I was just too eager about a solution to realize it never quite worked in the first place. As a result, I had considered deleting this post entirely, but I have decided to leave it live, to further the discussion of the topic, or at the very least to serve as a monument to my challenges.

WebKit, the rendering engine “under the hood” in both Safari and Chrome, has a known issue handling the CSS letter-spacing property at certain small increments, and at certain font sizes.

Specifically, if defining letter-spacing in increments smaller than 1px or 0.1em, it seems to just ignore the property altogether… except at larger-than-default sizes.

I typically use em or % these days to define text sizes in CSS. So in my situation, I’ve found that my letter-spacing: 0.05em works if I also specify font-size: 125% (or larger), but if I have font-size set to 100% or less, the letter-spacing gets ignored.

Typically, after loading reset.css, I set a baseline font size for the document with body { font-size: 100%; } (or some size… actually it’s usually 80% but these days I’ve been leaning towards larger type).

I decided to play around with this a bit to see if I could resolve the letter-spacing issue, and I found a nice, easy solution that works at least for the particular site I’m currently testing it on. Your experience may vary, depending on how your HTML is structured and how complex your design is.

Here’s the solution:

body {
  font-size: 125%;
  letter-spacing: 0.05em;
  line-height: 1.3em;
}

body>* {
  font-size: 85%;
  line-height: 1.3em;
}

You may want to adjust the exact values of font-size to suit your needs. (And, yes, I’m aware that mathematically 125% and 85% don’t cancel each other out, but they’re close enough for my purposes.) It’s important to include the line-height property in body>* to define your target line height; otherwise your lines will be too far apart. Set it to whatever your ideal value is. (I usually prefer line-height: 1.5em personally, but for larger type, as on the site I’m currently working on, it gets too spaced-out.)

So what’s going on here? Well, strangely, it seems WebKit can actually render smaller type with line-spacing less than 1px or 0.1em just fine, but it won’t unless somewhere in the “cascade” the type has been defined as being a certain amount larger than 100%. I don’t get it, but until the bug (which it seems clearly to be after all of this) gets fixed, at least this seems to be a reasonably clean workaround.

It’s very important that you use body>* and not just body *. If you don’t know why, well… try it out and see. (The upshot: we’re applying a uniform scaling-down across the board on all elements directly under body, which is practically the same as just defining our target font size directly on body itself, but with the benefit of working around the letter-spacing bug.)

Note: I have only tested this using em as the unit of measure for letter-spacing. I’m aware of the issue with px as well, but I’m not sure this solution will work for that. But… really… just use em instead!

The :first-child conundrum

I like to think I’m a pretty adept CSS developer. I may not have written the book, but I have a solid understanding of CSS and can do some sophisticated things with it.

But one place I always get snagged with CSS is in using the :first-child pseudoclass. The idea behind :first-child is that you can apply different styles to the first child element inside a parent element than for the rest of the instances of that child element inside the same parent.

A way I end up wanting to use it a lot is to give the first child different margins than the rest. Maybe most of them need margin-top: 2em; for instance, but I want the first one to be flush to the top of the parent by using margin-top: 0; to override the default margin.

The full CSS might end up looking like this:

div>h2 { margin-top: 2em; }
div>h2:first-child { margin-top: 0; }

And then that would be put together with some HTML like this:

<div id="content">

<h2>First header</h2>
<p>This is the first paragraph!</p>

<h2>Second header</h2>
<p>And, surprise! This is the second paragraph!</p>

</div>

So far, so good. The problem is, what if you stick something else into the <div> before the first <h2> that isn’t another <h2>? Say, something like this:

<div id="content">

<div class="floating_sidebar">This should be floating to
the right of the content.</div>

<h2>First header</h2>
<p>This is the first paragraph!</p>

<h2>Second header</h2>
<p>And, surprise! This is the second paragraph!</p>

</div>

You may have guessed at this point that I’m not describing a hypothetical situation here. This is a stripped-down version of exactly what I’m building right now. The problem is, now the first <h2> is no longer the first child element of the parent <div> overall, so the :first-child CSS gets ignored.

True, it’s not the first child element, altogether, inside the parent. But it is the first <h2> child inside the parent. I can understand how, in other circumstances — say, if the inserted <div> wasn’t a float — you’d want the h2:first-child not to apply here. But in general it seems to me that if you’re specifying a tag with your :first-child, it should only matter that it’s the first tag of that type under the parent, even if there are other different tags before it.

I guess the real solution here would be to create another pseudo-class that does what I want. Now I just need to convince the standards folks and the browser makers to do that.

Note: The sample HTML was kind of a mess when I originally posted this. That’s what happens when you write a blog post in a hurry before rushing out the door for a meeting. It has now been corrected, and I made some other edits for clarity while I was at it.

Bracing for the HD web

Joshua Johnson has an excellent new post over on Design Shack called Ready or Not, Here Comes HD Web Design, discussing adapting your web design techniques for the imminent HD revolution, being led by the new iPad.

I’ve been adapting my designs for the Retina Display on the iPhone 4/4S for a while now, but it’s easy enough to build a responsive web design that just shrinks down large desktop website images to half their size for display on a tiny iPhone screen. Making an essentially desktop-sized display support high-resolution graphics is a whole other story, and even though I knew (or presumed, along with the rest of the world) that a Retina iPad was coming, I think some small part of me was still in denial about what it would mean for web design.

Well, that future is here. Sure, most of the world is not browsing the web on a Retina Display iPad. But if you think the HD revolution ends there, think again. It’s just getting started. I’m about to enter the implementation phase on a handful of big web projects over the next month. Accommodating the new iPad’s display is going to be one of my top tasks.

I’ve been thinking for the past month or so that I was going to need to address this, and I’ve made the decision that, moving forward, on any site that has responsive web design as a component (which will probably be all sites I do), full-size “Retina Display” graphics are essential.

I posted a comment on Joshua Johnson’s post, where I noted that “Retina” (or, to avoid using Apple’s marketing term, “HD web”) graphics don’t really need to be 326 pixels per inch (ppi), the iPhone 4/4S’s resolution, or even 264 ppi, the new iPad’s resolution.

The standard practice with web images has always been to render them at 72 ppi, but the fact is, browsers don’t care what resolution an image is set to. A pixel is a pixel, and web images get displayed at the screen’s native resolution (unless, of course, you resize the image dynamically in the browser using HTML dimension attributes or CSS). The Retina Display approach Apple uses is to simply double the resolution (quadrupling the number of pixels). Web images by default get “pixel-doubled” in this scenario, displaying at the same relative size as they would if the iPad still had a low-res display, but appearing pixilated or blurry as a result.

You don’t need to render your images at 264 ppi for display on the new iPad. In fact, you can leave the resolution at 72 ppi, because the browser still doesn’t care. (Well, maybe it does; I haven’t actually had an opportunity to test it, but I strongly suspect the answer is no.) You just need to make the pixel dimensions of the image twice what they were before. In fact, even if you do change the resolution, you still need to double the dimensions. That’s the key.

After mulling all of this over for the past week, I’ve decided I’m going to have to get a new iPad (what a hardship, I know). I could technically do this work without it, but I think it’s important to be able to see what I’m producing, if for no other reason than to remind myself how important it is.

This is going to be an ongoing process, and because web design (or, more accurately, web design implementation — I usually work with designers who produce the initial UI in Illustrator or Photoshop) is only one part of my job, I can’t give it my undivided attention. But it’s something I am preparing now to immerse myself in as fully as possible. From now on, this is just how I do things. And with that in mind, there are some key points to consider:

1. Some images are more important to represent high-res than others. Logos, absolutely, 100%. Design elements that are on all pages (backgrounds, borders, navigation) come next. One-off photos are not as critical, but probably still are if they’re on the home page. But consider the next point as well.

2. Bandwidth is a concern. I’ve been somewhat dismissive of this up to now, as I’ve been focusing on high-res logos for the iPhone’s Retina Display — it can just take the regular web images and show them at half size to achieve high-res — but if you’re suddenly talking about downloading 4 or 5 high-res photos for a home page slideshow, it’s going to be a problem. Making users with standard resolution download unnecessarily large images is bad; making iPad users eat up their 4G data plan downloading your perfect-looking photos is bad too. Most of the attention paid to bandwidth in this discussion that I’ve seen so far has focused on the former, but both need to be addressed.

3. CSS and SVG. Joshua Johnson talks about this in his post. If we can render elements using CSS instead of images (things like curved corners, gradients, shadows, etc.), we should do that. More complex vector graphics can be displayed in SVG. All modern browsers now (finally) support SVG. Up to now it’s been a cool but essentially useless technology, due to lack of widespread support. But IE8 and earlier don’t support SVG, so if those browsers matter (and unfortunately they probably still do), you need a backup plan.

It is an exciting time to be working in web design and development. More and more, the challenges center around adapting your techniques to take advantage of cool new features and capabilities, not accommodating the limitations of crap browsers. But they’re still challenges, and we’re just beginning to discover their depth, along with their solutions.

Update: Over at Daring Fireball, John Gruber just linked to Duncan Davidson’s post detailing an issue with WebKit (the rendering engine inside Safari) automatically scaling down images above a certain size, specifically over 2 megapixels. Looks like sending huge, high-res images to the new iPad might present even more challenges than the ones I’d been considering.

I still don’t have that new iPad, so we’ll see what happens when I get it. (Tomorrow?)

Update #2 (March 25, 2012): A few more days have passed, and more has been learned on this topic. Duncan Davidson has a follow-up post that further explores the issue and a tentative path forward.

P.S. I did get that new iPad, and Duncan’s demo of an 1800-pixel JPEG on the iPad’s Retina Display is truly impressive. But what I find really interesting about it is that the 1800-pixel version of the photo looks better than the 900-pixel version even on a regular computer display… because, as I’ve observed, WebKit downscales images better than Photoshop does.

Responsive Web Design: On embracing the web’s uncertainty principle

What do Werner Heisenberg and Ethan Marcotte have in common? First and foremost is probably that I have just mentioned them in the same sentence. Second, whereas Heisenberg’s uncertainty principle paved the way for quantum physics (which revealed that matter and energy can exist as both a particle and a wave), Ethan Marcotte’s Responsive Web Design promises to usher in a new era where we discover that desktop and mobile websites, too, can be one and the same.

My analogy may be stretching thin, but the point remains that we are entering a new phase in web design. We can no longer assume websites are being viewed on a desktop computer screen of certain minimum dimensions. We also can no longer justify building and maintaining two (or more) discrete sites, shunting mobile users off to a scaled-back, limited experience while allowing desktop users access to the full version. And all of this means that we must consider the dynamic (and, in fact, increasingly so) nature of the web as a medium from the earliest steps in the design process.

Many examples of Responsive Web Design are beginning to crop up (including this site), but the best high-profile example so far is a site Marcotte himself consulted on: the new BostonGlobe.com. I’m hopeful that soon this design approach will become the norm for most websites.

But the challenges facing those of us who are ready to embrace Responsive Web Design are many. Getting a handle on the use of CSS3 media queries is the first and probably easiest of these, if you’re comfortable with code. Most of the leading innovators in web design have long worked directly in code — and knowing and working directly with HTML5 and CSS3 is pretty much a requirement for effective use of the Responsive Web Design approach.

But I would guess that the majority of web design going on today is still being done the “old fashioned” way. A graphic designer, usually with experience primarily in print, puts together a layout in one of Adobe’s creaky monolithic Creative Suite applications (Photoshop, Illustrator, InDesign), then (if we’re lucky) hands off that design file to a developer to build out as HTML. If the developer is with it, they will follow best practices and web standards, building out semantic HTML document structures with design properties defined in CSS. (No tables, please.)

There are many potential points of failure in this arrangement, because a design in an Adobe application bears little resemblance “under the hood” to an HTML/CSS layout in a web browser. It’s not just that the canvas you’re painting on is different, although there’s that. It’s that they’re not even both canvases. No matter how much Adobe tries to ease the transition for print designers, any process that forces you to start by specifying page dimensions just isn’t going to translate effectively to the nebulous, dynamic format of a website.

“Design in the browser” is the new mantra. And again, that’s great if the person designing knows how to do that. But many designers don’t, and it’s not necessarily fair to expect them to. The entire process needs to change. Developers and designers need to work together more collaboratively, and earlier on in the project. For years I’ve been promoting the importance of designers understanding HTML/CSS and the capabilities (and limitations) of web browsers, even if they don’t necessarily write the code themselves. It’s not just about knowing what certain browsers can or can’t do (like the fact that Internet Explorer didn’t support layered backgrounds until version 9). It’s about knowing all of the things browsers can do that can’t possibly be replicated or even represented in a static design built in an Adobe CS app.

There are so many aspects of this that have always been important (how best to slice up a design; what’s background/foreground; what should be images and what shouldn’t; when to use JPEG vs. PNG; optimal page widths; where the “fold” is and whether or not it exists even as a concept; the fluid nature of vertical elements; how users interact with elements and how the page gives feedback using JavaScript and/or CSS; etc.), but now on top of all of these concerns we have the additional complexity — and opportunity — of working with different classes of devices with radically different screen sizes, capabilities, and interaction methods.

Again, “design in the browser” is the ideal. But until we get there, it’s essential that graphic designers who aspire to work with the web take the time to really understand the medium: how it works, how varied it can be, how quickly it changes. Then, even if the designs are, for now, still delivered in an Adobe format, their structure and content will at least be better informed by the practical realities of the form they will finally take in a web browser.

So, as a designer, what’s the best way to get informed? Working with a developer who understands and is enthusiastic about Responsive Web Design is a great option (hint, hint), but at the very least I recommend reading Ethan Marcotte’s book. In fact, the entire A Book Apart series is essential reading for anyone who wants to build forward-looking websites. The future is coming. We may not know what it will look like yet, but it’s a safe bet that tools and techniques that were already antiquated a decade ago are not the way to get there.

I don’t want to end on a down note, so I’ll pose this final challenge to inspire and motivate any designers who might be reading this. Despite the potentially intimidating appearance of code, web standards are first and foremost about simplicity. The dynamic duo of HTML5 and CSS3 are a world apart from the hairy mess of table layouts and <font> tags that dominated the early web. Watching a design take shape directly in the web browser can even be fun! And with the powerful interactive capabilities of JavaScript tools like jQuery, and the typographic world that has been opened up recently with font embedding services like Typekit and Google Web Fonts, there’s never been a better time to be a web designer. The more you know about what goes into realizing your designs in a web browser, the better you will be at your job and the more opportunities you will have.

Google’s redesign: a second look

I want to follow up on my post about Google’s redesign from a couple weeks ago, as this redesign has, unsurprisingly, continued to evolve (or at least, reveal itself through ongoing usage).

It’s clear that Google is phasing in a massive overhaul, not just of how their products look, but how they work, and more specifically how they work together. This is a full-scale rethinking of the Google brand, and I’m not sure I like it.

The natural inclination for most users when something is unexpectedly changed is initially resistance. (Just look at how TechCrunch announced their redesign yesterday. They knew what the reaction would be.) And I frequently fall into that too, only to finally come around after a while when I finally “get it” or just get used to it.

But there are unprecedented challenges for Google with this redesign, owing mainly to two things: 1) users’ absolute dependence on Google tools for certain online tasks (search and mail being the most obvious) and 2) the vast scope of products and services Google is attempting to graft together.

The first is hard to avoid: the more users depend on something, the more upset they’ll be when you change it. (Like this.) The second is not. The second is neither necessary nor obvious. It didn’t have to happen at all, and it doesn’t have to happen the way it is. And as time goes on, I realize that’s what I dislike most about both the initial shoddy execution and the plan and goals underlying it.

As I consider it more, I realize that my disappointment and frustration stem from the fact that this massive integration effort affects my dependence on Google products in a way more profound than I would have expected. I have a Google Apps account for my room34.com domain, and in the conversion Google has forced upon that domain, I am running into numerous issues as I’ve had to merge my personal Google account with my domain account (which I didn’t even realize were separate, since they both use the same email address). Certain data didn’t survive the transition (like my Reader subscriptions); third-party applications that tie into these services are no longer working because of the “2-step verification process” which itself isn’t working, for reasons unknown; certain tools are unavailable to my domain, without explanation (I can’t create a Google Profile, which also means I can’t use Google+); and worst of all, whenever I run up against one of these issues, all Google can do is direct me to outdated and irrelevant documentation. No answers, only more questions.

I’m left with the impression that all of this was not fully thought through. But then again, I don’t think all of it could be thought through. I think it’s damn near impossible to integrate all of these disparate products and services into a cohesive whole, when most have been developed by relatively autonomous internal teams or acquired from outside, and were never designed nor envisioned as one day becoming integrated. And while I applaud Google for its (apparently sudden) focus on this grand new vision for its products, I’m not sure it’s something I really want anyway. Google is already a bit frightening and monolithic, with its vast stores of personal data collected about each of its millions of users. Despite its “Don’t be evil” motto, (former) CEO Eric Schmidt has said things like this (as quoted on Daring Fireball):

“We don’t need you to type at all. We know where you are. We know where you’ve been. We can more or less know what you’re thinking about.”

That quote is taken out of context, but the context doesn’t really help it much. With thinking like that trickling down from the top, do you really want Google to seamlessly integrate all of its products? Their disarray was the only thing providing a modicum of security-through-obscurity for Google’s users. Google may just be collecting all of this personal data to help it more effectively deliver ads to your eyeballs, which is how they make their money, and is bad enough. But that data is there. Who knows how it will be used by Google or whoever else might get their hands on it in the future?

Then again, maybe I shouldn’t be too paranoid. Google’s incomplete efforts at integration are probably a good thing after all.