Thomas Fuchs
Hi, I'm Thomas Fuchs. I'm the author of Zepto.js, of script.aculo.us, and I'm a Ruby on Rails core alumnus. With Amy Hoy I'm building cheerful software, like Freckle Time Tracking and Every Time Zone and write books like Retinafy.me.
   Want me to speak at your conference? Contact me!

Thanks to Retinafy.me readers, $1,044 go to kids in Ferguson!

December 2nd, 2014

Last Tuesday, I’ve started a little Thanksgiving charity drive to get some money together for kids in Ferguson. I couldn’t be happier that I’ve sold $1,044 worth of my book Retinafy.me with 100% of this going to Donors Choose projects in Ferguson, MO. (I’m coming up for the payment processor fees out of my own pocket, so all the $1,044 go directly to the kids!)

My wife and I are big proponents of supporting literacy—it’s the foundation on which all education, learning and communication with people that you can’t directly talk to is based. If you don’t start to read at an early age, chances are that you never get into it.

Unfortunately as a society we seem more obsessed about hate and fear than supporting those who can’t help themselves. Children are at the receiving end of racism and institutionalized blaming and shaming of minorities. No money for education but buying tanks for the police is just one of the many symptoms of this.

While it’s only a small gesture, we have to start somewhere. Consider regularly giving money and/or supporting local kids. There’s more that you can do than you can think of.

Here’s the projects fully or partially funded with the Retinafy.me purchases:

In the interest of transparency, here’s 1) the Proof of donating to Donors Choose and 2) an anonymized CSV tally of all sales from Tuesday, November 25, up to Monday, December 1.

Thanks again!

Get retinafied and support kids in need!

November 30th, 2014

Up to and including Monday December 1, 100% of sales of my Retina Web ebook will go to Donors Choose projects in Ferguson, MO.

ferguson

These kids need our help! Thank you!

Get your copy now!

Why and how I ditched icon fonts in favor of inline SVG

October 31st, 2014

Webfonts are the new hotness, and icon fonts even more so. There’s plenty to choose from, and Google just released an icon font that’s based on the new Android L. Icon nirvana reached?

Not really. Icon fonts have a few nasty problems that icon font makers rarely make you aware of. Here’s a few of these problems:

If you serve icons from a service, that services might randomly go down. I’ve seen this over and over again with big and small websites.

You can’t easily edit icons, and it’s hard to see what’s been updated in source code control. Webfont files are for the most part binary and changing one icon normally means the whole resulting font file is different.

There’s blurry rendering on certain browsers. Some CSS properties have to be abused (like -webkit-font-smoothing: antialiased;) to make the icons look good. This doesn’t work in some browsers and in some browser versions.

Most importantly, when icons are in the same CSS block, or when centered in an odd-width container, you get off by half-a-pixel blurryness, which can’t be corrected. This happens on all browsers, even on the latest and greatest Firefox, Chrome and Safari (even though Safari is doing better than IE, Firefox and Chrome, I’ve seen it happen on Safari as well).

Here’s some screenshots from GitHub on IE 10, showing this issue (it also happens with other browsers, like Chrome):

ie10

In Freckle Time Tracking we had a clever setup with SVG source files (on a precise 16×16 grid) and using fontcustom to compile fonts and doing some post-processing of the generated CSS with sed (most to remove unwanted font variants, as you only need woff in recent-ish browsers).

We also required to add some special headers when serving these font files so that our CDN (Amazon CloudFront) would correctly serve them.

All of this worked, but… blurryness alarm!

Even-width container:
Screen Shot 2014-10-09 at 9.05.28 PM

Odd-width container:
Screen Shot 2014-10-09 at 9.05.20 PM

Back to square one

Let’s take a step back and ask—what do you need from an icon? Why do icon fonts appear to be a good solution? And how can the problems be fixed?

  1. Icons need to be rendered pristinely and in focus.
  2. They should ideally be rendered the same or nearly the same on all browsers you support.
  3. You should be able to change the color and ideally other (CSS) properties.
  4. The same icon should look great on normal and retina screens; ideally you can substitute a different version for retina if you so fancy.
  5. It would be great if the files are text, so they work great with source code management. (Did you know that GitHub does graphical SVG diffs?)

