The “how did I screw this up?” bias

I love TechWell. They’re an online publication covering all stages of the software development lifecycle. Their articles are heavy on soft-skills, and I’ve found them very insightful, but they don’t seem to be too popular amongst software developers in general (based on the number of times I’ve seen them cited on HN, Reddit, Twitter, or in conversation).

Anyway, they recently posted a personal/process improvement article about various cognitive biases. I’m fascinated by these illogical tendencies in day-to-day human thinking, and I notice them a lot, in myself and in others. After reading the article, I added this comment, informally describing a “self-accountability bias” I’ve noticed.



Another debilitating cognitive tendency I strive to avoid is a form of “hasty generalization” (which is when a generalization is made about a population from a statistically insignificant sample, perhaps due to confirmation bias).

This particularly debilitating form is compounded by negativity bias. When it occurs, the “population” is the observer himself, and the sample consists of personal experiences connected to some relatively large, costly expectation or goal that is not met. The failure is compounded by the costs (both real and opportunistic) and can instigate a strong negativity bias. The generalizations are made about their own decisions, behaviors or traits. For example, when launching a startup, entrepreneurs are forced to make dozens of complex decisions with imperfect information. All of these decisions could be reasonably rational, but if the venture fails, the entrepreneur might conclude that the decisions were wrong and illogically “learn” not to repeat such decisions. Another example can spring from a failed long-term romantic relationship. Much time, energy, and consideration is put into such a relationship, and if it ultimately fails, a participant might be driven to attribute the failure to certain behaviors or traits of theirs, however illogical.

(The problem is not that individuals shouldn’t learn anything from these experiences, it’s that they tend to identify lessons that are based on unique circumstances but to hold them in broader circumstances. Identifying the useful lessons from complex failures is another matter.)

The extreme negativity of the experience can cloud their recognition of its complexity and uniqueness, and set them on a path of learning anything they can from it. These lessons can improperly deter them from goals or situations they can successfully manage. Perhaps this is the opposite extreme of hindsight bias, but the damage can be just as bad if not worse. A way to avoid this is to remind oneself of the uniqueness of the situation and that one acted in accordance with their morals, worldview, and perhaps limited knowledge of the situation; to think of times when suspect behaviors were actually beneficial to oneself; to acknowledge the variables beyond one’s control that played a role in the failure; and to reaffirm (or define) one’s morals and worldview to support a steady-handed outlook.

Programmatic Advertising

strawberries and milkProgrammatic what now?! Who-how advertising?!

I’m still a little fuzzy on the details myself, but it’s a topic I’m trying to catch up on quickly. What follows is my current, nascent understanding. (I hereby disclaim any assertion of truth, factual correctness, or entertainment value.) Programmatic advertising is the nouvelle vague of online advertising, that seeks to cut out the middleman while enriching a publisher’s ad inventory to increase margins for publishers.

Okay, some background. Online advertising traditionally works in one of two ways, both involving media and content publishers (who have empty ad space on their webpages, and are AKA sellers), who sell their ad inventory (i.e. their ad space) to advertisers (AKA buyers). This ad inventory is constantly being generated: each time a user loads a webpage, each ad placement represents a salable ad space, known as an ad impression.

The first way to capitalize on these ad impressions is through direct sales, in which a publisher staffs an in-house ad sales team that works directly with advertisers to transact sales of ad impression packages for advertisers to run their campaign(s) through. The packages can be targeted to the advertisers needs, for example, only at website visitors that are logged in and have purchased a waffle-maker from the site in the past two months. The more an advertiser can hone in on a particular marketing segment, by running highly-targeted campaigns, the more they are willing to pay for the ad inventory. It’s important to note that in this way, ad inventory is sold in advance of its actual generation: an advertiser buys a package of 10,000 impressions, and as those impressions are generated by users viewing pages on the site, the website will populate them with the advertiser’s ads.

