A passable but imperfect solution for full-bleed background images on Android and iOS

I’m working on a site right now that has a fixed, full-bleed (i.e. background-size: cover) background image on the <body>. The content flows over it, mostly obscuring it completely, but the background is occasionally revealed in the spaces between content blocks. Some blocks have a semi-transparent background so you can see the fixed background as if through frosted glass.

Here’s the CSS:

body {
  background: rgb(255,255,255) url('../images/ui/body_bg.jpg') center center no-repeat fixed;
  background-size: cover;
}

It’s a cool effect, but it really, really does not want to play nicely on mobile. Various odd things happen on both Android and iOS, and they are completely different.

Quick side note: Yes, the background image is a JPEG. Normally I only use PNG or SVG images in UI elements, but I had good reason to use JPEG here: even though it’s only two colors (with some in-between colors due to antialiasing), the pattern in the background is incredibly complex, and a JPEG version of the file is about 1/5 the size of the PNG. And since it’s an illustration, I tried making an SVG version first, but the pattern is so large that the SVG was about 2 MB! So JPEG it is… which may be a factor in the issue I’m having on Android, but I haven’t tested a PNG version of the image to verify that.

iOS Problems

I’m an iPhone user, so I mainly test responsive sites on iOS. I do own an Android phone (a Motorola Moto E, which I highly recommend as a cheap-but-decent Android phone for testing), but I generally only break it out during the final round of browser testing prior to launching a site.

The issues with background images on iOS are well-known to most web developers. iOS has a number of rather arbitrary seeming limitations imposed upon the Mobile Safari browsing experience, generally for one of three reasons: 1) performance, 2) touch interface usability, 3) the whims of the ghost of Steve Jobs. In the case of background images, background-attachment is not supported. I’m not really sure how this would impact either (1) or (2) — although I think with the early underpowered iPhone generations, it did impact performance — so I think we’re dealing mostly with (3) here. At any rate, because you can’t have an attached background on iOS, I added this in my media queries:

@media screen and (max-width: 782px) {

  body {
    /* For background handling on iOS */
    background-attachment: scroll; background-repeat: repeat;
  }

}

Another quick side note: Why is my phone break point at 782 pixels, you ask? Because that’s where WordPress has its break point for the admin interface. I’m not exactly sure why the WP team chose that number, but why fight it?

Besides the background attachment, there’s also the issue that background-size: cover on a phone is going to make the background image huuuuuuuuuge because it’s scaling it to fit the height of the page content, not the screen size. I initially solved that with background-size: 100%;, since we’re now allowing the background to repeat. As you’ll see, however, that led to problems on Android, so I ended up scrapping it.

Android Problems

Yes, Android has problems. Don’t even get me started! But I wasn’t prepared for this.

I opened the page in Android, and, although the background image was displaying as I expected in terms of size and attachment, it looked… awful. The original source image I am working with is a generous 2400 x 1857 pixels, enough to look reasonably sharp on most displays, even at high resolution. And it looks great on my Mac, great on my iPhone. But on the Android phone it was splotchy and low-res looking… like it had been reduced to 200 pixels and then upscaled (which is maybe what Android is doing, somehow… and here is where I’m wondering if the image being a JPEG is a factor, but that’s just a stab in the dark).

I tried a number of possible solutions, the most obvious being to set exact pixel dimensions for the image. I tried 1200 x 929, basically a “x2” size for high-res devices. Still looked like crap. I even tried setting it to 2400 x 1857, the actual dimensions of the image, and it looked like crap… and I don’t mean pixel-doubled, which is what it actually should be; I mean the same splotchy weirdness I had been seeing at other sizes.

And then I discovered David Chua’s solution:

html {
  /* For background image scaling on Android */
  height:100%; min-height:100%;
}

Yet another quick side note: Here I am not placing this inside a media query. We don’t want to only fix this issue on phone screens. Granted, the iOS solution above needs to work on iPads, too… something I haven’t really solved here. I’m workin’ on it!

This change for Android worked perfectly! By this point I had, temporarily at least, removed the iOS workarounds I mentioned above, so on Android the background image was not only perfectly scaled to the browser window, looking sharp and clean, but it was even fixed-position, just like on desktop!

