THE DAILY STREAM

Mike's site

Stuff and things

Latest updates
Newest first

Solving the seven sins of CSS

Recently, the ReactJS community has set its sights on a new method of building styles into React-based front ends. It comes straight from the source, Facebook.

I think this presentation makes a lot of sense to a lot of developers who've begun to think in the component-based (and honestly very sensible) React methodology. But there are a lot of strange justifications and a path paved with over-engineering that leads to vjeux's ultimate solution.

Warning: This is long.


The "Problems"

First, here are the problems that vjeux outlines. I'm not here to provide better solutions for them, but I will say that in many cases, they're not really problems at all.

1. Global Namespace

Firstly, I think this is key to illustrating why a developer of vjeux's caliber can have a great thought process but miss the boat to some degree on CSS. He calls a class a "global variable." This seems at first like a matter of introducing programming semantics into the conversation so we all know what we're talking about, but I think it's conflating what a class and a variable actually are. The word itself indicates that the value of a variable can change — if anything, a CSS class is a constant. It's simply a pointer or reference. If you prefer, a class or ID selector is a set of rules more akin to a function (or, in OO, a class... probably no coincidence there).

But getting away from a concept I honestly feel somewhat inadequately equipped to really talk about at length, the "namespace" issue itself is the first of these that isn't really an issue. A class living on its own, even one attached to an element (e.g., div.myclass), does inhabit a "global" namespace in the sense that you can use that class anywhere with no limitations. Only good practice will limit you. But writing self-contained rules is not incredibly hard, is it? Take this piece of LESS (roughly identical in SCSS):

.specific-container {
  input.super-specific-input {
    /* style rules */
  }
  label.super-specific-label {
    /* style rules */
  }
}

In the sense that .specific-container is available to use and abuse anywhere, it is a "global" element. But that class in itself becomes an effective namespace for anything within it. And a few simple naming conventions can take that further.

I can barely think straight to comment on these (literally) backwards extensions that the Facebook team apparently wrote before arriving at the conclusion that they should abandon CSS altogether.

2. Dependencies

I'm not entirely sure I understood this section, mostly because the expectations of CSS working like a build process (i.e., errors should cause everything to break) is such a foreign concept to me.

Maintainability and monitoring the Cascade used to be a huge issue with CSS. This is something that preprocessors have solved incredibly well, even though they don't change many fundamental aspects of CSS. That includes the Cascade itself, but one of Less's early counterarguments was that the ability to write such modular CSS discourage "proper" or cascading use of styles. I'm not exactly pedantic on that myself, but if one were so inclined to write completely modular Less/Sass with no globally-impacting styles and no large-scale cascading, it's not very hard to do. Basically the above example, repeated numerous times as separate files and associated with each module or UI component, becomes a set of dependencies. These are easily managed by Less/Sass imports.

3. Dead Code Elimination

Near as I can tell, what they're referring to as "dead code elimination" is a product of their own solution. I can't really speak to this.

What I can say is that poorly-maintained, long-running, legacy CSS (the old way, without the concatenation made possible from preprocessors) is a problem for a lot of people. This is not a fault of the language itself. Less/Sass certainly make it easier.

4. Minification

Maybe someone can help me here, but I'm confused about this one — the old, extended-CSS solution let Facebook's developers use incredibly weird, non-semantic, but very short class names in order to save a couple bytes. It's bizarre but has its logic. So how does programmatically replacing a token with a long list of inline styles — which are maintained as a single component but echoed into a page once for every instance — save bytes? Not sure. If semantic class selectors is a problem of byte size, that's fine, but I don't think it's one that huge, redundant inline styles can solve.

5. Sharing Constants

What's the old quote? There are two hard things in computer science: cache invalidation and naming things. Making your stuff sync up between content, presentation, and behavior is a problem old as the hills, but most teams don't have the specific problem in this deck because they're not working with this weird system.