The second way is through an ad network. An ad network is a giant middleman that buys ad inventory from publishers, standardizes it, enriches it, and then auctions it off to advertisers, algorithmically, piecemeal, in real-time. This means that publishers don’t need in-house ad sales teams pitching and managing accounts with advertisers. Instead, they can hook their website into the ad network via simple programming methods and quickly gain access to a huge market of advertisers. (Note: Even though this involves some programming, this is not what is known as programmatic advertising.)

“Piecemeal” and “real-time” mean that ad impressions are sold on an individual basis, automated at very high speed by the ad network. These transactions do not involve future inventory, like with direct ad sale packages, but instead involve ‘fresh” inventory as it is generated. (Yes, each ad you see on most websites you visit was transacted between the time you started loading the page and the moment the ad appeared!)

On the other hand, these ad networks don’t differentiate those fresh ad impressions in very many ways. This means publishers’ can’t capitalize on their ad inventory’s unique premium value.

Ad network: “Give us your fresh ad impressions. Put ‘em in the 5¢-bucket if the page it was generated on has anything to do with cheese, the 3¢-bucket if its display size is 200 pixels by 150 pixels, or the 1¢-bucket if neither.”
Publisher: “Wow, those are my choices? What about impressions generated by logged in users that bought a waffle-maker in the last two months? Advertisers have paid lots for that in the past.”
Ad network: “Pfft. Put it in the 1¢-bucket, or buck off!” [Evil laugh, as follows.]

Thousands of publishers continuously pour their ad inventory into these networks. One interesting ramification is this is that as an individual surfs between websites serviced by the same ad network, that network is able to track that user (through the magic of third-party browser cookies). While this threatens user privacy, it allows the ad network to enrich the inventory it has purchased from publishers with cross-website user attributes that the publisher alone could never know. This is valuable to advertisers, the ad network profits from it, though arguably at the cost of user privacy.

Anyway, back to that evil laugh. Because of it, so-called programmatic adversiting techniques and products have evolved. The essential idea is that publishers should be able to enhance their direct sales with their own real-time ad transacting service tailored to all the premium data attributes that are unique to their inventory. This cuts out the middleman (a significant agent of user privacy invasion), provides more targeting and value to the advertiser, and therefore increases revenue for the publisher. User behavior tracking is still involved, but it is now silo-ed within each website, which I think fits much more naturally with user expectations. These techniques, products, and services are difficult to implement but are rapidly becoming more affordable.

<analogy>

Allow me to illustrate. Let’s say I own a dairy farm, and I produce milk. I produce plain milk, but I also produce chocolate milk, and my family’s secret-recipe strawberry milk. Also, all my cows are rBST-free. I make money in two ways. One way is by painstakingly setting up contracts with local grocers. This requires sales, legal, billing, and delivery services, but at the same time the grocers pay a pretty penny, because they know they are getting high-quality plain, chocolate and strawberry rBST-free milk from a local farm. This is akin to content publishers using direct sales to sell targeted ad inventory at a premium; advertisers pay extra to be confident their ads will be displayed precisely to who they want to reach.

The second way I make money is by selling wholesale to a big national distributor. I truck off huge containers of my various kinds of milk. I don’t make as much profit per gallon, so it makes sense for me only if I can scale my milk production very high, and just profit on volume. One of the reasons the prices aren’t as high as when selling locally is that the distributor doesn’t differentiate between rBST-free milk and rBST-contaminated milk. They also don’t differentiate strawberry milk. (They just add it to their industrial tanks of plain milk!) All of my premium selling points are worthless to them. But because they have national reach, and I can’t sell all my milk locally (for one, I don’t have the legal and delivery resources, and two, there isn’t enough local demand), they are still a useful revenue channel. At the same time, the distributor might differentiate by region (so that consumers can buy fresher milk from a region close to them), something that is largely irrelevant to my local buyers.

(Here’s where I have to stretch the analogy just a bit.) Luckily, some smart people have come along and invented an affordable way for me to own my own national sales and distribution center! Sales are done directly to the grocery chains throughout the nation (and even directly to households) through a sophisticated website, that is customized to denote the premium rBST-free and strawberry milk that I offer. Let’s say the distribution center is manned by low-cost robots and self-driving cars. I still need to invest in some sales and other support staff, but not as much as before and with much greater return. Now I can have the best of both worlds: selling my premium products at premium rates, and reaching a national audience.

