Iestyn Williams is an engineer, designer, and coffee snob living and working in London.

iamthefold: The Data

The exposure to a tiny project I built over a hungover1 weekend has been amazing, humbling, and frankly scary at times. The response to the site has been nothing short of awesome, and it’s been great to see so much discussion about The Dreaded Fold in 2015.

I was originally just going to let the data speak for itself — leaving the site as the only view — but since there is now so much data, it would be a shame to not take the opportunity to produce some more in-depth results.

In maybe a week or so I’ll publish a far-lengthier post all about why and how I built the project, including all the mistakes I made and how it’s changed my perspective for future projects. If you think that might interest you, I suggest you follow me on twitter for updates. For this post though, I’m just going to present the data and some conclusions we can draw from it.


Although I will go into averages, uniques and some other numbers that might seem like things to design around, here’s some sage advice: do not design with a specific device or viewport size in mind, and remember the best thing about the web is it’s inclusiveness.

On the accuracy of the data

The values were obtained by grabbing the visitor’s window.innerHeight (the browser’s viewport height, excluding toolbars, window chrome etc). This does not take into account the zoom of the browser or any other extraneous variables. Each fold value (the line drawn) was recorded once per visitor2.

The basics

The data shown was collected between Monday 9th Feb at 12:223 and Sunday 15th Feb 14:15.

Unique values against total count

As you can see there’s a good spread of values across the board. There are a few values above ~2000 (invisible on the graph) that only crop up once or twice, with the max value being 5120.

Values that appear more than 3 times

Removing values that appear fewer than 3 times, you can see a clearer picture on where the most common fold values lie. As you can see, there is no obvious distribution here, but there are a few lines that occur more frequently than others.

Values that appear more than 300 times

I imagine the most common values must map to some specific devices. From some quick personal testing:

The best thing about this graph is that even when cutting down the values to show only the most common folds, there’s still a huge disparity between the largest and smallest.


“The Fold” is, and has always been, a thing on the web. Content above the fold constitutes the first thing a visitor views on your website, so of course it’s important! If you’re creating web pages these days, you’d be crazy not to take it into account.

However, this experiment has made it abundantly clear that there is no single fold (not that we in the web-design community were under any illusions that it was any other way). I hope more than anything that this tool can be used to educate those who aren’t aware of this fact, and help to show how fluid, disparate, and messy the web really is.


The data used for this post is available here. Feel free to do what you want with it (but if you build something cool with it, let me know!).

I’ll be updating it from time-to-time with data from iamthefold.

Issues viewing this post? Questions comments? Hit me up on twitter or open a PR on github

  1. The morning after the first match of the 2015 Rugby Six Nations: Wales vs. England

  2. I’ll go into detail how I enforced that in a follow-up technical post.

  3. Although the site launched on the day before, there was some abuse of the endpoint which meant I had to scrub the data.

Buttery Scroll

I couldn’t find a simple JavaScript library for smoothly scrolling up and down on a page, so I made one:

See the Pen VYpXJy by Iestyn Williams (@iest) on CodePen.

It’s 814 bytes unminified.

Source code here or grab it from npm: npm install buttery-scroll.

Icons for the web in 2014

Going for vector-based icons on the web is a no-brainer these days, but there are a few different ways you can implement them.

After joining Busuu at the end of March, one of the first things I set about doing was moving the product away from using a PNG-based sprite sheet, and toward a vector-based approach.

Previously, I’ve made heavy use of icon fonts to get the job done (especially the appropriately named Font Awesome), but building your own icon font can be pretty tedious. Most font software is super clunky and complex, and there’s an alternative that’s a lot more flexible for the modern web: SVG.

Chris Coyer over at CSS-tricks has written a bunch of awesome articles on using SVGs, as well as why they’re a better alternative than using icon fonts.

tl;dr — because they’re real elements, you don’t have to worry about font-specific CSS issues (line-height etc); a single icon can have different coloured/styled parts; you don’t get weird anti-aliasing issues… In short, icon fonts feel like a bit of a hack in comparison.

So, now we know SVG is better, what next?

Step 1: Creating SVGs

Any reasonable vector-based graphics package can export as SVG. I’ll show you how to do it with Sketch and Illustrator, just in case.


Exporting from sketch into usable SVG couldn’t be easier. Draw your shapes, wrap them in an art board, then hit export. Select SVG, and you’re good to go.

Sketch export


Pretty much the same deal as Sketch, except with a little more complication. Draw your icon and create an artboard around the icon, but then you’ll need to either Save As... or Save a Copy — you can’t simply “Export” SVG for some weird reason. Make sure you tick Use Artboards and select SVG. Then make sure the export settings are set to add as little cruft as possible. Finally, you’re good to go.