What vjeux shows here is a worst-of-both-worlds scenario where style has been mixed into behavior, but not all the way. I would argue that yes, in fact, his completely inline solution is a better answer than the hodgepodge here.

var buttonPadding = 5;

Reading that physically hurt me. He says "unfortunately there are many real world use cases where you need to do it." Not sure I buy that. If you really, really feel this need, there are tools for your Grunt or Gulp file that will transform a list of Less/Sass variables into Javascript at build time and thus keep the values synced automatically.

Upon reading the solution they developed, I got pretty confused at "CSS Variables."

6. Non-deterministic Resolution

This is another case of holding CSS to the same standards of behavior as a logical programming language, which it is not. The "linear" flow of later rules overriding earlier ones is always something that programmers struggle with because they can't organize things according to how they like; they must organize according to how the web browser is going to read the document.

Writing with the modular, "namespaced" blocks of Less/Sass eases these problems in two ways: one, confining the rules to their own pocket of markup will keep them from affecting anything else in the application, and two, the ease of auditing the styles will prevent unexpected cascades.

7. Breaking Isolation

I feel sad for the team at Facebook who've been burned by a poor understanding and even poorer practices of CSS writing. Overriding in the way shown in the example is unfortunate. But imagining myself as a designer in that organization, forced to think in an upside down way about my CSS, it kinda feels like it's no wonder the designers reach for non-ideal solutions as long as they work.


My Problems with the Solution

