Best practices

shame.css, or documenting your hacks

You’d be forgiven for thinking the point of this whole exercise is to shame the developers (you can always pick a name other than shame.css) but it’s really not. I am well aware of (and responsible for) hacks and quick fixes; your product owner doesn’t care if you used an !important, they just want the new feature out of the door. Hacks happen, fact.

shame.css is jokingly titled to make it a little light-hearted whilst also indicating that anything in there is a bit of a shame; a shame to have to have done, a shame to pollute the codebase with and so on…

By isolating all your hacks and bodge-jobs in their own file you can really easily keep tabs on them; isolating them isn’t to shame the developers, not at all, it’s merely to make the team aware of them and make them painfully, unmissably obvious.

The rules

Obviously you need some kind of rules and criteria:

  1. If it’s a hack, it goes in shame.css.
  2. Document all hacks fully:
    1. What part of the codebase does it relate to?
    2. Why was this needed?
    3. How does this fix it?
    4. How might you fix it properly, given more time?
  3. Do not blame the developer; if they explained why they had to do it then their reasons are probably (hopefully) valid.
  4. Try and clean shame.css up when you have some down time.
    1. Even better, get a tech-debt story in which you can dedicate actual sprint time to it.

This certainly seems like a good approach. That said, I personally prefer to have everything related to a component living with the component, but documented as a hack, possibly searchable via some sort of comment tag, like @hack <description>.

Material Design as gospel

“We went out with the original Material Design with what was a very fresh and very opinionated style. We wanted to get attention,” says Matias Duarte, the head of the Material Design group at Google. “And it was so strong and so opinionated and so successful, a lot of both the designer and developer community took it as a ‘gospel,’ perhaps is the right word.”


”We spent two years telling people ‘this is how to make Material yours,’” Duarte says, “and it didn’t work.” But he doesn’t blame developers. The problem is that Google didn’t provide the right tools. Specifically, he believes Google’s guidelines didn’t separate out the styling of the button from its function. Google wants apps to work like other Material Design apps, but it never meant for all Android apps to look like each other.

Global Accessibility Awareness Day

May 17th is Global Accessibility Awareness Day. See the source link for more. The participate page is a great list of things to test for and be aware of.

The target audience of GAAD is the design, development, usability, and related communities who build, shape, fund and influence technology and its use. While people may be interested in the topic of making technology accessible and usable by persons with disabilities, the reality is that they often do not know how or where to start. Awareness comes first.

Error logging - Robust Client-Side JavaScript

The standard approach is to monitor all exceptions on a page and to handle them centrally, for example using window.onerror. Then gather a bunch of context information and send an incident report to a log server. That server stores all reports, makes them accessible using an interface and probably sends an email to the developer.

Here is a simple global error reporter:

Code language: JavaScript