Inline SVG to the rescue…

Here’s our current workflow:

  • We’ve a bunch of SVG files in a folder, which are our icons. All of them are on a 16×16 pixel grid.
  • There’s shell script that optimizes the SVG, and then generates a Rails helper and a JavaScript helper, as well as copies the optimized SVG files into /public/images:
    #!/bin/sh
    # This requires "imagemin", install via:
    # npm install --global imagemin
     
    echo "Cleaning up..."
    rm -rf build
    mkdir build
     
    echo "Optimizing SVG..."
    imagemin *.svg ../public/images/icons
     
    ruby ./generate_helper.rb
    
  • For the optimization, we use imagemin, which will remove unnecessary stuff from the source SVG files (these are all saved in Adobe Illustrator, which likes to be on the verbose side when it comes to saving SVG).
  • There’s a Ruby script that reads the optimized SVG files one by one and generates a Rails helper file with icon_xxxxx methods. These methods can be called from any view to insert the desired icon as inline SVG:
    #!/usr/bin/env ruby
    require 'json'
     
    FILENAME = "../app/helpers/icon_helper.rb"
    JAVASCRIPT_HELPER = "../public/js/icons/icons.js"
     
    puts "Generating helper #{FILENAME}"
    File.open(FILENAME, 'w') do |helper|
      helper.write "module IconHelper\n\n"
     
      Dir.glob(File.join("..","public","images","icons","*.svg")).each do |icon|
        svg = File.read(icon).delete("\n").delete("\r").delete("\t")
        name = icon.split('/').last.tr('-','_').gsub(/\.svg$/,'')
        puts "#{name}: #{svg.size} bytes"
     
        helper.write "  def icon_#{name}\n"
        helper.write "    '#{svg}'\n"
        helper.write "  end\n\n"
      end
     
      helper.write "end"
    end
     
    puts "Generating JavaScript helper"
    File.open(JAVASCRIPT_HELPER, 'w') do |helper|
      Dir.glob(File.join("..","public","images","icons","*.svg")).each do |icon|
        svg = File.read(icon).delete("\n").delete("\r").delete("\t")
        name = icon.split('/').last.tr('-','_').gsub(/\.svg$/,'')
        
        # we only need a few specific icons in JavaScript, so skip those we don't want
        next unless name =~ /^cursor/ || name =~ /^arrow_right/
        
        puts "(JavaScript) #{name}: #{svg.size} bytes"
     
        helper.write "window.__icon_#{name} = #{svg.to_json};\n"
      end
    end
    

    Calling on icon_xxxx generates inline SVG as shown below:
    Screen Shot 2014-10-31 at 12.30.37 PM

  • The Ruby script also generates a JavaScript helper file that’s similar. We only include icons in it that we need from the few places we generate HTML in JavaScript, like our calendar widget.
  • Last but not least, the optimized files are copied into /public/images so you can use
    them for special cases when you don’t want inline SVG but a normal image tag or a background image.
  • To set the color of an icon in CSS, just add a fill: #abcdef; CSS property.

Boom—problem solved. This works great on all browsers, and you don’t get any of the rendering issues that you have with icon fonts.

Actually there’s several unexpected advantages:

  • It’s easier to use icons if you inject JavaScript into 3rd-party websites. We use this for the pink support widget that’s on the bottom right of Freckle’s landing page.
  • If you want to do more advanced animations, like morphing an icon into an other icon, it’s pretty easy to do as you can manipulate inline SVG easily with JavaScript (and you can use CSS animations as well!)
  • When you copy+paste text, the SVG is ignored so you don’t get weird extra characters in the pasted text.
  • There’s no weird “flash of unstyled text”, neither is there empty spaces that are only rendered when an icon font was fully loaded.

The only downside is perhaps that your HTML will be slightly larger than it would be with an icon font, which might result in slighter longer loading and rendering times. This is offset by not having to load an icon font in the first place, however, and in my tests has not been a problem at all. A possible way to reduce the HTML size is to set data-icon attributes on elements and have JavaScript insert the inline SVG (I’d say you’re probably better off with directly rendering tho, as running JavaScript isn’t “free” either).

Enjoy the SVG goodness!

What to do when Stack Overflow is down?

May 16th, 2014