I can certainly see the appeal of just styling within the component as Javascript. The author does fall into a pattern that is common among devs (I've done it too): a post-hoc justification.

Second, style is actually a much better name than class. You want to "style" the element, not "class" it.

Let's not bring the semantics into it — I get that the actual english words make more sense, but we've all agreed on what that word means in the context of markup. This is a side point though.

1. Redundant bytes and information

Whether you're talking in terms of human readability or the space taken on disk/downloaded over the internet, I have to question whether multiple references to a single CSS class:

.btnClass {
  background: #333;
  border-radius: 2px;
  color: #fff;
}

is not preferable to

<button style="background:#333;border-radius:2px;color:#fff">One button</button>

repeated over and over throughout the application. And here of course I'm using a very simple example; most real-world CSS rules are going to be significantly larger. This is one of those questions that I assume has been empirically answered, but there isn't a lot of usage of this method going around yet, so I don't know.

2. Separation of Concerns

I get the very real benefits in React of mixing concerns while separating physical application pieces. Everything associated with this piece (structure, style, behavior) is in one place, so I know exactly what needs to be done in order to make a change to that piece.

But part of the benefit of the classic "separation of concerns" philosophy is the ability to take a holistic look at the styles. For all the supposed solutions with regard to maintenance and dead code elimination, I'm afraid this has created many more potential ones. Obviously, this is to some degree going to be dependent on how a React application is structured, but components can't truly share stylistic elements, even if they have individual styles in common. So the ability to change that stylistic element from a central place is now lost.

The best we can really do with this method is reference a central variable, or possibly (I'm not even sure about this) something like a mixin. Like any of the CSS-based solutions that vjeux writes off as non-enforceable, this requires good practice.

3. Separation of Work

vjeux himself admits that part of the motivation for Facebook's crazed bolting on to CSS is due to having a large team of developers working on highly focused portions of code, most with limited expertise in front end. This is, let's be frank, not an uncommon problem but it is a specific one.

Though tools like KSS have been around for a while, style-guide-based development is just now coming into its own. Mailchimp, Starbucks, Lonely Planet and others have made huge and very public strides in building component libraries that developers can then reference and drop into new pages.

The benefits are easy to see: a streamlined design process, easy enforcement of standards, and a refocused approach that encourages solving problems with the same design patterns where possible.

With all styles inside the React components, control over front end is not only not handled holistically, it is handled entirely by developers who may or may not have much expertise with browser discrepancies, best practices, and all the other myriad of things that CSS writers actually focus their time on.

4. Missing Features

Generated content and other pseudo-class selectors are pretty much not available here. Is it overkill to impose a hover state just for a color? Perhaps not with React, whose bread and butter is state change.

And what about media queries? This is beyond unfortunate:

Not the best Responsive Design

Toward a better way

These are all fairly new issues. vjeux's still giving this presentation, and it only went online in November. React developers are still discovering the process and trying it on. The argument on Hacker News is still somewhat active.

My problem is not with upending dominant paradigms. It's not with trying to find new ways of styling. But ditching most of the primary benefits of CSS/Less/Sass and justifying that with arguments based on some inaccurate assumptions is a paradigm shift that doesn't quite feel necessary.

Discuss

So long, and thanks for all the Lone Star tallboys

I spent 7 years in Pittsburgh, another in Detroit, and now just shy of 7 years I'm leaving Austin. That's as lucky a number as any, although it feels like an incredibly short time in a city that grows and changes as rapidly as this one. But ultimately, the exciting stuff in this town suits young people who go out a lot, tech-libertarians, people who aren't yet sick of Texas's inability to "do" public transit, and the sort of day drinkers who've always occupied the Town of Linklater Films.

At least, I'll probably continue telling myself that indefinitely.

But there's a lot of truth there — it really is tough when you have a young child to even imagine enjoying the fruits of a town known for its nightlife, and eventually you start to wonder if that's really for you anymore. As a musician, it's hard to always play for nobody or to keep pace with the younger, better looking indie-poppers filling up the increasingly snobby and hard-to-book venues. As a person who tries to have some perspective, sometimes taking a step back you realize how much Austin is clinging to its fun slacker persona, even as it gets big enough that it really could stand to clean up its act maybe just a little before it loses everything that people love about it.

This isn't about how "Austin has changed, man"; That was old even when I moved here. Of course places change and that's part of what makes a town ok to continue living in more than 7 years. But I'm not a lone wolf slacker musician, I'm now some kind of "family man" (imposter syndrome doesn't just work at your job) and that is a super rewarding part of my life that's taking me away from the both the eye-rolling mustachioed coolness I'm so over and the merciless, dash-cracking sunshine I love so much. So yeah, there is a flipside.

I wasn't too great at making friends until moving here. I've become more social and worked in an office again, so I'm leaving behind maybe the closest, coolest bunch of people ever — people who, I'd like to think, "get" me.

I'm not exactly headed to unstable territory now, but if I'm being real it's difficult to leave behind 75-degree winters, constant restaurant openings, or that slight swell of pride when even a big city slicker's eyes brighten at the mention of where you live. It's even harder to leave those friends I've worked with, played music with, or lived next to. Having them all gather at a party for us yesterday was beyond cool — it was downright humbling that that many people care enough (A friend called the beautiful weather "one last kick in the nuts").

Now... It's not in the least bit hard to leave constant traffic, lines to sit in literally every one of those restaurants, or the Texas government, none of which are gonna go anywhere anytime soon. And I could do without the hypocritical faux-liberals who nod sagely about how we need affordable housing and mass transit, but then get all predictably NIMBY when it comes time to do something.

UPDATE IN 2024: OH NO EUGENE

But rather than dwell on what great things I'm leaving or bemoan the bad ones, I think it'd be more productive to commit yesterday's laughs and hugs to memory, give thanks for the all that's happened to me here, and think of what other positive stuff lies ahead.

I know I'm going to a culturally rich, meteorogically mild place with incredibly friendly people, and my new commute is going to add hours to my week (time) and probably years to my life (I-35 stress). But that's just the beginning. Now that I'm a little better at life than I was seven years ago, my hope is that I can create an even more amazing one there.

If this is me in the "Before" picture, look for the "After" soon. And at least check out my Instagrams from the road.

Discuss

My favorite albums of 2014

Now that it's almost February, I assume everyone has already read all the best-of-the-year lists that matter to them. So here's one that won't. These are the best records I heard that came out in 2014.

AURORA

Ben Frost - A U R O R A

I honestly really didn't know anything about Ben Frost and hadn't heard his earlier stuff, but this is a magical concoction of computerized and percussion-heavy experimental electronics that takes me back to the days of playing shows with fellow laptop jockeys and industrial car-part-smashers. It's a varied, rich, and constantly surprising piece of work, and it has Thor Harris on it too!

St. Vincent

I've seen St. Vincent, and I've heard pretty much all of her albums, but this was the first one to really catch my ear. This is the kind of art rock that people like Peter Gabriel and Kate Bush used to do — accessible but genuinely attempting to go places. She's also the kind of guitar player who's super talented but intriguing, not shreddy.

Soused

Scott Walker and SunnO))) - Soused

