I Used The Web For A Day With JavaScript Turned Off

dreamt up by webguru in Uncategorized | Comments Off on I Used The Web For A Day With JavaScript Turned Off

I Used The Web For A Day With JavaScript Turned Off

I Used The Web For A Day With JavaScript Turned Off

Chris Ashton

This article is part of a series in which I attempt to use the web under various constraints, representing a given demographic of user. I hope to raise the profile of difficulties faced by real people, which are avoidable if we design and develop in a way that is sympathetic to their needs. This week, I’m disabling JavaScript.

Why noscript Matters

Firstly, to clarify, there’s a difference between supporting a noscript experience and using the noscript tag. I don’t generally like the noscript tag, as it fragments your web page into JavaScript and non-JavaScript versions rather than working from the same baseline of content, which is how experiences get messy and things get overlooked.

You may have lots of useful content inside your noscript tags, but if I’m using a JavaScript-enabled browser, I’m not going to see any of that — I’m going to be stuck waiting for the JS experience to download. When I refer to the ‘noscript’ experience, I generally mean the experience of using the web page without JavaScript, rather than the explicit use of the tag.

Web MIDI API: Getting Started

Is it possible to use digital musical instruments as browser inputs? With the Web MIDI API, the answer is yes! The best part is, it’s fairly quick and easy to implement and even create a really fun project. Read article →

So, who cares about users who don’t have JavaScript? Do such noscript users even exist anymore?

Well, they do exist, albeit in small numbers: roughly 0.2% of users in the UK have JavaScript disabled. But looking at the numbers of users who have explicitly disabled JavaScript is missing the point.

I’m reminded of this quote by Jake Archibald:

“All your users are non-JS while they’re downloading your JS.”

Think of those users who have JavaScript enabled but who don’t get the JavaScript experience, for any number of reasons, including corporate or local blocking or stripping of JavaScript elements, existing JavaScript errors in the browser from browser add-ons and toolbars, network errors, and so on. BuzzFeed recently revealed that around 1% of requests for their JavaScript time out, equating to 13 million failed requests per month.

Sometimes the issue isn’t with the user but with the CDN delivering the JavaScript. Remember in February 2017 when Amazon’s servers went down? Millions of sites that rely on JavaScript delivered over Amazon’s CDNs were in major trouble, costing companies in the S&P 500 index $150 million in the four-hour outage.

Think also of the emerging global markets; countries still battling to build a network of fast internet, with populations unable to afford fast hardware to run CPU-intensive JavaScript. Or think of the established markets, where even an iPhone X on a 4G connection is not immune to the effects of a partially loaded webpage interrupted by their train going into a tunnel.

The web is a hostile, unpredictable environment, which is why many developers follow the principle of progressive enhancement to build their sites up from a core experience of semantic HTML, layering CSS and unobtrusive JavaScript on top of that. I wanted to see how many sites apply this in practice. What better way than disabling JavaScript altogether?

How To Disable JavaScript

If you’d like to recreate my experiment for yourself, you can disable JavaScript by digging into the settings in Chrome:

  • Open the Developer Tools (Chrome -> View -> Developer Tools, or ⌥⌘I on the keyboard)
  • Open the developer submenu (the three dots next to the close icon on the Developer Tools)
  • Choose ‘Settings’ from this submenu
  • Find the ‘Debugger’ section and check the ‘Disable JavaScript’ box

Or, like me, you can use the excellent Toggle JavaScript Chrome Extension which lets you disable JS in one click.

Creating A WordPress Post With JavaScript Disabled

After disabling JavaScript, my first port of call was to go to my personal portfolio site — which runs on WordPress — with the aim of writing down my experiences in real time.

WordPress is actually very noscript-friendly, so I was able to start writing this post without any difficulty, although it was missing some of the text formatting and media embedding features I’m used to.

Let’s compare WordPress’ post screen with and without JavaScript:

The Noscript version of WordPress’ post page, which is made up of two basic text inputs.
The noscript version of WordPress’ post page, which is made up of two basic text inputs.

The JavaScript version contains shortcuts for formatting text, embedding quotes and media, and previewing the content as HTML.
The JavaScript version contains shortcuts for formatting text, embedding quotes and media, and previewing the content as HTML.

I felt quite comfortable without the toolbars until I needed to embed screenshots in my post. Without the ‘Add Media’ button, I had to go to separate screens to upload my files. This makes sense, as ‘background uploading’ content requires Ajax, which requires JavaScript. But I was quite surprised that the separate media screen also required JavaScript!

Luckily, there was a fallback view:

WordPress media grid view (requires JS)
The noscript version of the Media section in the admin backend. I was warned that the grid view was not supported without JavaScript.

WordPress media list view (fallback)
Who needs grids anyway? The list view was perfectly fine for my needs.

After uploading the image, I had to manually write an HTML img tag in my post and copy and paste the image URL into it. There was no way of determining the thumbnail URL of the uploaded image, and any captions I wrote also had to be manually copied. I soon got fed up of this approach and planned to come back the next day and re-insert all of the images when I allowed myself to use JavaScript again.

I decided to take a look at how the front-end of my site was doing.

Viewing My Site Without JavaScript

I was pleasantly surprised that my site looked largely the same without JS:

With JavaScript
Personal site with JavaScript.

Without JavaScript
Personal site without JavaScript. Only the Twitter embed looks any different.

Let’s take a closer look at that Twitter embed:

Tweet with JavaScript
Note the author information, engagement stats, and information link that we don’t get with the noscript version. The ‘tick’ is an external PNG. (Source)

Tweet without JavaScript
Missing styles, but contains all of the content, including hashtag link and link to tweet. The ‘tick’ is an ASCII character: ✔.

Below the fold of my site, I’ve also embedded some Instagram content, which held up well to the noscript experience.

Instagram embed with JavaScript
Notice the slideshow dots underneath the image, indicating there are more images in the gallery.

Instagram embed without JavaScript
The noJS version doesn’t have such dots. Other than the missing slideshow functionality, this is indistinguishable from the JS version.

Finally, I have a GitHub embed on my site. GitHub doesn’t offer a native embed, so I use the unofficial GitHub Cards by Hsiaoming Yang.

GitHub embed with JavaScript
The unofficial card gives a nice little snapshot and links to your GitHub profile.

GitHub embed without JavaScript
I provide a fallback link to GitHub if no JavaScript is available.

I was half hoping to shock you with the before and after stats (megabytes of JS for a small embed! End of the world! Let’s ditch JavaScript!), and half hoping there’d by very little difference (progressive enhancement! Leading by example! I’m a good developer!).

Let’s compare page weights with and without JavaScript. Firstly, with JavaScript:

Page weight with JavaScript
51 HTTP requests, with 1.9MB transferred.

Now without JavaScript:

Page weight without JavaScript
18 HTTP requests, with 1.3MB transferred.

For the sake of a styled tweet, a GitHub embed and a full-fat Instagram embed, my site grows an extra 600KB. I’ve also got Google analytics tracking and some nerdy hidden interactive features. All things considered, 600KB doesn’t seem over the top — though I am a little surprised by the number of additional requests the browser has to make for all that to happen.

All the content is still there without JavaScript, all the menus are still navigable, and with the exception of the Twitter embed, you’d be hard-pressed to realize that JavaScript is turned off. As a result, my site passes the NOSCRIPT-5 level of validation — the very best non-JavaScript rating possible.

ashton.codes noscript rating: NOSCRIPT-5. ✅

What’s that? You haven’t heard of the noscript classification system? I’d be very surprised if you had because I just made it up. It’s my handy little indicator of a site’s usability without JavaScript, and by extension, it’s a pretty good indicator of how good a site is at progressively enhancing its content.

noscript Classification System

Websites — or more accurately, their individual pages — tend to fall into one of the following categories:

    The site is virtually indistinguishable from the JavaScript-enabled version of the site.
    The site provides functionality parity for noscript, but links to or redirects to a separate version of the site to achieve that.
    Site largely works without JavaScript, but some non-key features are unsupported or look broken.
    The site offers message saying their browser is not supported.
    The site appears to load, but the user is unable to use key functionality at all.
    The site does not load at all and offers no feedback to the user.

Let’s look at some popular sites and see how they score.


I’ve had my eye on a little robotic vacuum cleaner for a while. My lease doesn’t allow any pets, and this is the next best thing once you put some googly eyes on it.

At first glance, Amazon does a cracking job with its non-JavaScript solution, although the main product image is missing.

Amazon without JavaScript
Missing the main image, but unmistakably Amazon.

Amazon with JavaScript
With JavaScript, we get the main image. Look at this lovely little vacuum.

On closer inspection, quite a few things were a bit broken on the noscript version. I’d like to go through them one by one and suggest a solution for each.

I wanted to see some pictures of the products, but clicking on the thumbnails gave me nothing.


I clicked on these thumbnails but nothing happened.

Potential Solution

It would have been nice if these thumbnails were links to the full image, opening in a new tab. They could then be progressively enhanced into the image gallery by using JavaScript:

  • Hijack the click event of the thumbnail link;
  • Grab the href attribute;
  • Update the src attribute of the main image with the href attribute value.

Is this feature really so commonly used that it’s worth downloading extra bytes of JavaScript to all of your users so that it opens as an integrated modal within the page?

Amazon integrated modal window (JavaScript version)


Potential solution
It’s a good thing the product information looked accurate to me, because there was no way I could report any issues! The `href` attribute had a value of javascript://, which opens an integrated modal form

Potential Solution

The Amazon integrated modal form requires JavaScript to work. I would make the ‘report feature’ a standalone form on a separate URL, e.g. /report-product?product-id=123. This could be progressively enhanced into the integrated modal using Ajax to download the HTML separately.

Reviews Are Only Partially Visible By Default


Potential solution
The Read more link does nothing.

Potential Solution

Why not show the whole review by default and then use JavaScript to truncate the review text and add the ‘Read more’ link?

It’s worth pointing out that the review title is a link to the review on a standalone page, so it is at least still possible to read the content.

On the whole, I was actually pleasantly surprised just how well the site worked without JavaScript. It could just as easily have been a blank white page. However, the lack of product images means we’re missing out on a really core feature — I’d argue it’s critical to be able to see what you’re buying! — so it’s a shame we couldn’t put the icing on the cake and award it a NOSCRIPT-5 rating.

Amazon noscript rating: NOSCRIPT-3. 🤷‍

I still hadn’t decided which product I wanted to buy, so I turned to Camel Camel Camel, the Amazon price tracker.

Camel Camel Camel

I wanted to decide between the iLife V3s Pro versus the iLife A4s, so headed over to https://uk.camelcamelcamel.com/. At first, the site looked indistinguishable from the JavaScript-enabled version.

Potential Solution
Camel Camel Camel, looking nice and professional — with no JavaScript.

no JavaScript issue
You could run a git diff on these screenshots and struggle to see the difference!

Unfortunately, the price history chart did not render. It did provide an alt text fallback, but the alt text did not give me any idea of whether or not the price trend has been going up or down.

Noscript version
Alt text says “Amazon price history chart” but provides no insight into the data.

JavaScript version
Look at this lovely chart you get when JavaScript is enabled.

General suggestion: provide meaningful alt text at all times. I don’t necessarily need to see the chart, but I would appreciate a summary of what it contains. Perhaps, in this case, it might be “Amazon price history chart showing that the price of this item has remained largely unchanged since March 2017.” But automatically generating a summary like that is admittedly difficult and prone to anomalies.

Specific suggestion for this use case: show the image. The chart on the scripted version of the site is actually a standalone image, so there’s no reason why it couldn’t be displayed on the noscript version!

Still, the core content below the chart gave me the information I needed to know.

Who needs a chart? We’ve got a table!
Who needs a chart? We’ve got a table!

The table provides the feature parity needed to secure a NOSCRIPT-5 rating. I take my hat off to you, Camel Camel Camel!

Camel Camel Camel noscript rating: NOSCRIPT-5 ✅

Google Products

At this point in my day, I received a phone call out of the blue: A friend phoned me and asked about meeting up this week. So I went to Google Calendar to check my availability. Google had other ideas!

Surprisingly, Google Calendar offers nothing for noscript users.

I was disappointed that there wasn’t a noscript fallback — Google is usually pretty good at this sort of thing.

I wouldn’t expect to necessarily be able to add/edit/delete entries to my calendar, but it should be possible to provide a read-only view of my calendar as core content.

Google calendar noscript rating: NOSCRIPT-0 🔥

Interested in seeing how Google manages other products, I had a quick look at Google Spreadsheets:

Google Spreadsheets shows my spreadsheet but has a big warning message saying “JavaScript isn’t enabled” and won’t let me edit its contents.

In this case, the site fails a lot more gracefully. I can at least read the spreadsheet contents, even if I can’t edit them. Why doesn’t the calendar offer the same fallback solution?

I have no suggestions to improve Google Spreadsheets! It does a good job at informing the user if core functionality is missing from the noscript experience.

Google spreadsheets noscript rating: NOSCRIPT-2 😅

This rating isn’t actually that bad! Not all sites are going to be able to offer a noscript experience, but at least if they’re upfront and honest (i.e. they’ll say “yeah, we’re not going to try to give you anything”) that prepares you — the noscript user — for when it fails. You won’t waste a few precious seconds trying to fill in a form that won’t ever submit, or start reading an article that then has to use Ajax to retrieve the rest of its contents.