</analogy>

Reading about all this has opened my eyes to the dynamism of the online advertising space. What I thought was a static environment is actually a landscape of innovation and evolution. To digress a bit, another interesting aspect of online advertising I recently discovered is called ad network optimization. This is, as I understand it, when a publisher actually methodically measures the (revenue) performance of various ad networks against various ad placements and other impression attributes, and then automatically re-allocates inventory to maximize revenue. Online advertising, important privacy considerations notwithstanding, is a much more vibrant business than I’d previously thought.

One thing I will credit myself with: I’m stupid and I know it. And, if I’m gonna attempt to participate in this space, I’m gonna keep trying to learn more about where it’s going.


In the post above, I used the phrase “ad network,” though I might have meant “ad exchange.” I’m not 100% sure. My perception is that most ad purchases are bought through real-time bidding, which occurs on ad exchanges, but I seem to be reading that ad exchanges are still considered novel to a degree, and that ad networks handle most ad transactions. So, I’m not sure what the right phrase is, or what the current reality is. I.e., I’m really stupid.

Tunneling to Freedom without a Jailbreak

If you’re anything like me, you’re an idiot who lost your jailbreak today when you tried to upgrade from iOS 6.0 to iOS 6.1.2 (which supports an untethered jailbreak) but were forced to upgrade to iOS 6.1.3 since Apple’s servers already closed the signing window for iOS 6.1.2 installs. [Shakes fist in direction of Cupertino.] And that means you lost the ability to use GuizmoVPN to access your startup’s access-restricted development server.

In the past, I’d tried using OpenVPN Connect, the Apple-sanctioned OpenVPN client app, but it required the use of a so-called “tun” adapter. Tun operates at OSI level 2, as opposed to Level 1 which GuizmoVPN supports via the tap adapter. Of course the beauty of tap is that it can be bridged to your VPN servers LAN interface, meaning no mucking around with subnets and routes.

Anyway… today I was forced to get tun working. You could say I was in for a “tun” of fun! Digression. I needed to progress through a series of puzzles, riddles and enigmas, each more beguiling than the last, carefully designed to test a different skill and/or bit of administrivia, before I gained the power of tun.

Stage 1: The Wall of Fire

First, I had to open/forward a port on my private networks WAN gateway, and also on the local firewall of the VPN server itself (God bless ufw!), since I wanted to retain the operation of the existing tap-based OpenVPN server. Kids stuff.

Stage 2: The Tunnels

Next came OpenVPN configuration. The routing wasn’t as bad as I thought, but the general notion of having a separate subnet for the tunnel just felt wrong next to the simplicity of bridging. OK, say the private network uses 192.168.1.0/24, and I chose 192.168.2.0/24 as the tunnel subnet. Also, the OpenVPN server itself has a local IP of 192.168.1.2, and the private WAN gateway is at 192.168.1.1. This was my server OpenVPN conf.

port 13337
dev tun
mode server
tls-server
server 192.168.2.0 255.255.255.0
push "route 192.168.1.0 255.255.255.0"
push "redirect-gateway"
# TLS encryption stuff.
# Other (non-germane) stuff.

I could’ve placed the `push` settings on the client configuration but I prefer to manage it centrally. This works for both OpenVPN Connect on iOS as well as the Windows OpenVPN client. Flipping/flicking the switch in OpenVPN Connect resulted in a rewarding green checkmark. I’ll take it!

Mini-game 1: Pong

With that up and running, I tried a little `ping`. I could ping across the tunnel from the client to the VPN server, but not out to hosts on the private network. I thought all it would require was a simple:

# echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -A FORWARD -i tun+ -j ACCEPT