As Scott Walker gets increasingly prolific in his old age, it's starting to be apparent that he's actually got a pretty in-tune sense of humor. On paper, Walker with Sunn is the Lou Reed/Metallica album that actually works. In practice, it's basically a Scott Walker album with guitars, and that's just fine.

SWANS - To Be Kind

The Seer was maybe the peak of Gira's output, ever. It was the realization of the promise that Swans are Dead teased us with just before he originally disbanded the group. The only thing wrong with To Be Kind is that it's not The Seer.

Sumerian Fleet - Just Pressure

I basically kind of started following Dark Entries records around the time I got super into the Minimal Wave catalog as well. That led me to their flagship release of 2014. This retro slice of Linn-driven heavy old-school EBM meets sparse synth-wave makes me think of the best of early 242, and it's immaculately produced.

Run the Jewels 2

It topped a lot of the pros' lists, and it's probably obvious why. The first RTJ was a cool side project, but the real potential of an El-P/Killer Mike collaboration opened up on the second one.

BLXPLTN - Black Cop Down

This is one of Austin's most exciting local bands, but they're not going to get the press that the mellower or more rockist indie groups will. They're a hardcore band with a drum pad. What a weird thing, but they're so fierce, catchy, and fist-in-the-air angry it's hard to deny the live show or the record.

Under Color of Official Right

Protomartyr - Under Color of Official Right

The first Protomartyr album was kind of out of nowhere, and doing the jagged Fall-inspired post-punk thing in Detroit is unexpected. But the production is better, the songs are tighter and darker, and Joe Casey's incredible lyrics are more audible on the second one. It's a mix of a realistic portrait of alcoholic depression, a lament for Detroit, and what Casey calls "bad dad songs" (one of which, "Bad Advice," is about Kwame). This, from "I Stare At Floors," sums up well:

The day comes
same as before
it goes on again
the television a concave window
lawyers and murderers
the Law's confusing, the Order makes no sense
Scratching the skin
Staring at walls, staring at floors
The plan today is not to die
The cure-all's always over ice

I listened to it every day for like 3 months and still can't get enough.

Other stuff

Fennesz, Aphex Twin, The Bug, FKA Twigs, and of course Shellac all put out solid albums this year that I enjoyed a lot.

Honorable Mention from 2013

Speaking of Minimal Wave, I also discovered Veronica Vasik's sub-label Cititrax and the act Kontravoid. He apparently used to be the live drummer for Crystal Castles but in any case his self-titled dark synthpop LP from 2013 got a lot of play from me as well.

Discuss

Change is what the web is about

wrote this for our corporate blog. Rather than give everyone I know instructions for connecting to our VPN, I thought I'd reproduce it here. The gist is: as we go through a lot of change both process-wise and philosophically, we need to make sure nobody gets too attached to one way of thinking and gets left behind.

Since its inception, the Web has undergone constant evolution. But along the way, it’s also gone through some major revolutions that left it forever changed — and left some people behind.

Purty Pitchers

The first earth-shattering change was the NCSA Mosaic browser. Why? One word: graphics. Color graphics! You wouldn’t think this would bother anyone: sure, they took a long time to load and were really awful quality purplish GIFs for a long time, but being able to navigate around a web page with your mouse and scrollbar really opened up the web to a lot of people who would never have touched the green-on-black terminal browser Lynx.