Illustrator export

Step 2: Getting your icons rendering

There’s a few different ways to get your icons to render in a browser:

img tags

<img src="path/to/svg.svg">

You can add your SVG to your page via an img tag, setting the src attribute to be your icon’s path. Nice and simple. You get the power of vector (so high-res screen-ready), but you don’t get the real power of SVG yet.

Copy and Paste

  <rect class="logo" fill="#D8D8D8" x="0" y="0" width="100" height="100"></rect>

SVG is just XML — so open an icon with your text editor of choice, and copy-paste the code into your HTML. Now you can style your icon using just CSS:

See the Pen IzBGq by Iestyn Williams (@iest) on CodePen.


<svg style="display: none;">
  <symbol id="logo">
    <rect fill="#D8D8D8" x="0" y="0" width="100" height="100"></rect>

<svg> <!-- anywhere you want, even multiple places -->
  <use xlink:href="logo">

If you define your icons as symbols inside the SVG, you can reuse them inside your document at any point with a use tag:

See the Pen xcGIC by Iestyn Williams (@iest) on CodePen.

There is a very similar method where you place the icons inside a defs tag on the SVG. The main difference is the pesky viewBox attribute, which you have to add to each use element when using with the defs method, which you don’t have to do when using the symbol method.

This allows for way more flexibility than pasting long SVG code everywhere. All you have to do is make sure that the main SVG file is included on every page you want the icons to appear. Apparently the best place to put them is just after the opening body tag, but it seems to work anywhere in my experience.

If you look at the stylus tab on the second example above, you’ll see that I’ve tried to make one of the icons fill with blue, but because of the fill="red" attribute on the path element of the SVG definition itself, I can’t override it. So, we need to remove those fills if we want to be able to style our icons using just CSS.

But stripping these out manually from possibly hundreds of icons is no way to spend your day. Combining a bunch of individual icons into a single SVG symbol sheet is pretty tedious too.

For just a handful of icons this manual editing is manageable, but for larger sets where you’re continually iterating, you really need the power of automation.

Step 3: automating your workflow

Both sketch and illustrator allow for the mass-export of artboards, so we’ll use that feature to get all our icons into a folder to get us started.

The next step is to optimise your SVGs, not only stripping out fill tags, but also any extra crap your graphics package has left in there.

The best tool for this job is SVGO, an SVG Optimiser. It’s a really great tool, and has multiple interfaces. We use gulp as our build system at busuu, so we use a combination of gulp-svg-symbols and gulp-svgmin, a gulp wrapper for SVGO. There seems to be a slick GUI version of SVGO as well — worth checking out if you don’t want to get your hands dirty with javascript.

Using with gulp

Using gulp to build your SVG sprite sheet is pretty straightforward. Here’s our gulp task freshly ripped out of our gulpfile:

gulp.task('sprites', function() {
  return gulp.src('./app/images/icons/icon_*.svg')

This task will find all the icons with name “icon_something” (which are our art board names in Sketch) inside the icons folder, then pipe them through the svgmin and svgSymbols tasks. svgmin is the SVGO wrapper, so that’ll strip out all the crap and return a pristine SVG for the svgSymbols task, which will compress all the icons into a single SVG file and plonk it back in the icons folder.

Because we also use jade at Busuu, we can really easily inject the SVG directly into all our pages on the site, using a simple include statement.

Wrapping up

Hopefully I’ve shown you how easy it is to get SVG icons working on the web. They’re easy to export, and perfect for building a reusable set of icons with. Once you get your head around the use syntax and how the symbol method works, they’re super easy to work with.

Browser compatibility is great if you don’t need to support IE8. If you are that unlucky however, there are some great build tools to create PNG versions of your SVGs. Obviously this does cut down heavily on functionality (and colouring them would be a pain), but if you’re heavily relying on iconography in your project, then it’ll be worth it.

If you have any feedback, questions, or comments, hit me up on twitter!

Progressive Enhancement: Raising the bar

Progressive enhancement has become a bit of a catch-all term these days (like responsive web design), but it’s original definition was as an alternative to graceful degradation.

In older days, web builders would focus on building for the most advanced/capable browsers first, allowing web pages to degrade in functionality on older/less capable browsers. However, this often meant that the basic content of a site wasn’t even accessible on those older browsers.

In real terms, progressive enhancement works in the opposite way: start with the content, then build layers of enhancement on top. The end result is that any browser can access the basic content, whilst the more capable browsers have a more enhanced (and probably better) user experience.

In the last few years however, browsers have become more and more powerful. This power has allowed us web builders to create increasingly complex client-side apps that can compete with the user experience of native applications, whilst still being platform-agnostic.

Now, when I think about the best software in the world, I think about native iOS apps like Clear, Tweetbot, and Mailbox. The developers of these apps are able to create great user experiences because they know the environment the software will run in. There’s no concept of styles being disabled, or javascript not being available. The apps are already downloaded and installed, ready to go. The minimum barrier to entry is an iOS device from the last 3 years.

There’s no concept of progressive enhancement on these native platforms because the minimum level of functionality required for an app to work is the same for all devices.

On the web, we don’t have that luxury. We can’t assume what environment a web site or app will be accessed. But that doesn’t mean we don’t have a minimum barrier to entry. We do, even if it’s usually the ability to render HTML properly.

So, progressive enhancment is all about ensuring that the barrier to entry is as low as possible. But what if you’re building something that just can’t be done with plain old HTML?

You’re going to have to raise that barrier to entry. And you know what? That’s fine.

If you’re building a site that can’t perform it’s function without CSS (like Google Web Fonts, or Typekit), that’s fine.

If you’re building an app that can’t function without javascript (like Codepen, or Google Drive), that’s fine too.

If we never raised that bar, then the web would never move forward.

Why Stylus is my favourite CSS preprocessor

The first CSS preprocessor I used was Less. It was drier than sass, and once they had in-line @media query support, I didn’t think it could get much better.

Then I found stylus. Imagine all the best bits out of less & sass (mixins, variables, colour manipulation), but now with a touch of javascript (functions, conditionals, interpolation, iteration…). What you have is an incredibly flexible language to write better, cleaner outputted CSS, and be able to write it faster.

Another awesome thing about stylus is that because it’s indentation based, it doesn’t care if you use colons and semi colons. In a recent project I wrote every line as dry as possible, i.e.

    position relative
    float right
    overflow hidden

Vendor prefixes

One of the biggest pain points of writing CSS is getting the vendor prefixes right. Even though we just recently lost a rendering engine, if you want any hope of browser backwards-compatibility, you gotta have prefixes. Here’s a stylus function to output vendor prefixes easily:

vendors = o, moz, webkit, official
vendor(property, value)
  for vendor in vendors
    if vendor == official
      {property} value
      -{vendor}- {property} value

Now, in more detail…

vendors = o, moz, webkit, official

Here I’m defining vendors as an array, with all the vendors in it.

vendor(property, value)

Here we’re just defining a function called vendor, and we’re passing it the property we want to vendor-ify, property, and the value we want it set to, value.

for vendor in vendors

vendors is the above array. This line iterates through the vendors.

 if vendor == official
      {property} value

Inside the for loop, check if the vendor is official, if it is, we don’t want any browser prefixes, so we just want the property and value.

    -{vendor}- {property} value

If the vendor we get is not official, add dashes each side of the vendor variable, then the property and value.

Now, if we want some vendor prefixes, we can simply call:

vendor(border-radius, 4px)


-o-border-radius: 4px;
-moz-border-radius: 4px;
-ms-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;

Pretty sweet.

Transparent mixins

Transparent mixins allow you to redefine a CSS property as a function.

Read that last bit again.

Now let me show you a real-world example.

border-radius is one of the properties we typically want to add vendor prefixes to. What we can do is redefine it to use our vendor function from earlier…

    vendor(border-radius, arguments)

// Use `arguments` like you can in javascript to get the arguments given to the function.

Then whenever you want to use border radius in your stylesheet, it’s pretty simple:

border-radius: 5px

Just like using the specc’d syntax.

This outputs:

-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-o-border-radius: 5px;
-ms-border-radius: 5px;
border-radius: 5px;

Just like you’d expect!

Convinced yet?

You should be!

Just imagine the possibilities of transparent mixins. You can check if a background-color or colour you’ve set has an alpha channel, and if it does, output a solid-colour fallback for older browsers:

    if arguments == transparent
       background-color transparent
    else if alpha(arguments) != 1
        background-color rgb(arguments)
        background-color rgba(arguments)  
        background-color arguments
    if arguments == transparent
       color transparent
    else if alpha(arguments) != 1
        color rgb(arguments)
        color rgba(arguments)
        color arguments

Easily perform transforms and transitions with full vendor-prefix action:

  vendor(transform, arguments)

transition(what = all, duration = 200ms, timing = ease)
    vendor(transition, what duration ease)

Seriously, go and give stylus a try online.

This artcile been useful? Reasonable? Crap? Let me know what you think of this article on twitter.