However, I thought wrong, and pinging into the private network still failed. Oi! A couple head-smash-upon-keyboards later, I read that they need a route back to the pinging clients, since they live on separate subnets. Of course, it’s like playing tennis across parallel universes. Just like that. Luckily, all hosts on the private network are configured, by DHCP, to use the WAN gateway by default, so all I needed to do was add a static route on the gateway to 192.168.2.0/24 over 192.168.1.2. (Shout out to Tomato firmware, “Awww yeah!”) With that, pings were routed back to the originating client successfully. Game. Set. Match.

(You want to configure the IP forwarding to survive reboots. On Ubuntu, this is done in /etc/sysctl.conf.)

Mini-game 2: Dig-Dug

I’ve got dnsmasq running on the private network as well, which is a crucial piece of infrastructure when it comes to hostname-based web hosting. So once I confirmed pinging to hosts on the private subnet, I tried a quick `dig development-site`, but to no avail. Even worse `dig @192.168.1.1 development-site` was silent as well. So I set about getting DNS queries to go to the remote network. First piece of the puzzle was to inform the clients of the private DNS server. Adding

push "dhcp-option DNS 192.168.1.1"

to the OpenVPN config should’ve done the trick. But it didn’t. Fortunately, I had just recently been futzing around with my dnsmasq configuration, and I recalled that it could be configured to respond only to requests coming from certain interfaces. Peeking into the configuration revealed that it was indeed constrained to respond only to the LAN interface. A quick configuration change to loosen that up, and I was digging up my tunnel like nobody’s business!

Boss Stage: The Spider’s Nest

Finally I it was time to try `wget development-site`, but (altogether now) to no avail! “WAAHHH! But, but, but… I did the thing with the routes and the tunnels, blasting the hole in the firewall, the digging and the ping-ponging across parallel universes… alas, must I turn back, again?” I couldn’t let it go this time. But my dev site had alwaysbeen accessible in the past with tap OpenVPN, what gives?!

Suddenly, Alec Guiness’ voice boomed in my ear, “USE THE LOGS, LUKE! I MEAN, USE THE FORCE, MIKE. ER, USE THE MIKE, LOGS? UH, HEHE, YOU GET IT, RIGHT?” Looking at the logs, it turned out the requests were rejected because they were coming from IPs on the VPN subnet, not the private subnet! Of course. Even though tap gave VPN clients IP addresses on the private subnet, tun gave them addresses on the special tunnel subnet. Since Apache was configured with `Access 192.168.1`, requests from the tunnel subnet were rejected. A quick one-two punch to the Apache configuration (by the way, Access arguments are space-delimited, not comma-delimited), and BAM! Apache was mine!

Crossing my fingers, toes, and eyes, I flicked OpenVPN Connect to the On position, and Mobile-Safari’d my way to http://development-site… And, like a divine light emanating from the face of God himself, my development website graced my eyeballs. [Cue end theme.]

I hope this helped you out, dear reader/person that is “anything like me.” Also, if you’re anything like me, you’d probably like to know that neither of the Starbucks in Union Square have power outlets, but Think Coffee on 4th Av. does. Now you can access your private dev site while having fresh coffee and/or beer. You’re welcome.

How to Iterate Your Project Off a Cliff

That is what this article should have been titled, as it completely and dangerously misses the key insight of Scrum. Scrum is not merely a sequence hoops to jump through.

Fundamentally, Scrum is a recognition of certain risk-bearing concerns in projects, and the assignment of those concerns to separate roles. The division of concerns sets up a structural tension that drives attention to risks, and which are necessarily resolved through open negotiation. To truly reap the benefits of Scrum is to appreciate the value and organic nature of this tension.

All the steps listed in the article follow from this basic understanding, but these steps do not entail the myriad supporting activities that make Scrum valuable.

Patterns of pattern ignorance

Those wanting to pick up Backbone.js and can see past it’s current placement in the trough of disillusionment (see hype cycle) would likely encounter confusion with the names of its major components. Having read the codebase and coming from a Rails-flavored MVC/Model 2 background (namely ASP.NET MVC), I tend to understand the underlying patterns of Backbone.js components accordingly:

  • Routers work as front controllers,
  • templates (along with the browser’s DOM) as views, and
  • Views as presenters (from the MVP pattern).