NCSA Mosaic

Still, there were casualties: the early denizens of the internet, the super tech-savvy terminal jockeys and ASCII artists who preferred the music of a ker-chunking IBM Model M keyboard to the click of a mouse saw their little private utopia being taken away. In a way, I can sympathize. They were probably worried it’d be filled with n00bs, dads and ads eventually.

But the lesson is there. Adapt or get left behind.

The Blue Beanie

Most of these revolutions have happened during my career. The rise and fall of Flash, the advent of YouTube, blogging… it’s been a fun ride so far.

But from a designer/developer standpoint, something that in hindsight might’ve had the biggest effect was the Web Standards movement. As late as the mid–2000s, we’d been designing pages based on some anonymous genius’s realization that HTML tables and weirdly sliced images could be used to create print-like layouts on web pages. Thus the business of “web design.” But this was a hack, and it helped us grow an appetite for hacks. Meanwhile, Netscape and Microsoft were vying for supremacy in the browser market by adding more and more amazing but completely incompatible features. So we essentially had to build sites twice.

zeldman

But then Jeffrey Zeldman came along and told us all to try something: first off, stop using tables, because we’re hacking a useful feature of the browser to do something awful it wasn’t meant to do, and second, stop using these browsers’ non-standard features. Start using CSS. Thus the Web Standards Project (and what has come to be called the web standards movement) was born. And this movement effectively ended those dreaded Browser Wars.

Trust me, we’re all better for it. But for a while, there were a lot of designers and developers who didn’t want to abandon their fancy browser features, and didn’t want to stop using tables because they worked! Those people adapted. Or they became irrelevant once the browser makers got on board with the Standards crowd.

Responding to Change

The arrival of web applications was not about just one thing. Faster broadband, AJAX, browsers able to run complex Javascript, web fonts, SVG, and all kinds of other stuff made the web the new platform for software. It’s still getting better. And our desktop computers aren’t the only devices with these front-end capabilities anymore. If I can get my software over the web, and my phone has a really good web browser, I should be able to run the software on my phone, right?

Ethan Marcotte first coined the term “Responsive Web Design” four years ago on A List Apart, and the design world has been pretty… responsive to it. Rather than the conversations I used to have ten years ago over whether we’re going to finally support 1024x768 screens, applications can now resize, reflow, and customize for different screens and devices. It’s a huge change in a way of thinking, but it’s also one more way that web applications are now more like “real” applications: do Microsoft Word or Adobe Photoshop force me into a highly controlled layout that only works at a certain window size?

But like the ASCII art and table layouts, there are going to be some casualties in the new way. I think the concept of “pixel perfection” is one of those. If my application changes from screen to screen and situation to situation, I can’t ever know exactly what it’s going to look like to any particular customer.

And that’s fine.

There’s still room for all the careful and highly thought out work that we’ve always done when crafting web pages and web applications. In fact, our job is more important than ever because there’s no way a print layout designer can ever do what we do: deliver what our customers need, on whatever device they need it. And we don’t have any intention of being left behind.

Discuss

Tables considered good

A little while back, I linked to this article extolling the virtues of display: table-cell. And I wholeheartedly agree. Using table display moves the Holy Grail Layout from hacky and difficult to done in a couple lines of CSS.

One thing the article mentions is source order. The author kind of waves this away as an SEO concern, but I'd argue it's the single biggest issue holding back even the people who aren't skeeved out by the word "table." Source order used to matter little to me; I also thought it was pretty much an SEO issue, or possibly a tweak to page rendering speed at best, but in this day and age? It's easy to move stuff horizontally with floats, but stacked boxes in a mobile layout really need the source order you want to appear on screen. Which, conveniently, is probably the most sensical source order. And if your table layout doesn't support that, you might have created some real headaches for yourself in a responsive page or screen.