window.onerror = function(message, file, line, column, error) {
	var errorToReport = {
		type: error ? error.type : '',
		message: message,
		file: file,
		line: line,
		column: column,
		stack: error ? error.stack : '',
		userAgent: navigator.userAgent,
		href: location.href
	var url = '/error-reporting?error=' +
	var image = new Image();
	image.src = url;

This code sends a report to the address /error-reporting using a GET request.

The example above is not enough. It is not that easy to compile a meaningful, cross-browser report from an exception. Tools like TraceKit and StackTrace.js help to extract meaning from exceptions.

Quoted content by Mathias Schäfer is licensed under CC BY-SA. See the other snippets from Robust Client-Side JavaScript.

Strict Mode - Robust Client-Side JavaScript

ECMAScript 5 (2009) started to deprecate error-prone programming practices. But it could not just change code semantics from one day to the next. This would have broken most existing code.

In order to maintain backwards compatibility, ECMAScript 5 introduces the Strict Mode as an opt-in feature. In Strict Mode, common pitfalls are removed from the language or throw visible exceptions. Previously, several programming mistakes and bogus code were ignored silently. The Strict Mode turns these mistakes into visible errors – see failing fast.

Enable the Strict Mode by placing a marker at the beginning of a script:

Code language: JavaScript

'use strict';
window.alert('This code is evaluated in Strict Mode! Be careful!');

Or at the beginning of a function:

Code language: JavaScript

function strictFunction() {
	'use strict';
	window.alert('This function is evaluated in Strict Mode! Be careful!');

Syntax-wise, 'use strict'; is simply an expression statement with a string literal. This code does not do anything when evaluated. It is a meaningful marker for browsers that support ECMAScript 5, and innocuous code for browsers that do not.

Quoted content by Mathias Schäfer is licensed under CC BY-SA. See the other snippets from Robust Client-Side JavaScript.

Duck typing - Robust Client-Side JavaScript

As a weakly typed language, JavaScript performs implicit type conversion so developers do not need to think much about types. The concept behind this is called duck typing: “If it walks like a duck and quacks like a duck, it is a duck.”

typeof and instanceof check what a value is and where it comes from. As we have seen, both operators have serious limitations.

In contrast, duck typing checks what a value does and provides. After all, you are not interested in the type of a value, you are interested in what you can do with the value.


Duck typing would ask instead: What does the function do with the value? Then check whether the value fulfills the needs, and be done with it.


This check is not as strict as instanceof, and that is an advantage. A function that does not assert types but object capabilities is more flexible.

For example, JavaScript has several types that do not inherit from Array.prototype but walk and talk like arrays: Arguments, HTMLCollection and NodeList. A function that uses duck typing is able to support all array-like types.

Quoted content by Mathias Schäfer is licensed under CC BY-SA. See the other snippets from Robust Client-Side JavaScript.

Conditional statements and truthy values - Robust Client-Side JavaScript

The key to robust JavaScript is asking “if” a lot. During the concept phase, ask “what if”. In the code, ask if to handle different cases differently.

The if statement, or conditional statement, consists of a condition, a code block and an optional second code block.

Code language: JavaScript

if (condition) {
	// …
} else {
	// …

When an if statement is evaluated, first the condition expression is evaluated. The result of the expression is then converted into a boolean value, true or false. If this result is true, the first code block is executed, otherwise the second block, if given.

Most likely, this is not new to you. The reason we are revisiting it is the conversion into boolean. It means you can use a condition expression that does not necessarily evaluate to a boolean value. Other types, like Undefined, Null, String or Object are possible. For example, it is possible to write if ("Hello!") {…}.

If you rely on the implicit conversion, you should learn the conversion rules. ECMAScript defines an internal function ToBoolean for this purpose. In our code, we can use the public Boolean() function to convert a value into boolean. This delegates to the internal ToBoolean function.

To illustrate the conversion, imagine that

Code language: JavaScript

if (condition) {
	// …
} else {
	// …

is a short version of

Code language: JavaScript

if (Boolean(condition) === true) {
	// …
} else {
	// …

Values are called truthy when ToBoolean converts them into true. Values are called falsy when ToBoolean converts them into false.

The way ToBoolean works is simple, but with a twist. Let us quote the ECMAScript specification which is quite readable for once:

ToBoolean Conversions
Argument Type Result
Undefined Return false.
Null Return false.
Boolean Return argument.
Number If argument is +0, -0, or NaN, return false; otherwise return true.
String If argument is the empty String (its length is zero), return false; otherwise return true.
Symbol Return true.
Object Return true.

As you can see, most types have a clear boolean counterpart. All objects, including functions, dates, regular expressions and errors, are truthy. The two types denoting emptiness, undefined and null, are falsy.

For numbers and strings though, it is complicated. Numbers are truthy except for zeros and NaN. Strings are truthy except for empty strings.

Quoted content by Mathias Schäfer is licensed under CC BY-SA. See the other snippets from Robust Client-Side JavaScript.

NaN is contagious - Robust Client-Side JavaScript

NaN is a dangerous beast. NaN is a special value that means “not a number”, but in fact it is a number you can calculate with.

NaN is contagious. All calculations involving NaN fail silently, yielding NaN: 5 + NaN makes NaN, Math.sqrt(NaN) produces NaN. All comparisons with NaN yield false: 5 > NaN is false, 5 < NaN is also false. 5 === NaN is false, NaN === NaN is also false.

If a NaN slips into your logic, it is carried through the rest of the program until the user sees a “NaN” appearing in the interface. It is hard to find the cause of a NaN since the place where it appears can be far from the place that caused it. Typically, the cause of a NaN is an implicit type conversion. My advice is to raise the alarm as soon as you see a NaN.

Quoted content by Mathias Schäfer is licensed under CC BY-SA. See the other snippets from Robust Client-Side JavaScript.