Models are flavored with the Active Record pattern. Presenters and views are tightly coupled.

MVC and MVP coexist because the controllers respond to navigational input (mapping to model-presenter pairs) and the presenters respond to page-specific input (mapping to model manipulations and, possibly, server calls).

Considering that prominent tech bloggers are encountering similar naming confusion with other prominent libraries, this seems to be reflective of either lack of academic discipline by library authors or calculated marketing choices. Combined, that yields a zero net effect on adoption.

The Selector-Space Race

The article “Writing Efficient CSS Selectors” made the front page and generated some discussion on Hacker News today. These are always interesting articles, but rarely of practical value, and show just another way the software development community refuses to scrutinize CSS at the development process level.

Performance is only one concern of a website project. I’ve found that a greater risk by far is scalable stylesheet manageability, a topic with little useful engineering attention. Any decent-sized project is going to have to decompose their presentation declarations into manageable artifacts. This eases collaboration but has the unwanted side-effect of hiding existing selectors in multiple files. Add to this a tight project timeframe, a development team that regards CSS as a second-rate language (as almost all that I’ve encountered do, worsening the more senior they are), and CSS’ lack of usable “selector-spacing” (in the namespace sense), and you have a recipe for thermonuclear battles over selector specificity.

Selector and naming conventions can basically eliminate this problem. Module root elements have a class name that starts with a letter; module nested elements have a class name that starts with a dash. These are combined using the child selector (not the descendant selector!) to constrain their applicability by implying a much stricter subject structure. Each module goes into a separate file in a single directory, where each file shares the name of the module’s root class name.

This brings selector specificity to the forefront and establishes practical, explicit selector-spacing. What was once super-ambiguous, e.g.

body { color: black; }
.menu .item { color: orange; }
.menu .item .menu { color: black; }
.menu .item .menu .item { color: orange; }
/* and on */

is now very precise:

body { color: black; }
.menu > .-item { color: orange; }

Is it the most efficiently-interpreted ruleset? No, and I don’t care. It’s the most efficiently-manageable ruleset. (At least until Web Components are ubiquitous.)

The Company You Keep

I’ve always appreciated the efforts of companies to express the character they aspire to have, and the values they aspire to uphold and promote. Not only do such efforts demonstrate consciousness about their identity, they also show respect towards those who they may engage. Ultimately, actions speak louder than words, but certain words, when published, can constitute an act that speaks to the commitments a company is willing to make to themselves and to others.

To this end, I’ve shared Blocvox’s guiding principles on its blog.

Aaron Swartz and the Temple of Doom

Aaron Swartz was a prominent hacker who believed passionately in the potential of information access to improve society. In 2002, at 14 years old, he co-authored the RSS communication standard–the same one that powers Google Reader. In 2006, he became a co-founder of the fledgling Reddit when his company merged with it. Yesterday, at 26, he hung himself.

In 2011, he allegedly trespassed MIT’s campus to stash his laptop in a utility closet, which he had allegedly programmed to download millions of academic papers from the extremely expensive JSTOR database. JSTOR ultimately didn’t care. But MIT–that great stalwart of hacker culture–apparently did, and they sadly gave tacit support to his overzealous prosecution. US Attorney Carmen Ortiz fanatically pursued overreaching and severely disproportionate charges, carrying sentences of $4m in fines, and 50 years in jail!

From what I’ve read, he had already been struggling for years with depression. “You feel as if streaks of pain are running through your head, you thrash your body, you search for some escape but find none.” I am too familiar with this. A decade ago, I suffered a long bout of depression. Those streaks of pain inspired the name of this blog. It was intense, oppressive and ever-present. With time and space, I was able to sort through it; I didn’t have corporations or the government breathing down my neck.

If nothing else, I hope this brings greater mainstream awareness to the disconnect between justice and technology. Some people describe today’s information technology landscape as a lawless frontier. Perhaps that’s largely true. But anyone who ventures an act of protest or disobedience in those areas where corporations, governments, or other machinery of “orderly” power structures are located, will suddenly find himself trapped in a legally-hyperactive, Kafkaesque Temple of Doom.