The Internet is awesome. Information at your fingertips and always-available help from people all over the world is one of humanity’s dreams come true. I’m not sure if the ancient philosophers included copy & pasting of code snippets in this dream, but it’s a fact of daily developer life.

It’s awesome, and it’s very convenient.

But this is not how you learn and become great at thinking for yourself, finding solutions for solving programming problems and most importantly how to be creative. Over-using sites like Stack Overflow will not make you a better developer, it will only make you very good at clicking up-vote buttons and copy & pasting.

You owe it to your brain and future self that you try to find a solution first, and not give up just because something doesn’t work the first time you try it. Especially when you don’t feel comfortable or knowledgeable, because you’re working on a new project, with a new programming language or different development environment. Humans are built for exploration and understanding by doing. Your brain will reward you for discovering things. The rewards are higher as the problem is harder (for you) to solve.

That doesn’t mean to ban forums and answer sites from your bookmarks. You can and should share your discoveries and see how others solved similar problems. You’ll probably find that there’s (hope my cats won’t hear this) more than one way to skin a cat. Sharing will likely lead to new, better ways to tackle a specific problem, and this will benefit lots of people.

All because you spent 10 minutes thinking about a problem and not just copy & pasting the first answer that somewhat works.

What do you need to make a successful web app?

April 13th, 2014

Here’s some things you need to make a successful web app:

  • A plan to make an application that helps real people to make their lives easier, solving a well-researched problem
  • Understand human psychology
  • Know how to design, both in terms of UX flow and visual design
  • A marketing plan, to tell potential customers that your app solves their problem
  • A text editor
  • A web server
  • Probably some sort of database
  • A payment processor of sorts
  • Good security (including well-tested backups) from the start
  • A (at least basic) understanding of tax laws in your country
  • A healthy dose of perseverance

And here’s some things you don’t need:

  • The latest alpha of hype.js
  • CSS frameworks
  • Boilerplates
  • reset.css
  • JavaScript loaders
  • The newest NoNoNoSQL database
  • Distributed anything
  • That cool new jQuery plugin
  • A custom-designed font
  • Multiple load-balanced “webscale” servers

All these things create the illusion of making things easier when in reality they create very complex dependencies and will be very hard to remove later if they don’t turn out to be the silver bullets they promise to be. This doesn’t mean these things are bad or evil. You may want some of them later, when your app grows.

Remember, keep it simple and don’t over-engineer. Solve the problems at hand, and don’t anticipate “potential” problems.

You need to wear many hats when setting out to make a successful web application: entrepreneur, psychologist, designer, programmer, marketer, accountant—but you’re not a fortune teller.

Heartbleed exploit tl;dr

April 8th, 2014

OpenSSL had a bug for several years which allowed attackers to untraceably read all your SSL traffic and some server memory.

If you’re like me and have better things to do than reinvent the fix-wheel and you’re all like “WTFBBQ TL;DR” here’s the absolute minimum what anyone who runs a web server with SSL must do.

NO, NONE OF THESE STEPS ARE OPTIONAL.

  • Update OpenSSL to 1.0.1g. This is required before you do anything else.
  • Recompile anything that’s statically linked against OpenSSL. In many instances, web server software like Nginx is statically linked and must be recompiled. For example, if your Ruby is statically linked to OpenSSL, it’s recompile time!
  • Reboot the server. This must be done before issuing new certificates.
  • Create a new private key and CSR and get a new SSL certificate. You will need to revoke the old SSL certificate. (If you’re on Godaddy, use their “rekey” function. The old cert will be revoked automatically after 72 hours). Don’t forget to install your new cert.
  • Change any server passwords. These may have been read by an attacker as they are in server memory. It’s not a bad idea to issue new server SSH hostkeys as well.
  • Change any and all passwords and tokens of APIs you use. As server memory may have been compromised, an attacker could access the APIs as if they where you. Not good.
  • If you’re using cookie-based sessions in Rails (or similar environments) you must switch to a new encryption secret. Your current secret may have been compromised, allowing attackers to log in as anyone to your service. Unfortunately this means all your users will have to log in again.
  • Ask your users to change their passwords. As this security issue means that server memory may have been compromised as well as past traffic could be decrypted, passwords should be considered to be compromised.