Now, back to my potential Amazon purchase. I wanted to look at some third-party reviews before making a purchase.

Google search works really well without JavaScript. It just looks a little dated, like those old desktop-only sites at fixed resolutions.

Noscript version
noscript version has extra search options on the left (otherwise tucked away in settings on the JS version) — and no privacy banner (perhaps because ‘tracking’ is not relevant to noscript users?)

JavaScript version
JavaScript version has the ability to search via voice input, and the ‘privacy reminder’ message.

The images view looks even more different, and I actually prefer it in a few ways — this version loads super quickly and lists the dimensions and image size in kilobytes underneath each thumbnail:

Noscript version
noscript version: notice the image meta information which is not supplied on the scripted version!

JavaScript version
JavaScript version: notice the ‘related search terms’ area which is not supplied on the noscript version.

Google Search noscript rating: NOSCRIPT-5 ✅

One of the search results took me to a review on YouTube. I clicked, not expecting much. I was right not to get excited:

YouTube doesn’t offer much of a noscript experience.

I wouldn’t really expect a site like YouTube to work without JavaScript. YouTube requires advanced streaming capabilities, not to mention that it would open itself up to copy theft if it provided a standalone MP4 download as a fallback. In any case, no site should look broken. I stared at this screen for a few seconds before realizing that nothing else was going to happen.

Suggestion: If your site is not able to provide a fallback solution for noscript users, at a minimum you should provide a noscript warning message.

YouTube noscript rating: NOSCRIPT-0 🔥


I clicked a couple more review links. The Which? advice site failed me completely.

The site says there are 10 good vacuums to choose from, but the list is clearly populated with Ajax or something as I’m seeing nothing.

This was a page that looked like it loaded fine, but only when you read the content would you realize you must actually be missing some key information. That key information is absolutely core to the purpose of the page, and I can’t get it. Therefore, unfortunately, that’s a NOSCRIPT-1 violation.

Suggestion: If your site Ajaxes in content, that content exists at another URL. Provide a link to that content for your noscript users. You can always hide the link when you’ve successfully Ajaxed with JavaScript.

Which? review site noscript rating: NOSCRIPT-1 😫


Eventually, I concede that I can’t really afford a vacuum right now. So, I decided to hop onto social media.

Facebook says JavaScript is required to proceed, or we can click the link to the mobile site.
Facebook says JavaScript is required to proceed, or we can click the link to the mobile site.

Facebook flat-out refuses to load without JavaScript, but it does offer a fallback option. Here’s our first example of a NOSCRIPT-4 — a site which offers a separate version of its content for noscript or feature phone users.

The mobile site version of Facebook.
The mobile site version of Facebook.

The mobile version loads instantly. It looks ugly, but it seems as though I get the same content as I normally would. Crucially, I have feature parity: I can accomplish the same things here as I can on the main site.

Facebook noscript rating: NOSCRIPT-4 🤔

The page loaded at lightning speed:

50.8KB. Page loaded in 1.39 seconds
50.8KB. Page loaded in 1.39 seconds

I could only see 7 items in the news feed at any one time, but I could click to “See More Stories,” which takes me to a new page, using traditional pagination techniques.

I find myself impressed that I have the option to ‘react’ to a Facebook comment, though this is a multi-screen task:

Reacting first requires you to click ‘React’…
Reacting first requires you to click ‘React’…

…which then takes you to a separate screen to choose your reaction.
…which then takes you to a separate screen to choose your reaction.

There’s nothing stopping Facebook building a hover ‘reaction’ menu in non-JavaScript, but to be fair this is aimed at mobile devices that aren’t able to hover.

Suggestion: Get creative with CSS. You may find that you don’t need JavaScript at all.

Before long, a video item came up in my news feed. (At this point, it dawned on me just how much less video content I had seen on the mobile version compared to normal Facebook, meaning I’d actually been seeing peoples’ statuses rather than a random video they ‘liked’ — a major improvement as far as I’m concerned!)

I fully expected the video not to work when I clicked it, but clicking on the thumbnail opened the video in a new tab:

You don’t need JavaScript to play MP4 files
You don’t need JavaScript to play MP4 files.

I’m pleasantly surprised that all of the functionality appears to be there on this noscript version of the site. Eventually, however, I found one feature that was just too clunky and cumbersome to see through to the end: album creation.

I wanted to upload a photo album to Facebook, but in noscript-land this is a beast of a task. It involves uploading one photo at a time, going through two or three screens for each upload. I desperately tried and failed to find a bulk-upload option.

The laboriousness of this got to me after photo number three (my album will contain many more), so I decided to call it a day and come back tomorrow when I’ve got JavaScript.


Things got weird when I flew over to Twitter.

Twitter on first load
On first load, I got what looked like the normal desktop site.

Twitter redirect site
After a couple of seconds, I was automatically redirected to the mobile site.

I was intrigued by this mechanism, so dug into the source code, which was actually surprisingly simple:

<noscript><meta http-equiv="refresh" content="0; URL=https://mobile.twitter.com/i/nojs_router?path=%2F"></noscript>

As beautifully simple as this solution is, I found the experience quite clunky because in the flash before I was redirected, I saw that one of the people I follow on Twitter had got engaged. His tweet didn’t appear at the top of the ‘mobile’ version, so I had to go looking for it.

Suggestion: Build in a grace period into your server-side logic so that redirects and careless refreshes don’t lose interesting tweets before you’ve had a chance to read them.

I couldn’t remember my friend’s Twitter handle. Searching was a little tricky — I started to really miss the autofill suggestions!

A screenshot of me filling in 'andy' as a search term, but no autofill suggestions appearing as I type.
No autofill suggestions appeared as I typed.

Luckily, the search results page brought his account right up, and I was able to find his tweet. I was even able to reply.

Twitter noscript rating: NOSCRIPT-4 🤔

This may seem like a generous score, given the clunky feel, but remember that the key thing here is feature parity. It doesn’t have to look beautiful.

I tried out a couple more social media sites, which, unlike Twitter, didn’t reach the dizzy heights of NOSCRIPT-4 compliance.

Other Social Networks

LinkedIn has a nice, bespoke loading screen. But it never loads, so all I could do was stare at the logo.


LinkedIn noscript rating: NOSCRIPT-0 🔥

Instagram gave me literally nothing. A blank page. A whole other flavor of NOSCRIPT-0.


Instagram noscript rating: NOSCRIPT-0 🔥🔥🔥

I was surprised Instagram failed so spectacularly here, given that the Instagram embed worked flawlessly on my portfolio site. I guess with an embed you never know what the browser support expectations of the third party are, but as I’m visiting the site directly, Instagram is happy making the call to drop support.

BBC News

I headed over to the BBC to get my fix of news.

BBC without JavaScript
In the noscript version, notice the narrow column and the single story with thumbnail.

BBC with JavaScript
JavaScript version: notice the full use of the desktop screen and multiple article thumbnails.

The menu is a little bit off, and the column is quite narrow (definitely a pattern I’m seeing on a lot of sites — why does “no JavaScript” mean “mobile device”?) but I am able to access the content.

I clicked on the ‘Most Read’ tab, which takes me to another part of the page. With scripting, this anchor link is progressively enhanced to achieve actual tab behavior, which is a lovely example of building up from a solid HTML core.


So far, this is the only example of an anchor link I’ve come across in my experiment, which is a shame as it’s a nice technique that saves an additional page load and saves fragmenting the site into lots of micro pages.

It does look a little odd though, the ordered list CSS meaning we have a double numbering glitch here. I click on one of the stories.

The article should contain a video, but instead reads “Media playback is unsupported on your device”. There is no transcript.
The article should contain a video, but instead reads “Media playback is unsupported on your device”. There is no transcript.

I can’t access the video content, but due to rights issues, I suspect the BBC cannot provide a separate standalone video as Facebook does. A transcript would be nice though — and beneficial to more than just noscript users.

Suggestion: Provide textual fallbacks for audio-visual content.

To be fair, the article content basically sums up the content that appears in the video, so I’m not really missing out on information.

The article and index pages load lightning-fast, at about 300KB (mostly images). I do miss the thumbnail images for the other articles on the page, and the ability to make full use of my screen real estate — but that shouldn’t hamper the rating.

BBC noscript rating: NOSCRIPT-5 ✅


GitHub looks almost exactly the same as its JavaScript-enabled counterpart. Wow! But I guess this is a site developed by developers, for developers. 😉

GitHub with JavaScript
The one difference I can see is the way GitHub deals with time. With JavaScript enabled, notice how it says ‘2 days ago’…

GitHub without JavaScript
On the no script version, it instead says “Mar 1, 2018”.

I did a little housekeeping on GitHub, looking around repos and deleting old branches. For a while I genuinely forgot I was on the non-JavaScript version until I came across one little bug:

The “Fetching latest commit…” section will spin forever…
The “Fetching latest commit…” section will spin forever…

Then I wondered, “How is GitHub going to handle applying labels to issues?” so I gave that a go.

These fields are unresponsive when you click on them.
These fields are unresponsive when you click on them.

I was unable to create an issue and add labels to it at the same time. In fact, I couldn’t find any way of adding the label even after creating a blank issue. It’s a shame the site fell at the last hurdle because it was very nearly a seamless comparison with the scripted version.

GitHub noscript rating: NOSCRIPT-3 🤗

While GitHub looks incredible — I would never have known my JavaScript was turned off — not being able to use the same key functionality as the scripted version is a bummer. Even an ugly looking noscript site would get a higher score because functionality is more important than form.

Online Banking

If there’s one place I expected JavaScript to be required, it was on the NatWest bank website. I was wrong.

Not only does it work, but it’s also hard to distinguish from the normal site. The login screen is the same, the only difference being that the focus doesn’t automatically progress through each field as you complete it.

NatWest noscript rating: NOSCRIPT-5 ✅


I came across a few more sites throughout my day.

FreeAgent — the tax software site I use for my freelancing — doesn’t even try a noscript fallback. But hey, that’s better than showing a broken website.

FreeAgent shows a no-JavaScript message.
FreeAgent shows a no-JavaScript message.

FreeAgent noscript rating: NOSCRIPT-2 ⛔

And CodePen, somewhat understandably, has to be a NOSCRIPT-2 too.

A CodePen shows a no-JavaScript message, and suggests it would be pretty foolish to expect the site to work without JavaScript!

CodePen noscript rating: NOSCRIPT-2 ⛔

Tonik, the energy provider, doesn’t let me log in, but this seems like an oversight rather than a deliberate decision:

I see the words “embedded area” where I’m supposed to see a login form.
I see the words “embedded area” where I’m supposed to see a login form.

Tonik noscript rating: NOSCRIPT-1 ❌

M&S Energy lets me log in — only to tell me it needs JavaScript to do anything remotely useful.

M&S requires JavaScript to work, but you have to put more effort in to get to that point.
M&S requires JavaScript to work, but you have to put more effort in to get to that point.

M&S noscript rating: NOSCRIPT-1 ❌

Now I come to my favorite screenshot of the day.

One of my colleagues once recommended an Accessibility for Web Design course, which I bookmarked. I decided to take a look at it today, and laughed at the irony of the alt text:

Alt text of “Personas: Accessibility for Web Design”. Soooo… what am I missing?
Alt text of “Personas: Accessibility for Web Design”. Soooo… what am I missing?

With the alt text of “Personas: Accessibility for Web Design,” I’m not too sure what I’m missing here — is it an image? A video? A PDF? The course itself?

Hint: It’s actually a video, though you have to be logged in to watch it.

The alt text isn’t really supporting its purpose, partly because it’s populated automatically. We as a dev community need to get better at this sort of thing. I don’t think I’ve read any useful alt text today.


I started this experiment with the aim of seeing how many sites are implemented using progressive enhancement. I’ve only visited a tiny handful of sites here, most of them big names with big budgets, so it’s interesting to see the wide variation in no-JavaScript support.

It’s interesting to see that relatively simple sites — Instagram and LinkedIn particularly — have such poor noscript support. I believe this is partly down to the ever-growing popularity of JavaScript frameworks such as React, Angular, and Vue. Developers are now building “web applications” rather than “websites,” with the aim of recreating the look and feel of native apps, and using JavaScript to manage the DOM is the most manageable way of creating such experiences.

There is a danger that more and more sites will require JavaScript to render any content at all. Luckily, it is usually possible to build your content in the same, developer-friendly way but rendered on the server, for example by using Preact instead of React. Making the conscious decision to care about noscript gives the benefits of a core experience as outlined at the beginning of this article, and can make for a faster perceived loading time, too.

It can be quite daunting to think about an application from the ground up, but a decent core experience is usually possible and actually only involves simple tweaks in a lot of cases. A good core experience is indicative of a well-structured web page, which, in turn, is usually a good sign for SEO and for accessibility. It’s usually a well designed web page, as the designer and developer have spent time and effort thinking about what’s truly core to the experience. Progressive enhancement means more robust experiences, with fewer bugs in production and fewer individual browser quirks, because we’re letting the platform do the job rather than trying to write it all from scratch.

What noscript rating does your site conform to? Let us know in the comments!

Smashing Editorial
(rb, ra, il)