Launching 2013

Last year was a challenging and fulfilling one for me. It started off mundane enough, voluntarily having my life whittled away by my employer. I had set only a few goals for myself that year, and I’m happy to say I met them all, even if one of them required a… reinterpretation.

Resolved, that I will launch an entrepreneurial venture in 2012.

What started as a side-project to learn about a variety of software development technologies and practices in early 2011, evolved last year into a serious outlet for me to express some of my strongest held sociological hypotheses. Two years on, I am still knee deep in design and development. So for me to satisfy the resolution is a case of “It depends on what your definition of launch is.” ;-)

Originally, I intended “launch” to mean feature-completion of the initial product, deployment of the product to a proper production environment (e.g. dedicated technology resources, regular data backup, etc.), and triumphant announcement to the public that it was finally Ready™. I now interpret it simply as the public announcement of the venture and the general opening of discussion about the core product (which heretofore was stealth). So without further ado I introduce to you, Blocvox.

Blocvox composite diamond logo, with slogan 'Every voice counts'

Blocvox is a social communication platform that captures and publicizes the zeitgeist (i.e. intellectual and cultural spirit) of active social groups as they evolve over time. That it is based entirely on direct democracy allows these groups to counterbalance two debilitating challenges they must presently confront:

  1. The piecemeal delegation of constituents’ power to a handful of representatives creates a power concentration that risks its egregious abuse, and
  2. Profit-seeking by mainstream media outlets results in filtration and distortion of their messages and actions.

These challenges severely impede public understanding of groups. In the end, this undermines the earnest efforts of groups to compromise mutually-beneficial solutions to the complex problems of today’s world. Thus, Blocvox ultimately seeks to restore the promise of the freedoms of speech and association to make the world safer, freer, and more enriching to everyone. (Hey, at least I can’t be faulted for not thinking big enough.)

To say this is the most ambitious product I’ve ever worked on is an understatement. The expectations of modern web consumers are exacting. The social media landscape is crowded by some very heavy gorillas, and a veritable glut of capuchins. Oh, and did I mention, aside from immeasurable support and feedback from family and friends, I’m the only one currently undertaking the venture? Still, I can’t imagine doing anything else at this point in my life.

So what will 2013 bring, you ask?

Resolved, that my body fat percentage will be less than 15% for the last six months of the year.

This one’s a lot less open to interpretation. Drat.


Interested in staying up to date with Blocvox? Find it on the following services:

The CSS culture problem

I just read this article about CSS, essentially aiming to define some techniques to enhance maintainability. I appreciate the author’s attempt to bring an engineer’s eye to the discipline of document styling, and it’s a conversation that certainly needs more contributors, but I feel this article simply furthers the current state of confusion and resulting apathy in the community.

Based on the innacurate assessment that HTML has value without CSS (ever use Google Docs without CSS?) whereas CSS cannot exist without HTML (isn’t that what all those wildly popular CSS frameworks are?), the author argues that separating style from the intended document context is good architecture. Doing this results in an explosion of generic utility declaration blocks, with little rhyme or reason. Are these blocks the product of refactoring, or does a design architect/dictator craft them? How fine- or coarse-grained should they be? How do you guard against all the normal baggage of non-semantic naming and global utility code? How do you prevent their direct use from HTML documents? How do you mitigate or control repetition and mixin explosion? How are they managed in source artifacts? Without context, the code has little focus. There is no disciplinary framework to prevent it from becoming a massive ball of spaghetti.

It’s funny that the author even attempted to make this point while criticizing non-semantic CSS framework naming at the same time. Simply put, abstraction is not an end. Separating style into document agnostic utilities and document-aware glue is over-engineering that reminds me of EAV modeling. But on this premise, the author advocates using non-parameterized mixins as an abstraction mechanism to make it easier to re-use declaration blocks. I fail to see how this is any more maintainable than using selector groups. In fact, we only end up with repetitive CSS that takes longer to process. (The author would do better to use the ‘extends’ feature of Sass or Stylus to effect this misguided approach.)