Whew.

There’s an optional step, which I highly recommend while you’re at it—get your SSL configuration into shape and enable PFS and HSTS (and test it!). It just takes a minute if you’re on Nginx.

If you have anything to add, please email me directly and I’ll update this post.

How to get an A+ on the Qualsys SSL Labs test

April 4th, 2014

Recently we upgraded our server infrastructure for Freckle Time Tracking and in the process wanted to improve how we serve SSL.

If you don’t know much about this, it’s fine—there’s a few simple steps you can take to make your website more secure and faster loading in the process. _Important: of course, there’s no absolute security, and I make no claim that what I describe here is secure and will work for you. Use it at your own risk._

Long story short, you’ll want to get an A+ rating on the Qualsys SSL Labs test.

For that you’ll need to do the following:

  • Don’t support older protocols. A lot of servers support really old and obsolete protocols. If you run a web app, your users will very likely not need support for these.
  • Don’t support flawed SSL ciphers. There’s a bunch of these and you can avoid using them. Browsers support multiple different ciphers, so this is not a problem.
  • Cache SSL sessions. This will improve performance.
  • Turn on HTTP Strict Transport Security (HSTS). This is a special header that will tell browsers to never connect to the server via normal HTTP.

And that’s it. In order so you don’t need to research the proper settings, here’s how this looks like in form of an nginx configuration:

server {
  # deferred allows for faster connections if there's
  # no other servers on port 443 defined
  listen 443 ssl spdy deferred;

  ssl on;
  ssl_certificate /etc/nginx/your-certificate.crt;
  ssl_certificate_key /etc/nginx/your-private-key.key;

  ssl_prefer_server_ciphers on;
  ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS:!AES256;
  ssl_session_cache shared:SSL:10m;
  ssl_session_timeout 10m;
  ssl_stapling on;

  # tell any upstream things like unicorns that we're on https
  proxy_set_header X-Forwarded-Proto 'https';
  underscores_in_headers on;

  location / {
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
    # ...
  }

  # ...
}

And that’s it. Have fun with your new A+ rating on the SSL labs test.

Our Internet

March 30th, 2014

Our Internet isn’t big corporations doing whatever they want. Our Internet is not DRM, is not SOPA and not PIPA and not the spying on us (and everyone else). Our Internet isn’t bigots taking away human rights from people. Our Internet isn’t hiding behind PR releases.

Our Internet isn’t greed, narcissism, fear and blind hate.

Our Internet is people helping each other be excellent. It’s sharing, caring and being proud of what we humans can do if we only put our will to it. It’s about helping the unprivileged when governments fail. Our Internet is about standing up to your mistakes.

Our Internet is about love and empathy.

The only thing we have is each other.

That is all.

Scrolling DOM elements to the top, a Zepto plugin

January 19th, 2014

There’s bunches of plugins, extensions and techniques to smoothly scroll page elements, but most of them are convoluted messes and probably do more than you need. I like “small and works well”, and it’s a good exercise for those JavaScript and DOM muscles to write a small plugin from time to time.

My goal was to have an animated “scroll to top” for the mobile version of Freckle—normally the browser would take care of that (tap status bar to scroll to top), but in a more complex layout the built-in mechanisms for this quickly fail and you’ll have to implement some of the interactions users expect (like tap status bar to scroll to top) yourself. Specifically, this is for the native app wrapper (Cordova) I use for Freckle’s upcoming mobile app. It’s hooked up so that taps on the statusbar invoke a JavaScript method.

During development of this I needed the same thing for arbitrary scroll positions as well, so “scrolltotop” is a bit of a misnomer now. Anyway, here’s the annotated code:

Often, writing your own specialized plug-in is faster than trying to understand and configure existing code. If you do, share it! :)

Let it snow with Zepto—again!

December 24th, 2013

Updated with the latest and greatest Zepto.js… Let it snow!

If you’re interested how this works, grab the source. Except for Zepto.js (built with detect & fx support) there’s no external dependencies (not counting the Twitter and analytics).

Happy Holidays!

P.S. Because it was so popular, I’ve started another flash sale of my ebook Retinafy your web sites and app—use coupon “hiresholidays” for 15% off, but only on December 24th and 25th!