Source: Smashing Magazine, I Used The Web For A Day With JavaScript Turned Off

Collective #413

dreamt up by webguru in Uncategorized | Comments Off on Collective #413



Dominic Szablewski open-sourced his impressive HTML5 game engine, Impact.

Check it out

Collective #413 was written by Pedro Botelho and published on Codrops.

Source: Codrops, Collective #413

New CSS Features That Are Changing Web Design

dreamt up by webguru in Uncategorized | Comments Off on New CSS Features That Are Changing Web Design

New CSS Features That Are Changing Web Design

New CSS Features That Are Changing Web Design

Zell Liew

There was a time when web design got monotonous. Designers and developers built the same kinds of websites over and over again, so much so that we were mocked by people in our own industry for creating only two kinds of websites:

Is this the limit of what our “creative” minds can achieve? This thought sent an incontrollable pang of sadness into my heart.

I don’t want to admit it, but maybe that was the best we could accomplish back then. Maybe we didn’t have suitable tools to make creative designs. The demands of the web were evolving quickly, but we were stuck with ancient techniques like floats and tables.

Today, the design landscape has changed completely. We’re equipped with new and powerful tools — CSS Grid, CSS custom properties, CSS shapes and CSS writing-mode, to name a few — that we can use to exercise our creativity.

How CSS Grid Changed Everything

Grids are essential for web design; you already knew that. But have you stopped to asked yourself how you designed the grid you mainly use?

Most of us haven’t. We use the 12-column grid that has became a standard in our industry.

  • But why do we use the same grid?
  • Why are grids made of 12 columns?
  • Why are our grids sized equally?

Here’s one possible answer to why we use the same grid: We don’t want to do the math.

In the past, with float-based grids, to create a three-column grid, you needed to calculate the width of each column, the size of each gutter, and how to position each grid item. Then, you needed to create classes in the HTML to style them appropriately. It was quite complicated.

To make things easier, we adopted grid frameworks. In the beginning, frameworks such as 960gs and 1440px allowed us to choose between 8-, 9-, 12- and even 16-column grids. Later, Bootstrap won the frameworks war. Because Bootstrap allowed only 12 columns, and changing that was a pain, we eventually settled on 12 columns as the standard.

But we shouldn’t blame Bootstrap. It was the best approach back then. Who wouldn’t want a good solution that works with minimal effort? With the grid problem settled, we turned our attention to other aspects of design, such as typography, color and accessibility.

Now, with the advent of CSS Grid, grids have become much simpler. We no longer have to fear grid math. It’s become so simple that I would argue that creating a grid is easier with CSS than in a design tool such as Sketch!


Let’s say you want to make a 4-column grid, each column sized at 100 pixels. With CSS Grid, you can write 100px four times in the grid-template-columns declaration, and a 4-column grid will be created.

