Monday, 18 May 2015

Wednesday, 29 April 2015

Taming CSS

Observation 1: Web developers, in general, don’t know CSS as well as they should.

Observation 2: There aren’t really any good roadmaps for learning all the essentials of CSS.

There are great resources for the basics, for styling, for code organization/architecture, for advanced tricks. But to work through them all, you get a lot of overlap, and they still leave you with missing gaps in your knowledge. Often, with CSS, you don’t know what you don’t know, and that makes it hard to move forward. My hope is to fix that, by putting them all together in one place.

Announcing Taming CSS, a CSS book for web developers.

Thursday, 2 May 2013

So you have to write some CSS

I get it. You’re a python/ruby/java engineer, and you’re building your awesome webapp. The problem is, a webapp needs CSS. And you know… just enough to realize how little you know.

CSS is complicated. It’s not a programming language strictly speaking, but you would probably rather it was; you have learned new languages in the past. But CSS is off in its own little world, a wildly complicated set of rules. Sure, you can usually make a page do what you want. Other times leave you completely baffled and out of your element. You wish you had time to read up on how to do it well, but you have code that needs writing.

So here you go. Here are a handful of nice and easy rules for you. Follow these, and your CSS should be… more presentable than if you didn’t. It will be more maintainable into the future, and that front end engineer your startup will hire as soon as it can afford to will thank you. (Because that engineer may be me!)

  • Make your selectors as generic as possible — Use the shortest selector you can, and apply rules as universally as is reasonable. Say you’re adding a dialog box on your billing page. Don’t specify #billing .dialog if you’ll likely want the same CSS for dialog boxes later on; just use .dialog. (This isn’t completely absolute: if you know you’re dealing with an exception to the rule, keep it specific.)
  • Don’t use !important — Like tribbles, these things are born pregnant, and will multiply faster than you can imagine. Instead, take five minutes to learn how selector specificity works and use the browser dev tools to see which rule is overriding the one you want.
  • Minimize duplication — You organize your code into reusable functions; do the same with your CSS. This is kind of a corollary to the two points above.

    Say you have generic dialog box .dialog { color: blue; }, which is overridden on your billing page with a special rule #billing .dialog { color: red; }. If you later find yourself adding another rule like #account .dialog { color: red; }, STOP!

    Instead, make something reusable: .dialog-important { color: red; }. Then you don’t need to touch your CSS yet again when you encounter a third page that needs the same thing!

  • CSS must be refactored — Just like your code, CSS rots. Don’t be afraid to tear down and restructure as things evolve.

Sunday, 24 February 2013

The DOM as Global State

Let’s look at a common scenario: somewhere, deep inside your module, you need to do something to the DOM. Maybe something like, $("#my-id").show();. Find an element; make it visible. It seems like no big deal, but I want to make an observation:

You just used a global variable.

The DOM is a global state. This is stupidly obvious when I say it this way, but I have never thought about it in these terms before. I’ve seen a lot of code–and written a lot of code–littered with jQuery selectors grabbing elements from all over the page and manipulating them.

Using global state is generally considered an anti-pattern. And yet, I would venture the vast majority of web applications in the wild use it liberally: modules full of functions that reach into the DOM and manipulate various elements. In most applications, this sort of thing would be considered a side-effect. The readability and testability of code are compromised, because there’s no real way to know what a certain function does unless you also know the current state of specific elements on the page. And yet in the web world, it is commonplace.

Considering how much effort we’ve spent getting around the global namespacing problems of JavaScript, it’s pretty ridiculous to realize we’re not much further than where we started. Let’s fix that.

Dependency Injection

Thankfully, the solution here is the same as any other code: Pass the relevant data in as a function parameter. Then your functions and objects can do all they need to do, while acting only on items they are given references to. So instead of this:

function foo () {
    $("#my-div .baz").somethingElse();

I have begun structuring my code more like this:

function foo (element) {

(For an example using the module pattern, see my answer to this Stack Overflow question. It’s still contrived, but a little bit closer to real-world code. In more complex modules, I generally pass the element into an init() function or an object constructor)

Yes, you still have to perform the global selector, but now the real meat of your code is not dependent upon it. Your code is also able to handle more changes the the DOM without breaking, and in your unit tests, you can now pass in a mocked up element, instead of setting up a specific global state.

You stopped using global variables when you picked up the module pattern and other namespacing tactics. Now stop using them inside your namespaces as well.

Wednesday, 6 February 2013

My Very Favorite Things

I’ve come across two articles in the past several days that take critical views against something I love and believe in. JavaScript is the new Perl is skeptical of the recent surge in the popularity of Javascript. Five Reasons Why Responsive Design is Wrong for Your Business is skeptical of RWD.

Obviously, being a front end web developer, my someone-is-wrong-on-the-internet alarms started going off, and I “had” to comment on each. Both authors were kind enough to respond to my comments graciously (and left me hoping I didn’t come off as too much of a jerk). They also both clarified their stance a little to say, essentially, “just because tool X is cool and popular right now, doesn’t mean it’s the right answer for everything.” And as much as I love Javascript and RWD, I had to agree.

It’s easy to get absorbed in the excitement of new shiny things. It’s also good to step back and make sure you aren’t blinded to their limits.

It’s also very refreshing to see reasoned discourse on the internet. I don’t think there can be too much hype behind that.