But… the image was back to being huuuuuuuuuge on iOS. Apparently this html trick for Android does absolutely nothing on iOS, so you’re left trying to find another solution that won’t simultaneously break Android.

An uneasy compromise

It’s not perfect, but I found that if I put both of these tricks together, everything works… the only thing we lose is the fixed-position treatment that Android allows but iOS does not. But the background looks great on both platforms and most importantly, behaves consistently on both.

Here’s the complete code I’m rolling with, for now:

html {
  /* For background image scaling on Android */
  height:100%; min-height:100%;
}

@media screen and (max-width: 782px) {

  body {
    /* For background handling on iOS */
    background-attachment: scroll; background-repeat: repeat;
  }

}

As noted above, this doesn’t really address iPads. A simple solution would be to change the media query to @media screen and (max-width: 1024px), but a) that doesn’t account for the larger iPad Pro and b) it also means a desktop display will lose the proper background effect if the window is smaller than that size. I don’t really have a solution; an adaptive treatment using either server-side or JavaScript-based browser detection would be a consideration, but I don’t really like resorting to that sort of thing for something as basic as this.

It doesn’t help that I recently gave my iPad to my daughter so I don’t currently have a tablet of any kind for testing. That’s about to change as I have a newly ordered Kindle Fire arriving today, but of course that’s not going to give me the answer for an iPad. I can try Responsive Design Mode in desktop Safari, but that’s not always a perfect representation of the quirks of an actual mobile device.

Still… this combined solution for phones is an improvement over the default behavior in both cases.

Follow-up on my post about getting an iPhone 5c on the eve of the iPhone 6 announcement

So, a few weeks back, just 4 days before the iPhone 6 announcement to be specific, I wrote here that I wanted an iPhone 5c. I had been coveting the funky colors and unashamed plastic of them since they’d been announced, and I’d seen enough leaked photos and specs for the iPhone 6 that I already knew, if it lived up to the rumors, that I didn’t really want one.

The day after I wrote that blog post, I went for it. We went to the Apple Store and bought no fewer than three iPhone 5c’s, in fact — two 32 GB units and one 16 GB unit for the boy, who’s now in middle school and needs a way to communicate with us given his newfound independence — and switched from Verizon to T-Mobile in the process.

The rationale: regardless of what they did keep, I knew (or at least reasonably assumed) Apple would be discontinuing the 32 GB 5c once the 6 was announced, and I also knew that 32 GB was the “sweet spot” for my iPhone storage capacity needs. My faltering iPhone 5 had 64 GB of storage, and I had never used more than about 35 GB of that… and even then only by unnecessarily carrying around a half dozen full-length, HD movies on the device.

So it was that on the weekend before the iPhone 6 announcement, I became the proud owner of a gaudy, banana-yellow iPhone 5c. And it was good.

T-Mobile, so far, has been great. The guys at the T-Mobile store where I had to go the next day to activate my phone were fast and knew what they were doing, and T-Mobile’s service has been outstanding, with voice call clarity and LTE reliability I could never even have imagined possible with Verizon, at a little over half the cost.

But my joy didn’t last long. Not because the iPhone 6 surprised me — it didn’t. At all. But because less than 24 hours after I took my iPhone 5c out of the box, it fell out of my pocket as I got out of the car in our garage, and suffered a permanent ding in the plastic on the lower right corner. Fortunately it was very, very small. But it was big enough to consume a significant portion of my attention for the next two weeks. I touched it constantly. I stared closely at it, willing it to disappear.

It did not disappear.

On the night we bought the iPhones, I rationalized the obviously ludicrous purchase by noting Apple’s 14-day return policy. That gave me until the day after the iPhone 6 would go on sale to change my mind.

As it happens, a coworker had preordered the iPhone 6, and it arrived at the studio on Friday. I took a look at it. I held it. I even put it in my pocket. It was not bad… definitely not as obnoxiously big as I had expected. But I still didn’t want it. I would live with my iPhone 5c, scratch and all, for a year at least, until the next round of updates.

But then, the next morning, 14 days after my purchase, and therefore the last day I could return the 5c to the Apple Store, I was idly browsing Apple’s website.

The first thing I noticed was that the 5c, now the lowest-end iPhone, is now only available in an 8 GB size. I had assumed they’d keep the 16 GB around. 8 GB is just stupid now. But whatever. I had my 32 GB unit. I was happy.