.grid {
  display: grid;
  grid-template-columns: 100px 100px 100px 100px;
  grid-column-gap: 20px;

Screenshot of Firefox's grid inspector that shows four columns.
You can create four grid columns by specifying a column-width four times in grid-template-columns

If you want a 12-column grid, you just have to repeat 100px 12 times.

.grid {
  display: grid;
  grid-template-columns: 100px 100px 100px 100px 100px 100px 100px 100px 100px 100px 100px 100px;
  grid-column-gap: 20px;

Screenshot of Firefox's grid inspector that shows twelve columns.
Creating 12 columns with CSS Grid

Yes, the code isn’t beautiful, but we’re not concerned with optimizing for code quality (yet) — we’re still thinking about design. CSS Grid makes it so easy for anyone — even a designer without coding knowledge — to create a grid on the web.

If you want to create grid columns with different widths, you just have to specify the desired width in your grid-template-columns declaration, and you’re set.

.grid {
  display: grid;
  grid-template-columns: 100px 162px 262px;
  grid-column-gap: 20px;

Screenshot of Firefox's grid inspector that shows three colums of different width.
Creating columns of different widths is easy as pie.

Making Grids Responsive

No discussion about CSS Grid is complete without talking about the responsive aspect. There are several ways to make CSS Grid responsive. One way (probably the most popular way) is to use the fr unit. Another way is to change the number of columns with media queries.

fr is a flexible length that represents a fraction. When you use the fr unit, browsers divide up the open space and allocate the areas to columns based on the fr multiple. This means that to create four columns of equal size, you would write 1fr four times.

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-column-gap: 20px;
GIF shows four columns created with the fr unit. These columns resize according to the available white space
Grids created with the fr unit respect the maximum width of the grid. (Large preview)

Let’s do some calculations to understand why four equal-sized columns are created.

First, let’s assume the total space available for the grid is 1260px.

Before allocating width to each column, CSS Grid needs to know how much space is available (or leftover). Here, it subtracts grip-gap declarations from 1260px. Since each gap 20px, we’re left with 1200px for the available space. (1260 - (20 * 3) = 1200).

Next, it adds up the fr multiples. In this case, we have four 1fr multiples, so browsers divide 1200px by four. Each column is thus 300px. This is why we get four equal columns.

However, grids created with the fr unit aren’t always equal!

When you use fr, you need to be aware that each fr unit is a fraction of the available (or leftover) space.

If you have an element that is wider than any of the columns created with the fr unit, the calculation needs to be done differently.

For example, the grid below has one large column and three small (but equal) columns even though it’s created with grid-template-columns: 1fr 1fr 1fr 1fr.

See the Pen CSS Grid `fr` unit demo 1 by Zell Liew (@zellwk) on CodePen.

After splitting 1200px into four and allocating 300px to each of the 1fr columns, browsers realize that the first grid item contains an image that is 1000px. Since 1000px is larger than 300px, browsers choose to allocate 1000px to the first column instead.

That means, we need to recalculate leftover space.

The new leftover space is 1260px - 1000px - 20px * 3 = 200px; this 200px is then divided by three according to the amount of leftover fractions. Each fraction is then 66px. Hopefully that explains why fr units do not always create equal-width columns.

If you want the fr unit to create equal-width columns everytime, you need to force it with minmax(0, 1fr). For this specific example, you’ll also want to set the image’s max-width property to 100%.

See the Pen CSS Grid `fr` unit demo 2 by Zell Liew (@zellwk) on CodePen.

Note: Rachel Andrew has written an amazing article on how different CSS values (min-content, max-content, fr, etc.) affect content sizes. It’s worth a read!

Unequal-Width Grids

To create grids with unequal widths, you simply vary the fr multiple. Below is a grid that follows the golden ratio, where the second column is 1.618 times of the first column, and the third column is 1.618 times of the second column.

.grid {
  display: grid;
  grid-template-columns: 1fr 1.618fr 2.618fr;
  grid-column-gap: 1em;

GIF shows a three-column grid created with the golden ratio. When the browser is resized, the columns resize accordingly.
A three-column grid created with the golden ratio

Changing Grids At Different Breakpoints

If you want to change the grid at different breakpoints, you can declare a new grid within a media query.

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-column-gap: 1em;

@media (min-width: 30em) {
  .grid {
    grid-template-columns: 1fr 1fr 1fr 1fr;

Isn’t it easy to create grids with CSS Grid? Earlier designers and developers would have killed for such a possibility.

Height-Based Grids

It was impossible to make grids based on the height of a website previously because there wasn’t a way for us to tell how tall the viewport was. Now, with viewport units, CSS Calc, and CSS Grid, we can even make grids based on viewport height.

In the demo below, I created grid squares based on the height of the browser.

See the Pen Height based grid example by Zell Liew (@zellwk) on CodePen.

Jen Simmons has a great video that talks about desgining for the fourth edge — with CSS Grid. I highly recommend you watch it.

Grid Item Placement

Positioning grid items was a big pain in the past because you had to calculate the margin-left property.

Now, with CSS Grid, you can place grid items directly with CSS without the extra calculations.

.grid-item {
  grid-column: 2; /* Put on the second column */

Screenshot of a grid item placed on the second column
Placing an item on the second column.

You can even tell a grid item how many columns it should take up with the span keyword.

.grid-item {
  /* Put in the second column, span 2 columns */
  grid-column: 2 / span 2;

Screenshot of a grid item that's placed on the second column. It spans two columns
You can tell grid items the number of columns (or even rows) they should occupy with the span keyword


CSS Grid enables you to lay things out so easily that you can create a lot of variations of the same website quickly. One prime example is Lynn Fisher’s personal home page.

If you’d like to find out more about what CSS Grid can do, check out Jen Simmon’s lab, where she explores how to create different kinds of layouts with CSS Grid and other tools.

To learn more about CSS Grid, check out the following resources:

Designing With Irregular Shapes

We are used to creating rectangular layouts on the web because the CSS box model is a rectangle. Besides rectangles, we’ve also found ways to create simple shapes, such as triangles and circles.

Today, we don’t need to stop there. With CSS shapes and clip-path at our disposal, we can create irregular shapes without much effort.

For example, Aysha Anggraini experimented with a comic-strip-inspired layout with CSS Grid and clip path.

See the Pen Comic-book-style layout with CSS Grid by Aysha Anggraini (@rrenula) on CodePen.

Hui Jing explains how to use CSS shapes in a way that allows text to flow along the Beyoncé curve.

An image of Huijing's article, where text flows around Beyoncé.
Text can flow around Beyoncé if you wanted it to!

If you’d like to dig deeper, Sara Soueidan has an article to help you create non-rectangular layouts.

CSS shapes and clip-path give you infinite possibilities to create custom shapes unique to your designs. Unfortunately, syntax-wise, CSS shapes and clip-path aren’t as intuitive as CSS Grid. Luckily, we have tools such as Clippy and Firefox’s Shape Path Editor to help us create the shapes we want.

Image of Clippy, a tool to help you create custom CSS shapes
Clippy helps you create custom shapes easily with clip-path.

Switching Text Flow With CSS’ writing-mode

We’re used to seeing words flow from left to right on the web because the web is predominantly made for English-speaking folks (at least that’s how it started).

But some languages don’t flow in that direction. For example, Chinese words can read top down and right to left.

CSS’ writing-mode makes text flow in the direction native to each language. Hui Jing experimented with a Chinese-based layout that flows top down and right to left on a website called Penang Hokkien. You can read more about her experiment in her article, “The One About Home”.

Besides articles, Hui Jing has a great talk on typography and writing-mode, “When East Meets West: Web Typography and How It Can Inspire Modern Layouts”. I highly encourage you to watch it.

An image of the Penang Hokken, showcasing text that reads from top to bottom and right to left.
Penang Hokkien shows that Chinese text can be written from top to bottom, right to left.

Even if you don’t design for languages like Chinese, it doesn’t mean you can’t apply CSS’ writing-mode to English. Back in 2016, when I created Devfest.asia, I flexed a small creative muscle and opted to rotate text with writing-mode.

An image that shows how I rotated text in a design I created for Devfest.asia
Tags were created by using writing mode and transforms.

Jen Simmons’s lab contains many experiments with writing-mode, too. I highly recommend checking it out, too.

An image from Jen Simmon's lab that shows a design from Jan Tschichold.
An image from Jen Simmon’s lab that shows Jan Tschichold

Effort And Ingenuity Go A Long Way

Even though the new CSS tools are helpful, you don’t need any of them to create unique websites. A little ingenuity and some effort go a long way.

For example, in Super Silly Hackathon, Cheeaun rotates the entire website by -15 degrees and makes you look silly when reading the website.

A screenshot from Super Silly Hackthon, with text slightly rotated to the left
Cheeaun makes sure you look silly if you want to enter Super Silly Hackathon.

Darin Senneff made an animated login avatar with some trigonometry and GSAP. Look at how cute the ape is and how it covers its eyes when you focus on the password field. Lovely!

When I created the sales page for my course, Learn JavaScript, I added elements that make the JavaScript learner feel at home.

Image where I used JavaScript elements in the design for Learn JavaScript.
I used the function syntax to create course packages instead of writing about course packages

Wrapping Up

A unique web design isn’t just about layout. It’s about how the design integrates with the content. With a little effort and ingenuity, all of us can create unique designs that speak to our audiences. The tools at our disposal today make our jobs easier.

The question is, do you care enough to make a unique design? I hope you do.

Smashing Editorial
(ra, il, al)

Source: Smashing Magazine, New CSS Features That Are Changing Web Design

FAST UX Research: An Easier Way To Engage Stakeholders And Speed Up The Research Process

dreamt up by webguru in Uncategorized | Comments Off on FAST UX Research: An Easier Way To Engage Stakeholders And Speed Up The Research Process

FAST UX Research: An Easier Way To Engage Stakeholders And Speed Up The Research Process

FAST UX Research: An Easier Way To Engage Stakeholders And Speed Up The Research Process

Zoe Dimov

Today, UX research has earned wide recognition as an essential part of product and service design. However, UX professionals still seem to be facing two big problems when it comes to UX research: A lack of engagement from the team and stakeholders as well as the pressure to constantly reduce the time for research.

In this article, I’ll take a closer look at each of these challenges and propose a new approach known as ‘FAST UX’ in order to solve them. This is a simple but powerful tool that you can use to speed up UX research and turn stakeholders into active champions of the process.

Contrary to what you might think, speeding up the research process (in both the short and long term) requires effective collaboration, rather than you going away and soldiering on by yourself.

The acronym FAST (Focus, Attend, Summarise, Translate) wraps up a number of techniques and ideas that make the UX process more transparent, fun, and collaborative. I also describe a 5-day project with a central UK government department that shows you how the model can be put into practice.

The article is relevant for UX professionals and the people who work with them, including product owners, engineers, business analysts, scrum masters, marketing and sales professionals.

1. Lack Of Engagement Of The Team And Stakeholders

“Stakeholders have the capacity for being your worst nightmare and your best collaborator.”

UIE (2017)

As UX researchers, we need to ensure that “everyone in our team understands the end users with the same empathy, accuracy and depth as we do.” It has been shown that there is no better alternative to increasing empathy than involving stakeholders to actually experience the whole process themselves: from the design of the study (objectives, research questions), to recruitment, set up, fieldwork, analysis and the final presentation.

Anyone who has tried to do this knows that it can be extremely difficult to organize and get stakeholders to participate in research. There are two main reasons for this:

  1. Research is somebody else’s job.
    In my experience, UX professionals are often hired to “do the UX” for a company or organization. Even though the title of “Lead UX Researcher” sounds great and very important in my head, it often leads to misconceptions during kick-off meetings. Everyone automatically assumes that research is solely MY responsibility. It’s no wonder that stakeholders don’t want to get involved in the project. They assume research is my and nobody else’s job.
  2. UX process frameworks are incomplete.
    The problem is that even when stakeholders want to engage and participate in UX, they still do not know *how* they should get involved and *what* they should do. We spend a lot of time selling a UX process and research frameworks that are useful but ultimately incomplete — they do not explain how non-researchers can get involved in the research process.

Problems associated with stakeholders involvement in UX Research.
Fig. 1. Despite our enthusiasm as researchers, stakeholders often don’t understand how to get involved with the research process.

Further, a lot of stakeholders can find words such as ‘design,’ ‘analysis’ or ‘fieldwork’ intimidating or irrelevant to what they do. In fact, “UX is rife with jargon that can be off-putting to people from other fields.” In some situations, terms are familiar but mean something completely different, e.g., research in UX versus marketing research.

2. Pressure To Constantly Reduce The Time For Research

Another issue is that there is a constantly growing pressure to speed up the UX process and reduce the time spent on research. I cannot count the number of times when a project manager asked me to shorten a study even further by skipping the analysis stage or the kick-off sessions.

While previously you could spend weeks on research, a 5-day research cycle is increasingly becoming the norm. In fact, the book Sprint describes how research can dwindle to just a day (from an overall 5-day cycle).

Considering this, there is a LOT of pressure on UX researchers to deliver fast, without compromising the quality of the study. The difficulty increases when there are multiple stakeholders, each with their own opinions, demands, views, assumptions, and priorities.

The Fast UX Approach

Contrary to what you might think, reducing the time it takes to do UX research does not mean that you need to soldier on by yourself. I have done this and it only works in the short term. It does not matter how amazing the findings are — there is not enough PowerPoint slides in the world to convince a team of the urgency to take action if they have not been on the research journey themselves.

In the long term, the more actively engaged your team and stakeholders are in the research, the more empowered they will feel and the more willing they will be to take action. Productive collaboration also means that you can move together at a quicker pace and speed up the whole research process.

The FAST UX Research framework (see Fig. 2 below) is a tool to truly engage team members and stakeholders in a way that turns them into active advocates and champions of the research process. It shows non-researchers when and how they should get involved in UX Research.

The FAST UX Research approach; FAST UX Research methodology.
Fig. 2. The FAST User Experience Research framework

In essence, stakeholders take ownership of each of the UX research stages by carrying out the four activities, each corresponding to its research stage.

Working together reduces the time it takes for UX Research. The true benefit of the approach, however, is that, in the long term, it takes less and less time for the business to take action based on research findings as people become true advocates of user-centricity and the research process.

This approach can be applied to any qualitative research method and with any team. For example, you can carry out FAST usability testing, FAST interviews, FAST ethnography, and so on. In order to be effective, you will need to explain this approach to your stakeholders from the start. Talk them through the framework, explaining each stage. Emphasize that this is what EVERYONE does, that it’s their work as much as the UX researcher’s job, and that it’s only successful if everyone is involved throughout the process.

Stage 1: Focus (Define A Common Goal)

There is a uniform consensus within UX that a research project should start by defining its purpose: why is this research done and how will the results be acted upon?

Focus in FAST UX Research; first stage in the FAST UX Research process.
Fig. 3. Focus is about defining clear objectives and goals for the research and it’s ultimately the team’s and all stakeholders’ shared responsibility to do this.

Generally, this is expressed within the research goals, objectives, research questions and/or hypotheses. Most projects start with a kick-off meeting where those are either discussed (based on an available brief) or are defined during the meeting.

The most regular problem with kick-off sessions like these is that stakeholders come up with too many things they want to learn from a study. The way to turn the situation around is to assign a specific task to your immediate team (other UX professionals you work with) and stakeholders (key decision makers): they will help focus the study from the beginning.

The way they will do that is by working together through the following steps:

  1. Identify as a group the current challenges and problems.
    Ask someone to take notes on a shared document; alternatively, ask everyone to participate and write on sticky notes which are then displayed on a “project wall” for everyone to see.
  2. Identify the potential objectives and questions for a research study.
    Do this the same way you did the previous step. You don’t need to commit to anything yet.
  3. Prioritize.
    Ask the team to order the objectives and questions, starting with the most important ones.
  4. Reword and rephrase.
    Look at the top 3 questions and objectives. Are they too broad or narrow? Could they be reworded so it’s clearer what is the focus of the study? Are they feasible? Do you need to split or merge objectives and questions?
  5. Commit to be flexible.
    Agree on the top 1-2 objectives and ensure that you have agreement from everyone that this is what you will focus on.

Here are some questions you can ask to help your stakeholders and team to get to the focus of the study faster:

  • From the objectives we have recognized, what is most important?
  • What does success look like?
  • If we only learn one thing, which one would be the most important one?

Your role during the process is to provide expertise to determine if:

  • The identified objectives and questions are feasible for a single study;
  • Help with the wording of objectives and questions;
  • Design the study (including selecting a methodology) after the focus has been identified.

At first sight, the Focus and Attend (next stages) activities might be familiar as you are already carrying out a kick-off meeting and inviting stakeholders to attend research sessions.

However, adopting a FAST approach means that your stakeholders have as much ownership as you do during the research process because work is shared and co-owned. Reiterate that the process is collaborative and at the end of the session, emphasize that agreeing on clear research objectives is not easy. Remind everybody that having a shared focus is already better than what many teams start with.

Finally, remind the team and your stakeholders what they need to do during the rest of the process.

Stage 2: Attend (Immerse The Team Deeply In The Research Process)

Seeing first hand the experience of someone using a product or service is so rich that there is no substitute for it. This is why getting stakeholders to observe user research is still considered one of the best and most powerful ways to engage the team.

Attend in FAST UX Research; second stage in FAST UX Research.
Fig. 4. Attend in FAST UX Research is about encouraging the team and stakeholders to be present at all research sessions, but also to be actively engaged with the research.

What often happens is that observers join in on the day of the research study and then they spend the time plastered to their laptops and mobile phones. What is worse, some stakeholders often talk to the note-taker and distract the rest of the design team who need to observe the sessions.

This is why it is just as important that you get the team to interact with the research. The following activities allow the team to immerse themselves in the research session. You can ask stakeholders to:

  • Ask questions during the session through a dedicated live chat (e.g. Slack, Google Hangouts, Skype);
  • Take notes on sticky notes;
  • Summarize observations for everyone (see next stage).

Assign one person per session for each of these activities. Have one “live chat manager,” one “note-taker,” and one “observer” who will sum up the session afterwards.

Rotate people for the next session.

Before the session, it’s useful to walk observers through the ‘ground rules’ very briefly. You can have a poster similar to the one GDS developed that will help you do this and remind the team of their role during the study (see Fig. 3 above).

An observation poster; user research poster.
Fig. 5. A poster can be hanged in the observation room and used to remind the team and stakeholders what their responsibilities are and the ground rules during observation.

Farrell (2017) provides more detail on effective ways for stakeholders to take notes together. When you have multiple stakeholders and it’s not feasible for them to physically attend a field visit (e.g. on the street, in an office, at the home of the participant), you could stream the session to an observation room.

Stage 3: Summarize (Analysis For Non-Researchers)

I am a strong supporter of the idea that analysis starts the moment fieldwork begins. During the very first research session, you start looking for patterns and interpretation of what the data you have means.

Summarize in FAST UX Research; the third stage in FAST UX Research.
Fig. 6. Summarize in FAST UX Research is about asking the team and your stakeholders to tell you about what they thought were the most interesting aspects of user research.

Even after the first session (but typically towards the end of fieldwork) you can carry out collaborative analysis: a fun and productive way that ensures that you have everyone participating in one of the most important stages of research.

The collaborative analysis session is an activity where you provide an opportunity for everyone to be heard and create a shared understanding of the research.

Since you’re including other experts’ perspectives, you’re increasing the chances to identify more objective and relevant insights, and also for stakeholders to act upon the results of the study.

Even though ‘analysis’ is an essential part of any research project, a lot of stakeholders get scared by the word. The activity sounds very academic and complex. This is why at the end of each research session, research day, or the study as a whole, the role of your stakeholders and immediate team is to summarize their observations. Summarizing may sound superfluous but is an important part of the analysis stage; this is essentially what we do during “Downloading” sessions.

Listening to someone’s summary provides you with an opportunity to understand:

  • What they paid attention to;
  • What is important for them;
  • Their interpretation of the event.

Summary At The End Of Each Session

You do this by reminding everyone at the beginning of the session that at the end you will enter the room and ask them to summarize their observations and recommendations.

You then end the session by asking each stakeholder the following:

  • What were their key observations (see also Fig. 3)?
    • What happened during the session?
    • Were there any major difficulties for the participant?
    • What were the things that worked well?
  • Was there anything that surprised them?

This will make the team more attentive during the session, as they know that they will need to sum it up at the end. It will also help them to internalize the observations (and later, transition more easily to findings).

This is also the time to consistently share with your team what you think stands out from the study so far. Avoid the temptation to do a ‘big reveal’ at the end. It’s better if outcomes are told to stakeholders many times.

On multiple occasions, research has given me great outcomes. Instead of sharing them regularly, I keep them to myself until the final report. It doesn’t work well. A big reveal at the end leads to bewildered stakeholders who often cannot jump from observations to insights as quickly. As a result, there is either stubborn pushback or indifferent shrugs.

Summary At The End Of The Day

A summary of the event or the day can then naturally transition into a collaborative analysis session. Your job is to moderate the session.

The job of your stakeholders is to summarize the events of the day and the final results. Ask a volunteer to talk the group through what happened during the day. Other stakeholders can then add to these observations.

Summary At The End Of The Study

After the analysis is done, ask one or two stakeholders to summarize the study. Make sure they cover why we did research, what happened during the study and what are the primary findings. They can also do this by walking through the project wall (if you have one).

It’s very difficult not to talk about your research and leave someone else to do it. But it’s worth it. No matter how much you’re itching to do this yourself — don’t! It’s a great opportunity for people to internalize research and become comfortable with the process. This is one of the key moments to turn stakeholders into active advocates of user research.

At the end of this stage, you should have 5-7 findings that capture the study.

Stage 4: Translate (Make Stakeholders Active Champions Of The Solution)

“Research doesn’t have a value unless it results in decisions and actions.”

—Lang and Howell (2017).

Even when you agree with the findings, stakeholders might still disagree about what the research means or lack commitment to take further action. This is why after summarizing, ask your stakeholders to work with you and identify the “Now what?” or what it all means for the organization, product, service, team and/or individually for each one of them.

Translate in FAST UX Research; the fourth stage in FAST UX Research.
Fig. 7. Translate in FAST UX Research is about asking the team or individual stakeholders to discuss each of the findings and articulate how it will impact the business, the service, and product or their work.

Traditionally, it was the UX researchers’ job to write clear, precise, descriptive findings, and actionable recommendations. However, if the team and stakeholders are not part of identifying actionable recommendations, they might be resistant towards change in future.

To prevent later pushback, ask stakeholders to identify the “Now what?” (also referred to as ‘actionable recommendations’). Together, you’ll be able to identify how the insights and findings will:

  • Affect the business and what needs to be done now;
  • Affect the product/service and what changes do we need to make;
  • Affect people individually and the actions they need to take;
  • Lead to potential problems and challenges and their solutions;
  • Help solve problems or identify potential solutions.

Stakeholders and the team can translate the findings at the end of a collaborative analysis session.

If you decide to separate the activities and conduct a meeting in which the only focus is on actionable recommendations, then consider the following format:

  1. Briefly talk through the 5-7 main findings from the study (as a refresher if this stage is done separately from the analysis session or with other stakeholders).
  2. Split the group into teams and ask them to work on one finding/problem at a time.
  3. Ask them to list as many ways they see the finding affecting them.
  4. Ask one person from each group to present the findings back to the team.
  5. Ask one/two final stakeholders to summarize the whole study, together with the methods, findings, and recommendations.

Later, you can have multiple similar workshops; this is how you get to engage different departments from the organization.

Fast UX In Practice

An excellent example of a FAST UX Research approach in practice is a project I was hired to carry out for a central UK government department. The ultimate goal of the project was to identify user requirements for a very complex internal system.

At first sight, this was a very challenging project because:

  • There was no time to get to know the department or the client.
    Usually, I would have at least a week or two to get to know the client, their needs, opinions, internal pressures, and challenges. For this project, I had to start work on Monday with a team I had never met; in a building I had never worked, in a domain I knew little about, and finish on Friday the same week.
  • The system was very complex and required intense research.
    The internal system and the nature of work were very complex; this required gathering data with at least a few research methods (for triangulation).
  • This was the first time the team had worked with a UX Researcher.
    The stakeholders were primarily IT specialists. However, I was lucky that they were very keen and enthusiastic to be involved in the project and get their hands dirty.
  • Stakeholder availability.
    As is the case on many other projects, all stakeholders were extremely busy as they had their own work on top of the project. Nonetheless, we made it work, even if it meant meeting over lunch, or for a 15-minute wrap up before we went home.
  • There were internal pressures and challenges.
    As with any department and huge organization, there were a number of internal pressures and challenges. Some of them I expected (e.g. legacy systems, slow pace of change) but some I had no clue about when I started.
  • We had to coordinate work with external teams.
    An additional challenge was the need to work with and coordinate efforts with external teams at another UK department.

Despite all of these challenges, this was one of the most enjoyable projects I have worked on because of the tight collaboration initiated by the FAST approach.

The project consisted of:

  • 1 day of kick-off sessions and getting to know the team
  • 2,5 days of contextual inquiries and shadowing of internal team members,
  • Half a day for a co-creation workshop, and
  • 1 day for analysis and results reporting.

In the process, I gathered data from 20+ employees, had 16+ hours of observations, 300+ photos and about 100 pages of notes. Here is a great example of cramming in 3 weeks’ worth of work into a mere 5-day research cycle. More importantly, people in the department were really excited about the process.

Here is how we did it using a FAST UX Research approach:

  • Focus
    At the beginning of the project, the two key stakeholders identified what the focus of research would be while my role was mainly to help with prioritizing the objectives, tweak the research questions and check for feasibility. In this sense, I listened and mainly asked questions, interjecting occasionally with examples from previous projects or options that helped to adjust our approach.

    While I wrote the main discussion guide for the contextual inquiries and shadowing sessions, we sat together with the primary team to discuss and design the co-creation workshop with internal users of the system.

  • Attend
    During the workshop one of the stakeholders moderated half of the session, while the other took notes and observed closely the participants. It was a huge success internally, as stakeholders felt there was better visibility for their efforts to modernize the department, while employees felt listened to and involved in the research.
  • Summarize
    Immediately after the workshop, we sat together with the stakeholders for a 30-minute meeting where I had them summarize their observations.

    As a result of the shadowing, contextual inquiries and co-creation workshop, we were able to identify 60+ issues and problems with the internal system (with regards to integration, functionality, and usability), all captured in six high-level findings.

  • Translate
    Later, we discussed with the team how each of the six major findings translated to a change or implication for the department, the internal system, as well as collaboration with other departments.

We were so perfectly aligned with the team that when we had to talk about our work in front of another UK government department, I could let the stakeholders talk about the process and our progress.

My final task (over two additional days) was to document all of the findings in a research report. This was necessary as a knowledge repository because I had to move onto other projects.

With a more traditional approach, the project could have easily spanned 3 weeks. More importantly, quickly understanding individual and team pressures and challenges were the keys to the success of the new system. This could not have happened within the allocated time without a collaborative approach.

A FAST UX approach resulted in tight collaboration, strong co-ownership and a shared sense of progress; all of those allowed to shorten the time of the project, but also to instill a feeling of excitement about the UX research process.

Have You Tried It Out Already?

While UX research becomes ever more popular, gone are the days when we could soldier on by ourselves and only consult stakeholders at the end.

Mastering our craft as UX researchers means engaging others within the process and being articulate, clear, and transparent about our work. The FAST approach is a simple model that shows how to engage non-researchers with the research process. Reducing the time it takes to do research, both in the short (i.e. the study itself) and long term (i.e. using the research results), is a strategic advantage for the researcher, team, and the business as a whole.

Would you like to improve your efficiency and turn stakeholders into user research advocates? Go and try it out. You can then share your stories and advice here.

I would love to hear your comments, suggestion and any feedback you care to share! If you have tried it out already, do you have success stories you want to share? Be as open as you can — what worked well, and what didn’t? As with all other things UX, it’s most fun if we learn together as a team.

Smashing Editorial
(cc, ra, il)

Source: Smashing Magazine, FAST UX Research: An Easier Way To Engage Stakeholders And Speed Up The Research Process

Collective #412

dreamt up by webguru in Uncategorized | Comments Off on Collective #412



Curtains.js is a light-weight WebGL JavaScript library that turns HTML elements into interactive textured planes.

Check it out


Our Sponsor

Divi: A Web Designer’s Dream

Divi is the ultimate tool for web designers. Hundreds of thousands of WordPress freelancers and agencies are empowered by Divi to help run their growing businesses.

Try it now


Grid Level 2 and Subgrid

An article by Rachel Andrew where she explains subgrids and why they’d make a good addition to the Grid specification.

Read it



Build, train, and ship custom deep learning models using a simple visual interface. Available for beta invitations.

Check it out



ReLaXed is a tool which creates PDF documents interactively using HTML or Pug.

Check it out

Collective #412 was written by Pedro Botelho and published on Codrops.

Source: Codrops, Collective #412

Using Low Vision As My Tool To Help Me Teach WordPress

dreamt up by webguru in Uncategorized | Comments Off on Using Low Vision As My Tool To Help Me Teach WordPress

Using Low Vision As My Tool To Help Me Teach WordPress

Using Low Vision As My Tool To Help Me Teach WordPress

Bud Kraus

When I say that I see things in a different way, I’m not kidding. It’s literally true.

For almost 30 years, I’ve lived my life with macular degeneration, a destruction of my central vision. It is the leading cause of legal blindness in the United States and I’m one of those statistics.

Macular degeneration is a malady of old age. I see the world much as a very old person does. You could say that I am “hard of seeing.”

Since my condition is present in both eyes, there is no escape. Facial recognition, driving (looking forward to driverless cars), reading, and watching movies or TV are difficult or impossible tasks for me.

Since my peripheral vision is intact, I have no problem moving about without bumping into things. In fact, if you met me you would not immediately know that I have a serious vision impairment.

Sharing this is not easy. It’s not just that I don’t want to be branded as that blind WordPress guy or to have people feel sorry for me. I don’t like to discuss it because I find it is as interesting as discussing my right-handedness. Besides, I’m hardly the only person who has a disability or illness. Many people have conditions which are far worse than mine.

I have discovered that for most people technology makes things easier. For others, like me, it makes things possible.

I focus on what I can do, not what I can’t do. Then I figure out a way to do it better than anyone else. I use what I have learned from my disability as a tool to help me communicate.

Everyone works with WordPress differently. Me, even more so. Here are some of the adjustments I’ve made as a WordPress instructor and site developer.

1. How I Do It: Zoom/Talk/Touch

Let me show you how I really work with WordPress as I zoom in and out and let the machine talk to me.

What you don’t see here is how I use space and touch to know where objects are on a screen. It’s easy to understand this for mobile devices, but the same is true — especially for me — when it comes to knowing how far I need to move the mouse to do something. When a major change takes place on a site or in the WP Admin, it takes me time to re-orient myself to a new UI.

My visual impairment has improved my sense of touch for everything including finding and interacting with screen objects.

2. I’m Prepared

I can’t wing it. When I teach in class or do a presentation I need to know exactly what I’m going to say because I can’t read notes about what I will demonstrate. I need to have order.

The same holds true for working with clients or doing live webinars. Everything I do is structured.

I think of stories that have a beginning, middle, and end. When I teach or speak in public, I take you on a journey. I know where I will start, where I will finish, and how I got there.

Being a prep freak has made me better at everything I do.

3. I Recognize Patterns

Since I can recognize consistent shapes, I learned how to teach and use HTML and CSS. But a deep understanding of languages like Javascript and PHP are just out of my range because they are free-form and unpredictable.

Take HTML. Its hallmark is that it is a symmetrical, containerized markup system. Open tags usually need to be closed. The pattern is simple and easy for me to recognize:

<tag>Some Text Here</tag>

CSS is much the same. Its very predictable pattern make it possible for me to teach and use it. For example:



Think of it this way. I can read most fonts on a screen given proper illumination and magnification. Handwriting — which is so unpredictable — is impossible to read.

My abilities give me just enough skill to create WordPress child themes.

Since vision and memory are so closely connected, you could say I have a memory disability more than any other. Pattern recognition — an aid to memory — makes it possible to work with things like code.

4. A Little Help From My Friends

If I need it, I get assistance. If a class size is large enough, I’ll get someone to sit with a student who needs attention. If I do a presentation with a laptop — something I have a hard time with — I’ll have someone work the laptop. When I need someone to spell check and work over my words, I have a friend that does that too.

5. WordPress — More Than Alt Tags

You’d think that, given my disability, I’d be an expert on accessible web design. I’m not. However, 16 years ago when user agents and assistive technologies were more hope than reality, I taught classes at Pratt Institute in New York City on design which worked for the greatest number of people on the greatest number of devices.

Sound familiar?

To be sure, WordPress has a lot of built-in accessibility awareness, either in its core or because of its enlightened plugin and theme developers. It has an active group, Make WordPress Accessible, that ensures WordPress is compliant with the WCAG 2.0 standards.

While I stress the use of the Alt attribute (it’s misunderstood as an SEO signal), I rarely discuss features such as keyboard shortcuts and tabindex. Though I’m a stakeholder in ensuring that the WordPress admin is accessible, no one would mistake me for an expert in recognizing and knocking down all barriers to access in web design.

And What About Gutenberg?

WordPress will be rolling out its new content editor, Gutenberg, in 2018 replacing its well known but aging WP editor. It features a block editing system akin to what SquareSpace, WIX, and MailChimp use.

Gutenberg has a cleaner, sleeker user interface. Many of the user options are hidden and appear only after certain mouse over actions occur. This doesn’t seem to be much of an issue for me. What is distracting is that in certain instances the Gutenberg interface will cover up parts of the page copy.

A bigger issue is how keyboard shortcuts will work. Beyond the needs of disability communities, many power users prefer shortcuts. Currently, many but not all of Gutenberg’s functions are available as a shortcut. Equally troublesome, there are no indications of shortcuts in the menus or as tooltips. Nor is there any way to easily see all shortcuts in a single list.

7. Look Ma’, No Script! Creating Videos For My Online WordPress Course

I need to memorize just about everything. While creating my training course, “The WP A To Z Series,” I could not use a script for my screen capture videos. When creating videos I have to know the material cold. I try to make you wonder if I’m reading when I’m not. The result are videos that have a personal feeling to them which is what I wanted (and the only thing I could do).

8. I Never Use More Than I Need

If I need help — be it with tech or with a human — I ask for it. If I don’t need it, I don’t ask. I get and use as much help (human and tech) as I need and never more.

Since I don’t need JAWS, a popular screen reading program, I don’t know JAWS. I don’t need speech to text software, so I don’t use Dragon Dictate.

And that is the point.

People with — or without — disabilities work with tech in ways that will help them accomplish tasks in the most efficient matter. If something is overkill, why use it?

My Way Is Probably A Lot Like Your Way — Or Is It?

Turns out, I use WordPress a lot like everyone without a disability uses it. At least I think so. Sure, I have to zoom in to see things and I don’t care for radical changes in design. But, once I understand a UI, finding or manipulating things after a redesign is similar to the challenge a blind person faces in a room where the furniture has been moved or replaced.

As you saw in my video, I need text to speech software to make it easier to understand what is on the screen. And zooming in and out is as common to me as a click is to everyone. All this takes a little more time but it’s how I get things done.

As you may have surmised — and what I can’t stress enough — is that a disability is a very personal thing in more ways than one. The things I do in order to teach and work with WordPress are probably very different from what another person does who also has macular degeneration. It’s the idiosyncrasies that make understanding and working with any disability very challenging for everyone.

Smashing Editorial
(mc, ra, yk, il)

Source: Smashing Magazine, Using Low Vision As My Tool To Help Me Teach WordPress

A Conference Without Slides: Meet SmashingConf Toronto 2018 (June 26-27)

dreamt up by webguru in Uncategorized | Comments Off on A Conference Without Slides: Meet SmashingConf Toronto 2018 (June 26-27)

A Conference Without Slides: Meet SmashingConf Toronto 2018 (June 26-27)

A Conference Without Slides: Meet SmashingConf Toronto 2018 (June 26-27)

Vitaly Friedman

What would be the best way to learn and improve your skills? By looking designers and developers over their shoulder! At SmashingConf Toronto taking place on June 26–27, we will exactly do that. All talks will be live coding and design sessions on stage, showing how speakers such as Dan Mall, Lea Verou, Rachel Andrew, and Sara Soueidan design und build stuff — including pattern libraries setup, design workflows and shortcuts, debugging, naming conventions, and everything in between. To the tickets →

Smashingconf Toronto 2018
What if there was a web conference without… slides? Meet SmashingConf Toronto 2018 with live sessions exploring how experts think, design, build and debug.

The night before the conference we’ll be hosting a FailNight, a warm-up party with a twist — every single session will be highlighting how we all failed on a small or big scale. Because, well, it’s mistakes that help us get better and smarter, right?


One track, two conference days (June 26–27), 16 speakers, and just 500 available seats. We’ll cover everything from efficient design workflow and getting started with Vue.js to improving eCommerce UX and production-ready CSS Grid Layouts. Also on our list: performance audits, data visualization, multi-cultural designs, and other fields that may come up in your day-to-day work.

Here’s what you should be expecting:

Dan Mall and Lea Verou are two of the speakers at SmashingConf Toronto
That’s quite a speakers line-up, with topics ranging from live CSS/JavaScript coding to live lettering.

Conference Tickets

C$699Get Your Ticket

Two days of great speakers and networking
Check all speakers →

Conf + Workshop Tickets

Save C$100 Conf + Workshop

Three days full of learning and networking
Check all workshops →

Workshops At SmashingConf Toronto

On the two days before and after the conference, you have the chance to dive deep into a topic of your choice. Tickets for the full-day workshops cost C$599. If you combine it with a conference ticket, you’ll save C$100 on the regular workshop price. Seats are limited.

Workshops on Monday, June 25th

Sara Soueidan on The CSS & SVG Power Combo
Sara SoueidanThe workshop with the strongest punch of creativity. The CSS & SVG Power Combo is where you will learn about the latest, cutting-edge CSS and SVG techniques to create creative crisp and beautiful interfaces. We will also be looking at any existing browser inconsistencies as well as performance considerations to keep in mind. And there will be lots of exercises and practical examples that can be taken and directly applied in real life projects.Read more…

Sarah Drasner on Intro To Vue.js
Sarah DrasnerVue.js brings together the best features of the Javascript framework landscape elegantly. If you’re interested in writing maintainable, clean code in an exciting and expressive manner, you should consider joining this class. Read more…

Tim Kadlec on Demystifying Front-End Security
Tim KadlecWhen users come to your site, they trust you to provide them with a good experience. They expect a site that loads quickly, that works in their browser, and that is well designed. And though they may not vocalize it, they certainly expect that the experience will be safe: that any information they provide will not be stolen or used in ways they did not expect. Read more…

Aaron Draplin on Behind The Scenes With The DDC
Aaron DraplinGo behind the scenes with the DDC and learn about Aaron’s process for creating marks, logos and more. Each student will attack a logo on their own with guidance from Aaron. Could be something you are currently working on, or have always wanted to make. Read more…

Dan Mall on Design Workflow For A Multi-Device World
Dan MallIn this workshop, Dan will share insights into his tools and techniques for integrating design thinking into your product development process. You’ll learn how to craft powerful design approaches through collaborative brainstorming techniques and how to involve your entire team in the design process. Read more…

Vitaly Friedman on Smart Responsive UX Design Patterns
Vitaly FriedmanIn this workshop, Vitaly Friedman, co-founder of Smashing Magazine, will cover practical techniques, clever tricks and useful strategies you need to be aware of when working on responsive websites. From responsive modules to clever navigation patterns and web form design techniques; the workshop will provide you with everything you need to know today to start designing better responsive experiences tomorrow. Read more…

Workshops on Thursday, June 28th

Eva-Lotta Lamm on Sketching With Confidence, Clarity And Imagination
Eva-Lotta LammBeing able to sketch is like speaking an additional language that enables you to structure and express your thoughts and ideas more clearly, quickly and in an engaging way. For anyone working in UX, design, marketing and product development in general, sketching is a valuable technique to feel comfortable with. Read more…

Nadieh Bremer on Creative Data Visualization Techniques
Nadieh BremerWith so many tools available to visualize your data, it’s easy to get stuck in thinking about chart types, always just going for that bar or line chart, without truly thinking about effectiveness. In this workshop, Nadieh will teach you how you can take a more creative and practical approach to the design of data visualization. Read more…

Rachel Andrew on Advanced CSS Layouts With Flexbox And CSS Grid
This workshop is designed for designers and developers who already have a good working knowledge of HTML and CSS. We will cover a range of CSS methods for achieving layout, from those you are safe to use right now even if you need to support older version of Internet Explorer through to things that while still classed as experimental, are likely to ship in browsers in the coming months. Read more…

Joe Leech on Psychology For UX And Product Design
Joe LeechThis workshop will provide you with a practical, hands-on way to understand how the human brain works and apply that knowledge to User Experience and product design. Learn the psychological principles behind how our brain makes sense of the world and apply that to product and user interface design. Read more…

Seb Lee-Delisle on Javascript Graphics And Animation
Seb Lee-DelisleIn this workshop, Seb will demonstrate a variety of beautiful visual effects using JavaScript and HTML5 canvas. You will learn animation and graphics techniques that you can use to add a sense of dynamism to your projects. Read more…

Vitaly Friedman on New Front-End Adventures In Responsive Design
Vitaly FriedmanWith HTTP/2, Service Workers, Responsive Images, Flexbox, CSS Grid, SVG, WAI-ARIA roles and Font Loading API now available in browsers, we all are still trying to figure out just the right strategy for designing and building responsive websites efficiently. We want to use all of these technologies and smart processes like atomic design, but how can we use them efficiently, and how do we achieve it within a reasonable amount of time? Read more…

Conference Tickets

C$699Get Your Ticket

Two days of great speakers and networking
Check all speakers →

Conf + Workshop Tickets

Save C$100 Conf + Workshop

Three days full of learning and networking
Check all workshops →


Maybe you’ve already wondered why our friend the Smashing Cat has dressed up as a movie director for SmashingConf Toronto? Well, that’s because our conference venue will be the TIFF Bell Lightbox. Located within the center of Toronto, it is one of the most iconic cinemas in the world and also the location where the Toronto Film Festival takes place. We’re thrilled to be hosted there!

TIFF Bell Lightbox, our venue in Toronto
The TIFF Bell Lightbox, usually a cinema, is the perfect place for thrillers and happy endings as the web writes them.

Why This Conference Could Be For You

SmashingConfs are a friendly and intimate experience. It’s like meeting good friends and making new ones. Friends who share their stories, ideas, and, of course, their best tips and tricks. At SmashingConf Toronto you will learn how to:

  1. Make full advantage of CSS Variables,
  2. Create fluid animation effects with Vue,
  3. Detect and resolve accessibility issues,
  4. Structure components in a pattern library when using CSS Grid,
  5. Build a stable, usable online experience,
  6. Design for cross-cultural audiences,
  7. Create effective and beautiful data visualization from scratch,
  8. Transform your designs with psychology,
  9. Help your design advance with proper etiquette,
  10. Sketch with pen and paper,
  11. … and a lot more.

Download “Convience Your Boss” PDF

We know that sometimes companies encourage their staff to attend a different conference each year. Well, we say; once you’ve found a conference you love, why stray…

Think your boss needs a little more persuasion? We’ve prepared a neat Convince Your Boss PDF that you can use to tip the scales in your favor to send you to the event.

Diversity and Inclusivity

We care about diversity and inclusivity at our events. SmashingConf’s are a safe, friendly place. We don’t tolerate any disrespect or misbehavior. We also provide student and diversity tickets.

Conference Tickets

C$699Get Your Ticket

Two days of great speakers and networking
Check all speakers →

Conf + Workshop Tickets

Save C$100 Conf + Workshop

Three days full of learning and networking
Check all workshops →

See You In Toronto!

We’d love to meet you in Toronto and spend two memorable days full of web goodness, lots of learning, and friendly people with you. An experience you won’t forget so soon. Promised.

Smashing Editorial

Source: Smashing Magazine, A Conference Without Slides: Meet SmashingConf Toronto 2018 (June 26-27)

Building A Serverless Contact Form For Your Static Site

dreamt up by webguru in Uncategorized | Comments Off on Building A Serverless Contact Form For Your Static Site

Building A Serverless Contact Form For Your Static Site

Building A Serverless Contact Form For Your Static Site

Brian Holt

Static site generators provide a fast and simple alternative to Content Management Systems (CMS) like WordPress. There’s no server or database setup, just a build process and simple HTML, CSS, and JavaScript. Unfortunately, without a server, it’s easy to hit their limits quickly. For instance, in adding a contact form.

With the rise of serverless architecture adding a contact form to your static site doesn’t need to be the reason to switch to a CMS anymore. It’s possible to get the best of both worlds: a static site with a serverless back-end for the contact form (that you don’t need to maintain). Maybe best of all, in low-traffic sites, like portfolios, the high limits of many serverless providers make these services completely free!

In this article, you’ll learn the basics of Amazon Web Services (AWS) Lambda and Simple Email Service (SES) APIs to build your own static site mailer on the Serverless Framework. The full service will take form data submitted from an AJAX request, hit the Lambda endpoint, parse the data to build the SES parameters, send the email address, and return a response for our users. I’ll guide you through getting Serverless set up for the first time through deployment. It should take under an hour to complete, so let’s get started!

The static site form, sending the message to the Lambda endpoint and returning a response to the user.
The static site form, sending the message to the Lambda endpoint and returning a response to the user.

Setting Up

There are minimal prerequisites in getting started with Serverless technology. For our purposes, it’s simply a Node Environment with Yarn, the Serverless Framework, and an AWS account.

Setting Up The Project

The Serverless Framework web site. Useful for installation and documentation.
The Serverless Framework web site. Useful for installation and documentation.

We use Yarn to install the Serverless Framework to a local directory.

  1. Create a new directory to host the project.
  2. Navigate to the directory in your command line interface.
  3. Run yarn init to create a package.json file for this project.
  4. Run yarn add serverless to install the framework locally.
  5. Run yarn serverless create --template aws-nodejs --name static-site-mailer to create a Node service template and name it static-site-mailer.

Our project is setup but we won’t be able to do anything until we set up our AWS services.

Setting Up An Amazon Web Services Account, Credentials, And Simple Email Service

The Amazon Web Services sign up page, which includes a generous free tier, enabling our project to be entirely free.
The Amazon Web Services sign up page, which includes a generous free tier, enabling our project to be entirely free.

The Serverless Framework has recorded a video walk-through for setting up AWS credentials, but I’ve listed the steps here as well.

  1. Sign Up for an AWS account or log in if you already have one.
  2. In the AWS search bar, search for “IAM”.
  3. On the IAM page, click on “Users” on the sidebar, then the “Add user” button.
  4. On the Add user page, give the user a name – something like “serverless” is appropriate. Check “Programmatic access” under Access type then click next.
  5. On the permissions screen, click on the “Attach existing policies directly” tab, search for “AdministratorAccess” in the list, check it, and click next.
  6. On the review screen you should see your user name, with “Programmatic access”, and “AdministratorAccess”, then create the user.
  7. The confirmation screen shows the user “Access key ID” and “Secret access key”, you’ll need these to provide the Serverless Framework with access. In your CLI, type yarn sls config credentials --provider aws --key YOUR_ACCESS_KEY_ID --secret YOUR_SECRET_ACCESS_KEY, replacing YOUR_ACCESS_KEY_ID and YOUR_SECRET_ACCESS_KEY with the keys on the confirmation screen.

Your credentials are configured now, but while we’re in the AWS console let’s set up Simple Email Service.

  1. Click Console Home in the top left corner to go home.
  2. On the home page, in the AWS search bar, search for “Simple Email Service”.
  3. On the SES Home page, click on “Email Addresses” in the sidebar.
  4. On the Email Addresses listing page, click the “Verify a New Email Address” button.
  5. In the dialog window, type your email address then click “Verify This Email Address”.
  6. You’ll receive an email in moments containing a link to verify the address. Click on the link to complete the process.

Now that our accounts are made, let’s take a peek at the Serverless template files.

Setting Up The Serverless Framework

Running serverless create creates two files: handler.js which contains the Lambda function, and serverless.yml which is the configuration file for the entire Serverless Architecture. Within the configuration file, you can specify as many handlers as you’d like, and each one will map to a new function that can interact with other functions. In this project, we’ll only create a single handler, but in a full Serverless Architecture, you’d have several of the various functions of the service.

The default file structure generated from the Serverless Framework containing handler.js and serverless.yml.
The default file structure generated from the Serverless Framework containing handler.js and serverless.yml.

In handler.js, you’ll see a single exported function named hello. This is currently the main (and only) function. It, along with all Node handlers, take three parameters:

  • event
    This can be thought of as the input data for the function.
  • context object
    This contains the runtime information of the Lambda function.
  • callback
    An optional parameter to return information to the caller.
// handler.js

'use strict';

module.exports.hello = (event, context, callback) => {
  const response = {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Go Serverless v1.0! Your function executed successfully!',
      input: event,

  callback(null, response);

At the bottom of hello, there’s a callback. It’s an optional argument to return a response, but if it’s not explicitly called, it will implicitly return with null. The callback takes two parameters:

  • Error error
    For providing error information for when the Lambda itself fails. When the Lambda succeeds, null should be passed into this parameter.
  • Object result
    For providing a response object. It must be JSON.stringify compatible. If there’s a parameter in the error field, this field is ignored.

Our static site will send our form data in the event body and the callback will return a response for our user to see.

In serverless.yml you’ll see the name of the service, provider information, and the functions.

# serverless.yml

service: static-site-mailer

  name: aws
  runtime: nodejs6.10

    handler: handler.hello

How the function names in serverless.yml map to handler.js.
How the function names in serverless.yml map to handler.js.

Notice the mapping between the hello function and the handler? We can name our file and function anything and as long as it maps to the configuration it will work. Let’s rename our function to staticSiteMailer.

# serverless.yml

    handler: handler.staticSiteMailer
// handler.js

module.exports.staticSiteMailer = (event, context, callback) => {

Lambda functions need permission to interact with other AWS infrastructure. Before we can send an email, we need to allow SES to do so. In serverless.yml, under provider.iamRoleStatements add the permission.

# serverless.yml

  name: aws
  runtime: nodejs6.10
    - Effect: "Allow"
        - "ses:SendEmail"
      Resource: ["*"]

Since we need a URL for our form action, we need to add HTTP events to our function. In serverless.yml we create a path, specify the method as post, and set CORS to true for security.

    handler: handler.staticSiteMailer
      - http:
          method: post
          path: static-site-mailer
          cors: true

Our updated serverless.yml and handler.js files should look like:

# serverless.yml

service: static-site-mailer

  name: aws
  runtime: nodejs6.10

    handler: handler.staticSiteMailer
      - http:
          method: post
          path: static-site-mailer
          cors: true

  name: aws
  runtime: nodejs6.10
    - Effect: "Allow"
        - "ses:SendEmail"
      Resource: ["*"]
// handler.js

'use strict';

module.exports.staticSiteMailer = (event, context, callback) => {
  const response = {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Go Serverless v1.0! Your function executed successfully!',
      input: event,

  callback(null, response);

Our Serverless Architecture is setup, so let’s deploy it and test it. You’ll get a simple JSON response.

yarn sls deploy --verbose
yarn sls invoke --function staticSiteMailer

    "statusCode": 200,
    "body": "{"message":"Go Serverless v1.0! Your function executed successfully!","input":{}}"

The return response from invoking our brand new serverless function.
The return response from invoking our brand new serverless function.

Creating The HTML Form

Our Lambda function input and form output need to match, so before we build the function we’ll build the form and capture its output. We keep it simple with name, email, and message fields. We’ll add the form action once we’ve deployed our serverless architecture and got our URL, but we know it will be a POST request so we can add that in. At the end of the form, we add a paragraph tag for displaying response messages to the user which we’ll update on the submission callback.

<form action="{{ SERVICE URL }}" method="POST">
    <input type="text" name="name" required>
    <input type="email" name="reply_to" required>
    <textarea name="message" required></textarea>
  <button type="submit">Send Message</button>
<p id="js-form-response"></p>

To capture the output we add a submit handler to the form, turn our form parameters into an object, and send stringified JSON to our Lambda function. In the Lambda function we use JSON.parse() to read our data. Alternatively, you could use jQuery’s Serialize or query-string to send and parse the form parameters as a query string but JSON.stringify() and JSON.parse() are native.

(() => {
  const form = document.querySelector('form');
  const formResponse = document.querySelector('js-form-response');

  form.onsubmit = e => {

    // Prepare data to send
    const data = {};
    const formElements = Array.from(form);
    formElements.map(input => (data[input.name] = input.value));

    // Log what our lambda function will receive

Go ahead and submit your form then capture the console output. We’ll use it in our Lambda function next.

Capturing the form data in a console log.
Capturing the form data in a console log.

Invoking Lambda Functions

Especially during development, we need to test our function does what we expect. The Serverless Framework provides the invoke and invoke local command to trigger your function from live and development environments respectively. Both commands require the function name passed through, in our case staticSiteMailer.

yarn sls invoke local --function staticSiteMailer

To pass mock data into our function, create a new file named data.json with the captured console output under a body key within a JSON object. It should look something like:

// data.json

  "body": "{"name": "Sender Name","reply_to": "sender@email.com","message": "Sender message"}"

To invoke the function with the local data, pass the --path argument along with the path to the file.

yarn sls invoke local --function staticSiteMailer --path data.json

An updated return response from our serverless function when we pass it JSON data.
An updated return response from our serverless function when we pass it JSON data.

You’ll see a similar response to before, but the input key will contain the event we mocked. Let’s use our mock data to send an email using Simple Email Service!

Sending An Email With Simple Email Service

We’re going to replace the staticSiteMailer function with a call to a private sendEmail function. For now you can comment out or remove the template code and replace it with:

// hander.js

function sendEmail(formData, callback) {
  // Build the SES parameters
  // Send the email

module.exports.staticSiteMailer = (event, context, callback) => {
  const formData = JSON.parse(event.body);

  sendEmail(formData, function(err, data) {
    if (err) {
      console.log(err, err.stack);
    } else {

First, we parse the event.body to capture the form data, then we pass it to a private sendEmail function. sendEmail is responsible for sending the email, and the callback function will return a failure or success response with err or data. In our case, we can simply log the error or data since we’ll be replacing this with the Lambda callback in a moment.

Amazon provides a convenient SDK, aws-sdk, for connecting their services with Lambda functions. Many of their services, including SES, are part of it. We add it to the project with yarn add aws-sdk and import it into the top the handler file.

// handler.js

const AWS = require('aws-sdk');
const SES = new AWS.SES();

In our private sendEmail function, we build the SES.sendEmail parameters from the parsed form data and use the callback to return a response to the caller. The parameters require the following as an object:

  • Source
    The email address SES is sending from.
  • ReplyToAddresses
    An array of email addresses added to the reply to the field in the email.
  • Destination
    An object that must contain at least one ToAddresses, CcAddresses, or BccAddresses. Each field takes an array of email addresses that correspond to the to, cc, and bcc fields respectively.
  • Message
    An object which contains the Body and Subject.

Since formData is an object we can call our form fields directly like formData.message, build our parameters, and send it. We pass your SES-verified email to Source and Destination.ToAddresses. As long as the email is verified you can pass anything here, including different email addresses. We pluck our reply_to, message, and name off our formData object to fill in the ReplyToAddresses and Message.Body.Text.Data fields.

// handler.js
function sendEmail(formData, callback) {
  const emailParams = {
    Source: 'your_email@example.com', // SES SENDING EMAIL
    ReplyToAddresses: [formData.reply_to],
    Destination: {
      ToAddresses: ['your_email@example.com'], // SES RECEIVING EMAIL
    Message: {
      Body: {
        Text: {
          Charset: 'UTF-8',
          Data: `${formData.message}nnName: ${formData.name}nEmail: ${formData.reply_to}`,
      Subject: {
        Charset: 'UTF-8',
        Data: 'New message from your_site.com',

  SES.sendEmail(emailParams, callback);

SES.sendEmail will send the email and our callback will return a response. Invoking the local function will send an email to your verified address.

yarn sls invoke local --function testMailer --path data.json

The return response from SES.sendEmail when it succeeds.
The return response from SES.sendEmail when it succeeds.

Returning A Response From The Handler

Our function sends an email using the command line, but that’s not how our users will interact with it. We need to return a response to our AJAX form submission. If it fails, we should return an appropriate statusCode as well as the err.message. When it succeeds, the 200 statusCode is sufficient, but we’ll return the mailer response in the body as well. In staticSiteMailer we build our response data and replace our sendEmail callback function with the Lambda callback.

// handler.js

module.exports.staticSiteMailer = (event, context, callback) => {
  const formData = JSON.parse(event.body);

  sendEmail(formData, function(err, data) {
    const response = {
      statusCode: err ? 500 : 200,
      headers: {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': 'https://your-domain.com',
      body: JSON.stringify({
        message: err ? err.message : data,

    callback(null, response);

Our Lambda callback now returns both success and failure messages from SES.sendEmail. We build the response with checks if err is present so our response is consistent. The Lambda callback function itself passes null in the error argument field and the response as the second. We want to pass errors onwards, but if the Lambda itself fails, its callback will be implicitly called with the error response.

In the headers, you’ll need to replace Access-Control-Allow-Origin with your own domain. This will prevent any other domains from using your service and potentially racking up an AWS bill in your name! And I don’t cover it in this article, but it’s possible to set-up Lambda to use your own domain. You’ll need to have an SSL/TLS certificate uploaded to Amazon. The Serverless Framework team wrote a fantastic tutorial on how to do so.

Invoking the local function will now send an email and return the appropriate response.

yarn sls invoke local --function testMailer --path data.json

The return response from our serverless function, containing the SES.sendEmail return response in the body.
The return response from our serverless function, containing the SES.sendEmail return response in the body.

Calling The Lambda Function From The Form

Our service is complete! To deploy it run yarn sls deploy -v. Once it’s deployed you’ll get a URL that looks something like https://r4nd0mh45h.execute-api.us-east-1.amazonaws.com/dev/static-site-mailer which you can add to the form action. Next, we create the AJAX request and return the response to the user.

(() => {
  const form = document.querySelector('form');
  const formResponse = document.querySelector('js-form-response');

  form.onsubmit = e => {

    // Prepare data to send
    const data = {};
    const formElements = Array.from(form);
    formElements.map(input => (data[input.name] = input.value));

    // Log what our lambda function will receive

    // Construct an HTTP request
    var xhr = new XMLHttpRequest();
    xhr.open(form.method, form.action, true);
    xhr.setRequestHeader('Accept', 'application/json; charset=utf-8');
    xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');

    // Send the collected data as JSON

    // Callback function
    xhr.onloadend = response => {
      if (response.target.status === 200) {
        // The form submission was successful
        formResponse.innerHTML = 'Thanks for the message. I’ll be in touch shortly.';
      } else {
        // The form submission failed
        formResponse.innerHTML = 'Something went wrong';

In the AJAX callback, we check the status code with response.target.status. If it’s anything other than 200 we can show an error message to the user, otherwise let them know the message was sent. Since our Lambda returns stringified JSON we can parse the body message with JSON.parse(response.target.response).message. It’s especially useful to log the error.

You should be able to submit your form entirely from your static site!

The static site form, sending the message to the Lambda endpoint and returning a response to the user.
The static site form, sending the message to the Lambda endpoint and returning a response to the user.

Next Steps

Adding a contact form to your static is easy with the Serverless Framework and AWS. There’s room for improvement in our code, like adding form validation with a honeypot, preventing AJAX calls for invalid forms and improving the UX if the response, but this is enough to get started. You can see some of these improvements within the static site mailer repo I’ve created. I hope I’ve inspired you to try out Serverless yourself!

Smashing Editorial
(lf, ra, il)

Source: Smashing Magazine, Building A Serverless Contact Form For Your Static Site

A Guide To The State Of Print Stylesheets In 2018

dreamt up by webguru in Uncategorized | Comments Off on A Guide To The State Of Print Stylesheets In 2018

A Guide To The State Of Print Stylesheets In 2018

A Guide To The State Of Print Stylesheets In 2018

Rachel Andrew

Today, I’d like to return to a subject that has already been covered in Smashing Magazine in the past — the topic of the print stylesheet. In this case, I am talking about printing pages directly from the browser. It’s an experience that can lead to frustration with enormous images (and even advertising) being printed out. Just sometimes, however, it adds a little bit of delight when a nicely optimized page comes out of the printer using a minimum of ink and paper and ensuring that everything is easy to read.

This article will explore how we can best create that second experience. We will take a look at how we should include print styles in our web pages, and look at the specifications that really come into their own once printing. We’ll find out about the state of browser support, and how to best test our print styles. I’ll then give you some pointers as to what to do when a print stylesheet isn’t enough for your printing needs.

Key Places For Print Support

If you still have not implemented any print styles on your site, there are a few key places where a solid print experience will be helpful to your users. For example, many users will want to print a transaction confirmation page after making a purchase or booking even if you will send details via email.

Any information that your visitor might want to use when away from their computer is also a good candidate for a print stylesheet. The most common thing that I print are recipes. I could load them up on my iPad but it is often more convenient to simply print the recipe to pop onto the fridge door while I cook. Other such examples might be directions or travel information. When traveling abroad and not always having access to data these printouts can be invaluable.

Reference materials of any sort are also often printed. For many people, being able to make notes on paper copies is the way they best learn. Again, it means the information is accessible in an offline format. It is easy for us to wonder why people want to print web pages, however, our job is often to make content accessible — in the best format for our visitors. If that best format is printed to paper, then who are we to argue?

Why Would This Page Be Printed?

A good question to ask when deciding on the content to include or hide in the print stylesheet is, “Why is the user printing this page?” Well, maybe there’s a recipe they’d like to follow while cooking in the kitchen or take along with them when shopping to buy ingredients. Or they’d like to print out a confirmation page after purchasing a ticket as proof of booking. Or perhaps they’d like a receipt or invoice to be printed (or printed to PDF) in order to store it in the accounts either as paper or electronically.

Considering the use of the printed document can help you to produce a print version of your content that is most useful in the context in which the user is in when referring to that print-out.


Once we have decided to include print styles in our CSS, we need to add them to our workflow to ensure that when we make changes to the layout we also include those changes in the print version.

Adding Print Styles To A Page

To enable a “print stylesheet” what we are doing is telling the browser what these CSS rules are for when the document is printed. One method of doing this is to link an additional stylesheet by using the <link> element.

<link media="print" href="print.css">

This method does keep your print styles separate from everything else which you might consider to be tidier, however, that has downsides.

The linked stylesheet creates an additional request to the server. In addition, that nice, neat separation of print styles from other styles can have a downside. While you may take care to update the separate styles before going live, the stylesheet may find itself suffering due to being out of sight and therefore out of mind — ultimately becoming useless as features are added to the site but not reflected in the print styles.

The alternate method for including print styles is to use @media in the same way that you includes CSS for certain breakpoints in your responsive design. This method keeps all of the CSS together for a feature. Styles for narrow to wide breakpoints, and styles for print. Alongside Feature Queries with @supports, this encourages a way of development that ensures that all of the CSS for a design feature is kept and maintained together.

@media print {

Overwriting Screen CSS Or Creating Separate Rules

Much of the time you are likely to find that the CSS you use for the screen display works for print with a few small adjustments. Therefore you only need to write CSS for print, for changes to that basic CSS. You might overwrite a font size, or family, yet leave other elements in the CSS alone.

If you really want to have completely separate styles for print and start with a blank slate then you will need to wrap the rest of your site styles in a Media Query with the screen keyword.

@media screen {

On that note, if you are using Media Queries for your Responsive Design, then you may have written them for screen.

@media screen and (min-width: 500px) {

If you want these styles to be used when printing, then you should remove the screen keyword. In practice, however, I often find that if I work “mobile first” the single column mobile layout is a really good starting point for my print layout. By having the media queries that bring in the more complex layouts for screen only, I have far less overwriting of styles to do for print.

Add Your Print Styles To Your Pattern Libraries And Style Guides

To help ensure that your print styles are seen as an integral part of the site design, add them to your style guide or pattern library for the site if you have one. That way there is always a reminder that the print styles exist, and that any new pattern created will need to have an equivalent print version. In this way, you are giving the print styles visibility as a first-class citizen of your design system.

Basics Of CSS For Print

When it comes to creating the CSS for print, there are three things you are likely to find yourself doing. You will want to hide, and not display content which is irrelevant when printed. You may also want to add content to make a print version more useful. You might also want to adjust fonts or other elements of your page to optimize them for print. Let’s take a look at these techniques.

Hiding Content

In CSS the method to hide content and also prevent generation of boxes is to use the display property with a value of none.

.box {
  display: none;

Using display: none will collapse the element and all of its child elements. Therefore, if you have an image gallery marked up as a list, all you would need to do to hide this when printed is to set display: none on the ul.

Things that you might want to hide are images which would be unnecessary when printed, navigation, advertising panels and areas of the page which display links to related content and so on. Referring back to why a user might print the page can help you to decide what to remove.

Inserting Content

There might be some content that makes sense to display when the page is printed. You could have some content set to display: none in a screen stylesheet and show it in your print stylesheet. Additionally, however, you can use CSS to expose content not normally output to the screen. A good example of this would be the URL of a link in the document. In your screen document, a link would normally show the link text which can then be clicked to visit that new page or external website. When printed links cannot be followed, however, it might be useful if the reader could see the URL in case they wished to visit the link at a later time.

We achieve this by using CSS Generated Content. Generated Content gives you a way to insert content into your document via CSS. When printing, this becomes very useful.

You can insert a simple text string into your document. The next example targets the element with a class of wrapper and inserts before it the string, “Please see www.mysite.com for the latest version of this information.”

.wrapper::after {
  content: "Please see www.mysite.com for the latest version of this information.";

You can insert things that already exist in the document however, an example would be the content of the link href. We add Generated Content after each instance of a with an attribute of href and the content we insert is the value of the href attribute – which will be the link.

a[href]:after {
  content: " (" attr(href) ")";

You could use the newer CSS :not selector to exclude internal links if you wished.

a[href^="http"]:not([href*="example.com"]):after {
  content: " (" attr(href) ")";

There are some other useful tips like this in the article, “I Totally Forgot About Print Stylesheets”, written by Manuel Matuzovic.

Advanced Print Styling

If your printed version fits neatly onto one page then you should be able to create a print stylesheet relatively simply by using the techniques of the last section. However, once you have something which prints onto multiple pages (and particularly if it contains elements such as tables or figures), you may find that items break onto new pages in a suboptimal manner. You may also want to control things about the page itself, e.g. changing the margin size.

CSS does have a way to do these things, however, as we will see, browser support is patchy.

Paged Media

The CSS Paged Media Specification opens with the following description of its role.

“This CSS module specifies how pages are generated and laid out to hold fragmented content in a paged presentation. It adds functionality for controlling page margins, page size and orientation, and headers and footers, and extends generated content to enable page numbering and running headers/footers.”

The screen is continuous media; if there is more content, we scroll to see it. There is no concept of it being broken up into individual pages. As soon as we are printing we output to a fixed size page, described in the specification as paged media. The Paged Media specification doesn’t deal with how content is fragmented between pages, we will get to that later. Instead, it looks at the features of the pages themselves.

We need a way to target an individual page, and we do this by using the @page rule. This is used much like a regular selector, in that we target @page and then write CSS to be used by the page. A simple example would be to change the margin on all of the pages created when you print your document.

@page {
  margin: 20px;

You can target specific pages with :left and :right spread pseudo-class selectors. The first page can be targeted with the :first pseudo-class selector and blank pages caused by page breaks can be selected with :blank. For example, to set a top margin only on the first page:

@page :first {
  margin-top: 250pt;

To set a larger margin on the right side of a left-hand page and the left side of a right-hand page:

@page :left {
  margin-right: 200pt;
@page :right {
  margin-left: 200pt;

The specification defines being able to insert content into the margins created, however, no browser appears to support this feature. I describe this in my article about creating stylesheets for use with print-specific user agents, Designing For Print With CSS.

CSS Fragmentation

Where the Paged Media module deals with the page boxes themselves, the CSS Fragmentation Module details how content breaks between fragmentainers. A fragmentainer (or fragment container) is a container which contains a portion of a fragmented flow. This is a flow which, when it gets to a point where it would overflow, breaks into a new container.

The contexts in which you will encounter fragmentation currently are in paged media, therefore when printing, and also when using Multiple-column layout and your content breaks between column boxes. The Fragmentation specification defines various rules for breaking, CSS properties that give you some control over how content breaks into new fragments, in these contexts. It also defines how content breaks in the CSS Regions specification, although this isn’t something usable cross-browser right now.

And, speaking of browsers, fragmentation is a bit of a mess in terms of support at the moment. The browser compatibility tables for each property on MDN seem to be accurate as to support, however testing use of these properties carefully will be required.

Older Properties From CSS2

In addition to the break-* properties from CSS Fragmentation Level 3, we have page-break-* properties which came from CSS2. In spec terms, these have been superseded by the newer break-* properties, as these are more generic and can be used in the different contexts breaking happens. There isn’t much difference between a page and a multicol break. However, in terms of browser support, there is better browser support for the older properties. This means you may well need to use those at the current time to control breaking. Browsers that implement the newer properties are to alias the older ones rather than drop them.

In the examples that follow, I shall show both the new property and the old one where it exists.

break-before & break-after

These properties deal with breaks between boxes, and accept the following values, with the initial value being auto. The final four values do not apply to paged media, instead being for multicol and regions.

  • auto
  • avoid
  • avoid-page
  • page
  • left
  • right
  • recto
  • verso
  • avoid-column
  • column
  • avoid-region
  • region

The older properties of page-break-before and page-break-after accept a smaller range of values.

  • auto
  • always
  • avoid
  • left
  • right
  • inherit

To always cause a page break before an h2 element, you would use the following:

h2 {
  break-before: page;

To avoid a paragraph being detached from the heading immediately preceding it:

h2, h3 {
  break-after: avoid-page;

The older page-break-* property to always cause a page break before an h2:

h2 {
  page-break-before: always;

To avoid a paragraph being detached from the heading immediately preceding it:

h2, h3{
  page-break-after: avoid;

On MDN find information and usage examples for the properties:


This property controls breaks inside boxes and accepts the values:

  • auto
  • avoid
  • avoid-page
  • avoid-column
  • avoid-region

As with the previous two properties, there is an aliased page-break-inside from CSS2, which accepts the values:

  • auto
  • avoid
  • inherit

For example, perhaps you have a figure or a table and you don’t want a half of it to end up on one page and the other half on another page.

figure {
  break-inside: avoid;

And when using the older property:

figure {
  page-break-inside: avoid;


Orphans And Widows

The Fragmentation specification also defines the properties orphans and widows. The orphans property defines how many lines can be left at the bottom of the first page when content such as a paragraph is broken between two pages. The widows property defines how many lines may be left at the top of the second page.

Therefore, in order to prevent ending up with a single line at the end of a page and a single line at the top the next page, you can use the following:

p {
  orphans: 2;
  widows: 2;

The widows and orphans properties are well supported (the missing browser implementation being Firefox).



The final property defined in the Fragmentation module is box-decoration-break. This property deals with whether borders, margins, and padding break or wrap the content. The values it accepts are:

  • slice
  • clone

For example, if my content area has a 10-pixel grey border and I print the content, then the default way that this will print is that the border will continue onto each page, however, it will only wrap at the end of the content. So we get a break before going to the next page and continuing.

The border does not wrap each page and so breaks between pages
The border does not wrap each page and so breaks between pages

If I use box-decoration-break: clone, the border and any padding and margin will complete on each page, thus giving each page a grey border.

The border wraps each individual page
The border wraps each individual page

Currently, this only works for Paged Media in Firefox, and you can find out more about box-decoration-break on MDN.

Browser Support

As already mentioned, browser support is patchy for Paged Media and Fragmentation. Where Fragmentation is concerned, an additional issue is that breaking has to be specified and implemented for each layout method. If you were hoping to use Flexbox or CSS Grid in print stylesheets, you will probably be disappointed. You can check out the Chrome bugs for Flexbox and for Grid.

The best suggestion I can give right now is to keep your print stylesheets reasonably simple. Add fragmentation properties — including both the old page-break-* properties as well as the new properties. However, accept that these may well not work in all browsers. And, if you find lack of browser support frustrating, raise these issues with browsers or vote for already raised issues. Fragmentation, in particular, should be treated as a suggestion rather than a command, even where it is supported. It would be possible to be so specific about where and when you want things to break that it is almost impossible to lay out the pages. You should assume that sometimes you may get suboptimal breaking.

Testing Print Stylesheets

Testing print stylesheets can be something of a bore, typically requiring using print preview or printing to a PDF repeatedly. However, browser DevTools have made this a little easier for us. Both Chrome and Firefox have a way to view the print styles only.


Open the Developer Toolbar then type media emulate print at the prompt.

Typing media emulate print
Emulating print styles in Firefox


Open DevTools, click on the three dots icon and then select “More Tools” and “Rendering”. You can then select print under Emulate CSS Media.

Chrome DevTools emulate print media
Emulating print styles in Chrome

This will only be helpful in testing changes to the CSS layout, hidden or generated content. It can’t help you with fragmentation — you will need to print or print to PDF for that. However, it will save you a few round trips to the printer and can help you check as you develop new parts of the site that you are still hiding and showing the correct things.

What To Do When A Print Stylesheet Isn’t Enough

In an ideal world, browsers would have implemented more of the Paged Media specification when printing direct from the browser, and fragmentation would be more thoroughly implemented in a consistent way. It is certainly worth raising the bugs that you find when printing from the browser with the browsers concerned. If we don’t request these things are fixed, they will remain low priority to be fixed.

If you do need to have a high level of print support and want to use CSS, then currently you would need to use a print-specific User Agent, such as Prince. I detail how you can use CSS to format books when outputting to Prince in my article “Designing For Print With CSS.”

Prince is also available to install on your server in order to generate nicely printed documents using CSS on the web, however, it comes at a high price. An alternative is a server like DocRaptor who offer an API on top of the Prince rendering engine.

There are open-source HTML- and CSS-to-PDF generators such as wkhtmltopdf, but most use browser rendering engines to create the print output and therefore have the same limitations as browsers when it comes to implementing the Paged Media and Fragmentation specifications. An exception is WeasyPrint which seems to have its own implementation and supports slightly different features, although is not in any way as full-featured as something like Prince.

You will find more information about user agents for print on the print-css.rocks site.

Other Resources

Due to the fact that printing from CSS has really moved on very little in the past few years, many older resources on Smashing Magazine and elsewhere are still valid. Some additional tips and tricks can be found in the following resources. If you have discovered a useful print workflow or technical tip, then add it to the comments below.

Smashing Editorial

Source: Smashing Magazine, A Guide To The State Of Print Stylesheets In 2018

Collective #411

dreamt up by webguru in Uncategorized | Comments Off on Collective #411



A micro service for getting a user avatar across multiple social services by providing a username, email or domain as input.

Check it out



A visualization of various sorting algorithms with “async” powered animations. By Aaron Bird.

Check it out


From Our Blog

Particle Effects for Buttons

A little library that can be used for bursting particles effects. The idea is to disintegrate an element into particles and make it disappear (or vice versa).

Check it out

Collective #411 was written by Pedro Botelho and published on Codrops.

Source: Codrops, Collective #411