It’s the culture, stupid

Although the author goes on to touch on cascade management, the focus of the article is this non-parameterized mixin-centric architecture. The root problem with this is the false premise that declaration blocks are a common or ideal candidate for re-use, but I understand why the author presumes this. While I rarely find declaration blocks ripe for re-use, I commonly see the undisciplined grouping of selectors that represent design subjects that have no conceptual commonality. This is akin to refactoring Person and Street to derive from a common base class because they both have a Name. Why is this so common? Because engineers take a dim or dismissive view of the visual designer.

The visual designer’s job is to inspire, with as much fidelity as possible, the user’s mental model with the product’s information architecture. He achieves this by carefully synthesizing user research with product research into visual and interactive subjects. This is a discipline requiring great expertise and depth, but is usually treated by developers as a strictly upstream process. The correct approach is to use design artifacts as a reference point to engage in deeper requirements gathering, to understand the intention behind various design decisions and attributes, much like one would with a business subject matter expert. This conversation should be on-going and should touch on everything from color to spacing. The information gathered is the raw material from which a maintainable, well-designed stylesheet collection can be built.

I prefer to think of the stylesheet as authored by an individual who advocates for the visual designer. His goal is to capture the underlying concepts and the relations intended by the visual designer in a way that is idiomatic to CSS (or whatever hypothetical stylesheet language is used). On the other hand, the document template author typically advocates for performance (DOM, transport size, template processing), marketing (SEO), usability (accessibility), etc. The two must collaborate to create a document structure that is suitable to both. In practice, these roles are performed by the same person. It’s difficult, but not impossible, for the same person to switch hats and advocate for all concerns. After all, this is just another application of the Single Responsibility Principle.

Make no mistake, there’s enough blame to go around. Perhaps visual designers can be faulted for not disclaiming any implied completeness of mockups or other simple artifacts, triggering on-going engagement with the developers. And, as stated, managers and technical leads can be faulted for not explicitly directing visual design interviews by front-end engineers. Most troubling might be that visual designers themselves lack a clear conceptual discipline when creating visual designs. Even if they were to be interviewed, one would only discover that their creations were driven by inarticulable instinct and intuition. But this is no excuse. Project commisioners trust the development team to raise flags about project risks like these. Thus it’s incumbent upon the developer to demand and drive a deeper explanation of the visual design (or to communicate the risk to ongoing front-end development agility). That should generally manifest itself in seeking more methodical, conscious visual designers. Worst case, the developer is forced to infer underlying concepts and relations from artifacts. With understanding of the cultural problem and the importance of encoding the design’s intent, this can at least be done consciously to avoid arbitrary and inappropriate CSS design. Regardless, change begins with no one but the front line developers.

Without respect for the visual designer, front-end developers lack crucial information to craft nuanced implementations, and managers have no reason for allocating resources to do this. But if maintainable, adaptable CSS is important, then proper visual design requirements gathering is crucial. So the solution to improving the state of CSS starts with refocusing the development process and resources on the visual designer’s intent. And when intent is properly represented, not only can more informed, nuanced code be crafted, but a particular set of patterns and anti-patterns also emerge. Only then should pre-processors be brought in. Otherwise, one ends up writing articles like the one cited, which treat symptoms superficially because of misdiagnosis. Prognosis: more pain.

One such pattern takes the technique mentioned in the 37signals citation to the logical conclusion, to use child selector chains to create groups of related rulesets that effectively form isolated sub-stylesheets capable of representing complex visual subjects. Another is simply to name magical strings and numbers using pre-processor variables to effect proper re-use. These two techniques alone go a long way toward crafting maintainable, easy-to-use, massive web UIs. An anti-pattern is using selector groups to effect cross-subject re-use; I have found it’s rare to for a visual designer to intend a specialization hierarchy of visual subjects. I hope to find time to expound on this in the future.

In the meantime, I hope we can begin giving visual designers the respect they deserve.