Aside from that, I've just started playing with display:table in earnest on some sites and I'm experiencing some strange behavior with regard to showing and hiding elements. This is further compounded by shifting breakpoints as you resize the browser.

There's a couple schools of thought on that, both of which I've belonged to:

  1. The diligent front end devs who will make sure that they've fixed every little weird issue. This is probably the "right" school to be in.
  2. The pragmatic but perhaps somewhat lazy approach says "only designers sit and resize their browsers all day long making sure all the breakpoints work." We're designing for multiple devices and screen sizes, not constantly shifting screen sizes. Probably. And the major layout shift where the bug happens is at a small enough size that you probably won't see it on desktop browser at all, where resizing is possible. Probably.

The thing of responsive layout is that it's an admission we don't know all the cases. So knowingly leaving a weird situation in there without making a pretty significant effort to fix it is a disingenuous move. Hopefully I'll make progress on it, and if I do, I'll document it here.

Discuss

(A series of grunting noises)

I've finally taken my first step into the wide world of yesterday's favorite web technology with a new understanding of Grunt. UPDATE: It wasn't long before I moved to Gulp. Welp.

It's par for the course that designers and front end devs are trendy, fad-prone folks with their eye to the future and an almost obsessive-compulsive desire to find the "perfect" set of tools or processes. And by now, many (especially the ones prone to blog posts) have moved past Grunt to another Javascript/Node-based system called Gulp.

I'm not there.

I love being hip and with the times too — I have a Ghost blog. But having just discovered enough information about Grunt from ebooks, coworkers, and Stack Overflow threads to be dangerous, I'm not about to move on just yet. And now that I "get it," I have to say that maybe it is kind of the "perfect" tool.

What will make Grunt resilient in the long run?

The "perfection" of Grunt is not about its extreme levels of functionality, nor its user-friendliness (lol). It's the flexibility. Grunt serves that obsessive-compulsive tool-design side of front end with a lot of plugins and an easy way to write more. If you're a FED and you really need something that isn't in the Node Package Manager (NPM) repository, then maybe you should consider taking your skills to the node-module-writing level.

It's also super portable, which makes creating an environment a snap — just install Node, and you can run Grunt-powered sites and apps. I've heard opposing arguments on whether to put your Node modules for an app or site into Git, but right now we're not. Any new environment just needs to run npm install and they're up and running. It's literally that easy.

What are we doing with it?

Currently I'm working on a static prototype with bootstrap (LESS version), JQuery, and a few charting libraries. Grunt moves static files from a src to dist directory, minifies Javascript, compiles LESS files and Jade templates, and runs Browsersync for live reloading and injection. When we're all synced up, it also deploys to Amazon S3 for the stakeholders to view live.

This is a relatively simple setup for Grunt, which can do all kinds of more Node apps and complex whosamawhatsits. But it's the right tool for the job when compared to something like Preproc or CodeKit which, don't get me wrong, are nice apps.

For instance, I nailed down the file structure early and defined it in the Jade compiler. Now every new Jade template added automatically compiles to an HTML file in the right structure. CodeKit requires me to define the path of every new template.

Grunt also lets you create multiple setups. For instance, in development, the watcher and compiler might not minify the final Javascript and CSS so they're more easily debugged in the browser. But on deploy, minify it all. And this is all a one-time setup.

Downsides

That one-time setup is pretty much Grunt's big downside. The syntax is a bit arcane to me, not quite resembling any normal Javascript or JSON files. Installing packages is a breeze with NPM, but actually setting up the tasks and getting them to do what you want can be a many-hour process.

Now, is that worth the flexibility and other advantages it offers over simpler GUI compiler applications? Depends on your use case, I'd guess. For us, it's really fantastic. I still use CodeKit on some other sites, and I'm sure the daunting setup process will keep me away a few times that I might prefer using Grunt.

But overall, it's been fun to learn and satisfying to set up a workflow exactly how I want. That might make me a fad-chasing Kool-Aid drinker but I'm happy to never struggle with my tools not doing what I want.

Discuss