Of course I was aware that the 5s had been bumped down to the mid-range level previously occupied by the 5c. Which meant that if I’d just waited a few days, I could’ve gotten a 5s for the price of a 5c. I didn’t really care. I knew it was faster, had a slightly better camera, and had TouchID, which I didn’t think I wanted. I was fine with my banana-colored 5c.

Until I looked at the price. The 32 GB 5s was now $50 cheaper than what I had paid for the two 32 GB 5c’s we had bought 14 days earlier. That meant we could take them back, upgrade to 5s’s, and get $100 back! Hell yes.

Not only that, I could get rid of the ding in the plastic that had plagued my mind for two weeks.

So later that afternoon, we trekked back to the Apple Store, past all of the people queued up outside to get iPhone 6’s, and straight to a blue-shirted employee who was more than happy to work with us and never once even glanced in the direction of the ding. 15 minutes later, we had exchanged our 5c’s for 5s’s and had gotten a big credit back to our bank account.

I used part of my $50 refund to buy a bright yellow case for my “space gray” iPhone 5s.

It’s totally crazy, but I think I want to buy an iPhone 5c… now

topic_iphone_5cNext Tuesday, Apple will be announcing the iPhone 6. Supposedly they’re also announcing an “iWatch” or whatever. The latter is still shrouded in mystery but it really seems like we already know everything there is to know about the iPhone 6.

And honestly… I’m not sure I want it. Thinner? Yes, that would be great. That’s always great. But it’s not like my iPhone 5 is “thick.” Bigger screen? I guess. I’m fine with the size of my iPhone 5 screen, and I don’t want a larger slab to carry around in my pocket. Faster processor? Who would say no to that? Although to be completely honest, my iPhone 5 seems perfectly snappy to me.

So, yeah… I’m pretty happy with my iPhone 5. In fact, there’s only one reason I’m even interested in getting a new phone at all when my contract runs out this month. About a year and a half ago, I dropped my iPhone 5 on asphalt, and dinged the corner right by the camera. Since then, the inside of the camera lens has gradually accumulated dust, to the point where my photos are noticeably blurry, washed-out, and occasionally infested with weird splotches.

Would I be happy replacing my iPhone 5 with another iPhone 5? Yes. I’d be perfectly happy with that. But they don’t sell the iPhone 5 anymore. Instead they sell the iPhone 5c, which is basically the exact same phone but in a cheaper-to-produce (and possibly more resistant to the kind of damage mine suffered) plastic casing. And it comes in bright colors.

I want one. I want the obnoxious yellow one. And I’ve wanted it almost since they came out. For me, the only thing the iPhone 5s had going for it over the 5c was the A7 processor. But, again, I haven’t had any problems with the performance of the 5’s A6 processor.

So, I am left with a strange quandary. I am sure any of my fellow Apple fans will think I am an idiot (or worse) for seriously considering buying an iPhone 5c (actually, two of them) right now, on the cusp of the big iPhone 6 announcement. But here I am.

Apple always has three iPhone models available: the latest-and-greatest (currently the 5s), the last-year’s-model (in this case the 5c, a modified 5), and the two-years-old-model (the 4s). I am wondering what Apple is going to do with their new low-end phone after next Tuesday. Right now it’s the aging 4s, which will be discontinued. That would generally mean it’s time for the 5c to drop into that spot. If I wait until then, I might be able to get a 5c for “free” (“subsidized” by the carrier)!

But… the lowest-end model has only ever been available in a 16 GB size. I’ve learned over the years with iOS devices that I can’t really get by with less than 32 GB of storage. Right now the iPhone 5c is available in 16 and 32 GB models. But after next Tuesday, assuming it becomes the low-end model, the 32 GB version might disappear.

And what of the mid-level model? Will the 5s be downgraded to colorful plastic and renamed the 5sc or some other strange appellation? Would I want that instead? (Yes, I probably would, especially since it would most likely still come in a 32 GB version.)

At the moment I am considering hedging my bets, and buying two 32 GB iPhone 5c’s right now. Yes. Buy them. Keep them in the package. And for the love of all that is good in the universe keep the receipt. Then, wait and see. If I actually want something that gets revealed on Tuesday, I could return the 5c’s. If not, I have them.

Am I crazy?

