Yesterday I sat down and implemented a cross-browser (WebKit and Firefox, I don’t count IE) way to achieve a “fade out the element on the right with a mask” effect for our upcoming web app Charm Customer Support—it’s harder than it should be, and here’s how it works:
Fist off, for WebKit-based browsers, the -webkit-mask-image CSS property is used with a CSS gradient. This is really easy to do and straight-forward. However, on Firefox, you need to use a SVG-based gradient that’s piped into the mask CSS property. As far as I know, you can’t just copy+paste the mask property into an external CSS file—if you do that you’ll need to specify the SVG gradient in an external SVG file as well.
JavaScript is a modern, flexible and malleable scripting language, and it deserves to be treated as such—to this extend, I’ve extracted the style guide Mislav and I wrote for Zepto in a new project called Pragmatic.js.
There are a lot of style guides out there, but they are all a long and tedious read and, in my opinion, often read like people are scared of using JavaScript and want to make it look more like C or Java. But it’s not. It’s a super awesome scripting language with lots of wonderful features (and arguably some quirks as well!).
Writing pragmatic JavaScript is all about optimizing the process of writing JavaScript for you as a programmer, using all the facilities the language provides.
While there are relatively few expensive laptops that have a Retina screen, practically all mobile devices have a high density screen. And if you think this is just an Apple-thing, you’re dead wrong—all Android phones and tablets, the Amazon Kindle Fire, the Playbook, and Windows Phones have high-density screens. On the enterprisey side of things, Microsoft announced that Windows 8 will have full support for high-density desktop computers and laptops.
Let’s put this in context: mobile internet usage has doubled last year, and right now about 20% of all web traffic in the US is from mobile devices. This means Retina screens will soon become the norm.
If your websites and apps aren’t Retina-friendly, you’re going to be showing standard definition websites in a high-definition world. It’s not going to be pretty.
I’ve done weeks of research on it and put together the first, definitive guide on the essentials to make your websites and apps shine on high density displays. You can learn all that in just 30 minutes. And it’s out of beta now—updated with the latest and greatest information.
30 minutes to websites and apps that shine on high density displays—in the amount of time it’ll take you to sort through what to read on the web, you could instead read my ebook and be half done with Retinafy-ing your websites already!
An assumption that a lot of web developers have is that retinafying images by doubling their resolution results in files that are four times larger.
The reasoning goes like this: If I take a 100×100 pixel image, that has 10,000 pixels, and has a file size of, for example, 10kb, doubling the resolution to 200×200 means that there are 40,000 pixels now, and the file size must increase to 40kb accordingly.
However, image compression doesn’t work like that—it hardly scales linearly with the amount of pixels in the image.
Let’s look at PNG images first. These are often used for interface elements, logos and so on. There are huge areas of transparency, of single colors and of repetitive color patterns that doesn’t change. Because of that, actual file sizes of images that are twice the resolution of the original don’t differ that much.
For JPEG images, you can just double the resolution (or go as high as possible depending on your original image source), and lower the JPEG quality. Don’t be afraid to go as low as 15 to 25, as shown in these example photos from my Retinafy.me ebook. Yes, on a normal density screen this would cause all sorts of ugly JPEG artifacts—but don’t forget that on a retina screen pixels are so small that you can’t see them, which results in JPEG compression artifacts being far less visible. And when you scale the bigger JPEG image down for display on a normal screen, you get results that rival much higher quality JPEG images at the small resolution.
Note that exceptions prove the rule, and you may end up finding an image which doesn’t compress well or which has visible issues on low quality JPEG settings. For these, I highly recommend spending some time to figure out the root cause and implement workaround (you’ll find information about what to look for in my book!).
Whether the small pixels of retina screens scare you (just kidding!) or you’ll simply don’t want to spend countless hours researching it, my book will be your guide. Step-by-step instructions will show you how to upgrade to high-resolution screens with the least effort. Plus, I’m obsessed about loading speed and image quality.
Learn about…
What’s a Retina screen, and which variations are out there
Why you should use high-resolution images by default
The most efficient way to target retina screens in CSS
How to use CSS and SVG to replace bitmapped user interface elements
Deciding if you need two versions of an image
Creating beautiful favicons that work great on any screen
How to keep file sizes of images in check
Why JavaScript-based image replacement techniques are a bad idea
And create Retina-ready web sites in no time!
The book also includes easy to follow rules, a decision tree and case studies; as well as detailed comparisons of various quality settings when dealing with high-resolution photos. You’ll also learn how to workaround issues when features are not supported (SVG on Android, hah) and when things are rendered badly.
Right now, the book is in beta and rough around the edges… but you’ll save a cool $10 off the final price if you buy before it’s finalized (the final version should be available in late Summer 2012!).
Update 24/7: If you like the flowchart, grab my ebook on all things Retina at retinafy.me! It’s out in beta now—save $10 over the final price.
With Retina screens all around us, it’s time to take the plunge and retinafy your website or webapp. Here’s the process I use (for both mobile and desktop) in the form of a flowchart for some more sanity in all of this.
Since the announcement of the MacBook Pro with Retina screen, everybody seems to be busy making Retina versions of their sites and apps. Before you @2x everything, let’s take a step back and look at the big picture (*rimshot*). Here are the screen densities of some more or less current Apple products and a current Android phone:
iMac 27″ 109dpi
MacBook Pro 13″ 113dpi
MacBook Pro 15″ Hi-Res 128dpi
iPad 2 132dpi
MacBook Air 11″ 135dpi
MacBook Pro 15″ Retina 220dpi
New iPad 264dpi
Galaxy Nexus 316dpi
iPhone 4 326dpi
What’s not included here is that on the MacBook Pro with the Retina screen you can choose a virtual resolution, and the screen is scaled accordingly.
These virtual resolutions are (afaik) achieved by rendering at twice the virtual resolution and scaling the resulting picture to 2880×1800 (the native resolution of the MacBook Pro’s screen). Let’s have a look at the settings:
1024×640: rendered at 2048×1280, ~156dpi
1280 x 800: rendered at 2560×1600, ~195dpi
1440 x 900: rendered at 2880×1800, 220dpi (native)
1680 x 1050: rendered at 3360×2100, ~257dpi
1920 x 1200: rendered at 3840×2400, ~293dpi
The point is, that if you take all these pixel densities there’s a pretty linear spread. “Just have one normal version and a scaled-by-two version” is just not enough. And this is not only true for Macs and mobile devices, Windows 8 will run at 1x, 1.4x, and 1.8x scaling modes (/ht @thijs).
Plus, on mobile devices people zoom into (and out of) website content all the time and this will likely become the norm on desktop computers, too (Safari already has full support for gesture-based zooming). And there’s the topic of accessibility.
My advice: better do away with ALL raster graphics for your web app or site, and switch to use vector-based artwork (SVG!), possibly custom fonts and of course other CSS3 features where possible. For photos and images, use hi-resolution JPEGs and spend time on optimizing the quality settings.
I recently ported my little CreditCard.js library from Prototype.js to use underscore.js, as I needed that in a project. Here’s what I’ve found—check out the original Prototype.js version first:
And here’s the same thing, but ported to underscore.js:
A few observations that, needless to say, are opinions, not scientific fact:
Prototype.js’ direct extensions of built-in prototypes make code cleaner and easier to read
Sometimes JavaScript-provided APIs like reduce have their arguments in just the wrong order; especially when used with chained method calls.
Some helper functions, like $w are missing in underscore.js
curry is more fun than bind, and I don’t need to specify a scope
Porting is pretty straight-forward, a testament to Prototype.js’ influential role in modern JavaScript
Prototype.js is still awesomesauce, and in many ways the mother of modern JavaScript libraries. I still prefer the syntax over many of the newer libraries. These newer libs have their own advantages, of course, mainly size and modularity. But sometimes I do long for the good old times.
Want to learn how to master JavaScript? Grab a seat at the JavaScript Master Class, a two half-day live online class with Amy Hoy and yours truly! (Next date: June 14/15, 2012!)
These days (actually more like for the last five years), when you’re designing a site and have preview thumbnails/photos/screenshots of things, you’re probably using one of the millions of light box scripts/plugins out there. Light boxes are the new funny mouse trails.
Chances are you’re completely breaking your sites for mobile users.
If you don’t have a mobile site
In case you’re serving the same site to both desktop and mobile users (which for most sites is preferable anyway, Apple does it!), use a light box script that calculates the “center of screen” position once when you open the image. Make sure the button to close the zoomed-in image is always visible.
Don’t use any scripts that recalculate the position on scrolling or window size changes. Users on mobile devices will hate you for it. A lot.
In general, don’t try to be too clever.
If you have a mobile site
The trick is to link to the bigger version of the image directly.
Why? First off, it loads really fast, as only the image has to be transferred and you won’t need any JavaScript at all. Secondly, the user can use gestures to zoom in on the image and by default it’s shown as full-screen as possible. Afterwards the user can just hit the back button to go back to your main content. There’s no need to implement fancy zoom scripts and complicated UI controls; the user already knows how to zoom images on the device.
Zappos does it, so you can too.
Addtionally, don’t bother having “retina” versions and “normal” versions. Just provide one single hi-res image.
It’s better to spend your time on seeing what level of JPEG compression works best for the image you use (if you’re curious, Zappos uses 92 for this particular image—one way to find out is to use identify -verbose filename.jpg | grep "Quality" if you have ImageMagick installed).
Plus, have good toolchain to minimize your images without quality loss, I can’t recommend the ImageOptim tool highly enough for that. I was able to shave off a cool 6% of the file size of the image used on Zappos. Your users will love you for the faster loading images!
Want to learn how to master JavaScript? Grab a seat at the JavaScript Master Class, a two half-day live online class with Amy Hoy and yours truly! (Next date: June 14/15, 2012!)
The aerogel-weight mobile JavaScript framework, which also works great for Safari and Chrome extensions. The jQuery-compatible API makes it easy to pick up, and it's just 5k to 7k in size!