Defense Against the Dark Arts (of iMessage Configuration)

Ever since upgrading to iOS 6, I’ve had a problem. The glorious promise of iMessage with its seamless integration of SMS/MMS and Apple’s messaging services between iPad, iPhone and Mac has mostly worked, with one infuriating, deal-breaking exception.

Texts to my phone number go to my iPad and not to my iPhone.

Look, all of this integrated messaging is cool. Being able to have text messages show up not only on my phone but on my other devices is awesome. But they have to at least show up on my phone or the whole thing is a failure.

I’ve researched the problem and found some people with somewhat similar issues, lots of stuff involving jailbroken iPhones (which mine is not), etc. but no clear answers to my exact problem. Several people in forums suggested shutting off iMessage on the various devices, deleting accounts, full-blown factory restore, you name it. All of which were either things I tried and found didn’t work, or wasn’t willing to try due to the amount of time and tedious work involved.

iMessage SettingsSo I began experimenting. There was one distinct problem I could see in settings. On both iOS devices and my Mac, the Messages app was showing both my phone number and email address. But in some cases one was grayed out. Infuriatingly, on my iPad and Mac, the phone number was grayed out and checked, and on the iPhone the phone number was grayed out and not checked. I could easily add or remove the connection of my email address to any of the devices, but my phone number was stubbornly locked into my iPad only. (Or, well, my iPad and my Mac… I guess. Honestly I hardly ever use Messages on my Mac so I haven’t really paid attention.)

I wish I could give a clear account of what came next, but I started tapping various buttons and clicking various boxes with such a fury that it all became a blur. What I do remember is that I clicked the checkbox next to my email on my Mac, which un-grayed the phone number. I was then able to uncheck the phone number, and the email now became grayed out.

So, if I understand correctly, the way iMessage settings work, at least one receiving phone number/email address must be checked at all times, so if only one is checked, it’s also grayed out so you can’t uncheck it. Then, if you check the other one, you may be able to uncheck the first.

That wasn’t working on my iPhone, however. Strangely though (at least as I recall from the aforementioned blur), when I repeated the process from my Mac on my iPad, then took a look at my phone, it was already switched to having the phone number checked and grayed out.

So then I began running some tests. This is where things get muddy, and since all of this just happened a few minutes ago, I still may not have a complete solution. I tried sending a text to my phone number from SLP’s iPhone. Never got it. Then I tried sending a text to my phone number from my iPad and it went to my phone within seconds. Cool. Then I tried sending a text to my email address from SLP’s iPhone, and it immediately showed up on all three of my devices.

Everything then is working as expected except that I did not get the text from SLP’s iPhone to my phone number at all, on any device. It’s hard to say what that’s all about. Are things working now? I don’t know.

Here’s another weird thing to throw into the mix. SLP and I share an iTunes Store account, but we have separate iCloud accounts. I also have a separate iCloud account apart from the iTunes Store account. The iTunes Store account uses my “real” email address, and I have a separate me.com email address I use on iCloud. So that’s all kind of a big mess, yes I know. Anyway, whenever I made these various changes to my configurations, the iOS devices would pop up alerts regarding the change. These alerts also appeared on SLP’s iPhone, even though her Messages settings don’t have any of my account info associated with them.

The bottom line here, for me, is that Apple really has not dealt with the reality of multiple users on the same device, multiple family members sharing an iTunes Store account but needing their own iCloud accounts, etc. They may be trying to deal with it all, but they’re trying to integrate too many things that had developed for too long as independent products. And they’re not having as much success at it as they think they are.

This post began as many others here do, as an attempt to share my solution to an Apple conundrum. Unfortunately in this case I just can’t quite make sense of what’s happening, and it seems to be one of those dark-clouds-on-the-horizon portents of more trouble to come with Apple’s tendency for its ambitions to exceed its capabilities in the realm of networked services.

I just want it to work. Isn’t that the Apple promise?

Follow up: Just after posting this I had our neighbor — who also has an iPhone but of course does not share our iTunes/iCloud accounts — send a text to my phone number, and I got it. So the problem seems mostly resolved. But let’s leave it at this: if you share your iTunes Store account with another family member and you both have iPhones, you might need to send your text to each other’s email addresses instead of phone numbers, if you’re running into the same problems I’ve been having.

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.