Ills of the Graphics Interchange Format

The Graphics Interchange Format1 might be useful for people who love sharing cats and 3-second movie clips. These people certainly think they’re useful, and I won’t take that away from them. But they have no place in the professional developer environment.

In the building of UIs, it often becomes necessary to share a brief clip that demonstrates the user experience. When it comes to this, you have two choices: you can use a MPEG-4 Part 144 uploaded to a service like Screencast, or you can use the Graphics Interchange Format uploaded to a service like CloudApp. The former choice is the better one. The problems with the Graphics Interchange Format are legion. I’ll enumerate the more burdensome.

  1. It takes longer to begin watching a clip in this format than in a standard video format. The reason is because you must load the entire resource before you can begin it. There is no concept of “buffering” or “streaming.”
  2. Not only does it take longer, but because there is no “play” button, you are not in control of when it starts playing. The resource begins playing as soon as it is ready to do so, not when you are ready to do so. What this means is that you must sit there idly waiting for the resource, rather than doing something else whilst you wait. You dare not switch tabs because the file will begin playing at a time you think not.
  3. Likewise, because there is no “pause” button and no ability to scrub, if you want to revisit a certain piece of a 30-second clip, or if your impatience gets the better of you in the previous bullet and you miss the start, you must wait the duration of the clip. This is egregious.
  4. The determination of whether the file loops or not is determined by the creator of the file, not by the consumer of the file. More often than not, the author chooses to loop, which means you have a hideous distraction before your eyes after the first or second viewing.
  5. In order to avoid said distraction, Slack has made it possible to disable the animation of Graphics Interchange Format files in settings. Because of this, sharing such a file is no guarantee that the recipient will actually receive what the sender intended — they might instead receive a static image frozen on the first frame. On the contrary, when you share a proper video, you have a guarantee that the recipient gets what you sent and nothing less.
  6. The colors are limited.
  7. The frame count is limited.

The Graphics Interchange Format robs mankind of everything that is decent and noble in frame sharing. Do not use this format for professional use.

  1. You’ll pardon the verbosity. I’m still recovering from the use of acronyms during my 4-month stint earlier this year in corporate America. ↩︎

The Actual Purpose of the Document Base URL Element  

The only time I think I’ve seen the piece of markup below used in real life is in the context of a Single Page Application:

<base href="/">

What I hadn’t realized, until yesterday, is that if you’re at a page like this:

And there’s a relative image referenced in the DOM like this:

<img src="avatar.png">

Then that will normally resolve in an HTTP request to but if you have <base> element defined like above, then that will resolve in an HTTP request to It’s always a funny feeling when you learn something fundamental about something you’ve been familiar with for ages but haven’t given any thought to.

The Tesla Model 3 Is the Top Selling Car by Revenue in the US  

It’s also the 5th best selling car by units. This is incredible when you consider that a Model 3 costing $10,000 less is coming out in early 2019. If the Model 3 is performing this well with a $45,000 starting price, what will it be then? Tesla has gone from being a company that sells cars to rich coastal elites to being a company that sells cars to average American consumer.

As I was driving to work today I was struck by how arbitrarily noisy the highway is. A day may come where that noise is looked upon as the mark of an era that came and went.

Because the average energy cost per mile of an electric car is a third the cost of a gas car, why wouldn’t you want to enjoy the higher precision of an electric motor when the up-front cost is comparable? It’s a objectively superior technology. Through irrefutable, unstoppable math, the automotive industry is getting disrupted in an way unparalleled since its inception. The Tesla Model 3 is to cars what the iPhone is to phones. Honda and Toyota, heretofore the defining American automotive staples, are the new Research In Motion.1

  1. (That’s RIM, the company behind the BlackBerry.) ↩︎

The iPhone Browser That Ignores Responsive Design  

When you long-press the reload button in Safari for iOS and select “Request Desktop Website,” all you’re doing is changing your user agent. This doesn’t do anything for most websites, because most websites offer their mobility via responsive CSS. Responsive CSS pays no attention to the user agent — instead it looks at the viewport width. And in Safari there’s no way to customize your viewport width. That’s where the Desktop Browser for iOS comes in. It somehow modifies things so responsive websites think you’re using a browser that’s wider than it really is. Desktop Browser might be achieving this by simply removing the viewport meta tag from the head of the document. That tag often looks something like this:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1" />

The more I think about it, that’s probably how Desktop Browser is achieving this.1 However it’s doing it, it works consistently, and I love it.

  1. When you visit a viewport revealer in Desktop Browser that programmatically shows your viewport width, it registers as the correct one (375 pixel width on an iPhone XS). That’s why I don’t think Desktop Browser is spoofing the viewport width. ↩︎

You Needn’t SCSS or LESS to Create CSS Variables  

I didn’t know about native CSS variables until this week. Internet Explorer doesn’t support them, but nobody cares about IE.1

The only real reason left to use SCSS or LESS is for scoping. But nested CSS isn’t the right solution to scoping. The real solution is having CSS that’s scoped or modularized by its very nature. If you’re using a JavaScript framework, you can approximate this with CSS Modules (e.g. here is its port to VueJS). But the long term solution is the Shadow DOM.

SCSS and LESS will be extinct in a decade.

  1. I get a rush when I see people building websites that bring IE to its knees in hopeless, permanent incompatibility. ↩︎

How to Adjust the Brightness of an External Display on macOS Mojave  

One of the glaring bugs of macOS Mojave’s initial release is that you can’t adjust the brightness of an external display using the brightness keys. Nor can you do it from System Preferences. But you can adjust it by downloading Brightness Slider from the App Store. It’s free and it works. Hat tip to Jreinhal.

Update December 24, 2018: I noticed last week that this bug is now fixed. By pressing F1 and F2 on my bluetooth external keyboard, I can adjust the brightness of my external display.

The Essential Symbiosis of Algorithm and Heuristic

In his book Creative Selection, which I recommend very highly, Ken Kocienda talks about the importance of having software that takes heuristics into account. Much of computer software is algorithmically deduced. But not everything can be initially derived from algorithms. Some things require experimentation, trial and error, heuristic. Some of Ken’s examples:

  • Determining the proper size of icons on the iOS home screen so that they’re consistently tappable.
  • Determining how deep “pinch to zoom” should take you when looking at a photo.
  • Skewing the touch event to be higher than your touch’s placement so you feel like the tip of your finger is what interacted with the screen.

The only way to really get to these decisions is by heuristically using the software and finding what works best, and then extracting an algorithm from your findings. In addition to this, Ken said, “Sometimes we used heuristics to temper algorithms.” As an example, he talked about how they tweaked the auto-correction algorithm on the iOS keyboard to accommodate human behaviors and real-life situations that they hadn’t previously considered.

In contrast to this approach, we gaze upon the newly designed website, which continues to make heavy use of the Golden Ratio Typography Calculator and not much else. Chris has said, “I use math—not whimsy—to inform my designs.”1 But whimsy is just a despondent term for heuristic. What Chris is really saying here is this: “I have little patience for heuristic when determining web design.” The Golden Ratio Typography Calculator has always bothered me, frankly, because it tries to remove this essential heuristic ingredient from the equation.2 It blames anyone who comes up with their own typography numbers as “whimsical.”

I’m glad the iPhone wasn’t designed with this dogma. Life’s too short to use software that was built purely by heuristic-barren algorithms. Long live informed whimsy and the liberal arts.

  1. As of about a week ago, this oft-seen maxim at the old site is now only viewable at Its underpinning ideology is still alive and well at the new site, however. ↩︎
  2. While I’m slaying sacred cows, I’ll go on the record for saying that the results don’t even look that good. The line height is invariably too much. ↩︎

Why Primitive Parameters Are Bad

Consider the following JavaScript function call:


As you can see, we’re passing an argument of true. That’s a primitive type, and as such, it’s not clear what it’s doing. Now imagine if the referenced function were rewritten to take an object parameter instead. Calling it would then look something like this:

fetchUser({ forceReload: true });

This is much more clear. We can reasonably deduce that by passing true, we’re telling the code to ignore local cache and do a hard HTTP call to a server.

As a general rule, named parameters are better than simple boolean parameters. I’ve gotten to where I hardly ever write function definitions that have simple primitives as parameters, even if the function only has one parameter. Never underestimate the value of code readability.

A second reason why primitive parameters are bad is this: they make future extensibility harder. When it does come time to add a second parameter, you have to worry about changing the order of them. If you’re working with a team, you’ll soon be debating which parameters should come first. A lot of drama and intricacy can surround this. Usually developers want the most important parameters to go first. Once they’ve agreed on the order of importance, there’s still the debate about which parameters should have default values and which ones should be required. It especially gets messy if some of the more important parameters have logical defaults while some of the less important ones don’t. Once everyone’s finally agreed on how it should work in an ideal world, then there’s the debate about whether it’s worth refactoring every place that calls this method. Should you refactor, or just tack on the new parameter at the end with a default value as a less-than-ideal solution to avoid “busywork”? Remember, Chris has an unrelated work-in-progress branch that is touching this code a lot already, and he’d have to deal with a bunch of conflicts if the function signature were to get changed upstream. He’s ok with the change, but can it wait a couple weeks until his thing is done? There are so many opportunities for confusion and disagreement and frustration and subtle procrastination in all of this.

This whole debacle dissipates by simply using an object as your parameter. With named parameters, order doesn’t matter, because object properties are ordered alphabetically. And the best part? Thanks to object destructuring, you don’t even have to change the body of your function. If your function definition used to look like this:

const fetchUser = (forceReload = false) => {
  // function body that references `forceReload` boolean

It can now look like this:

const fetchUser = ({ forceReload = false }) => {
  // body remains unchanged

Never did an opening and closing bracket solve so many problems so effortlessly.

The Senseless Requirement for Having a Custom Avatar at the Apple Support Communities  

Roger Wilmut1, clarifying what it takes to upload a custom avatar in the Apple Support Communities:

You need to get to level 3 - 500 points: 50 ‘solved’ or 100 ‘helpful’ or a combination thereof. Welcome to the forums: I hope you enjoy answering peoples questions and hopefully gaining points (and karma) by helping them.

This is bonkers. I’ve never seen any other forum work this way. On Stack Overflow, an immensely more important website than, you get to use a custom avatar right out the gate. Same for every other major site I’ve ever seen.

I’m sure Apple has a reason for this restriction. There’s always a “good” reason, just like there’s always a perfectly rational explanation for walking around in white socks, crocks, cargo pants, and a fanny pack, with a side of wispy beard. But the fact that this problem has been solved by other communities proves that it doesn’t have to be this way. Apple should want as many people at its community to have custom avatars as possible. Default avatars are McDonald’s; custom avatars bring culture. It makes no sense to me why Apple restricts customer avatars to the 1%.

How to Hide Recent Apps From the Dock in macOS Mojave  

Until Mojave, if you quit an app that did not have “Keep in Dock” enabled, it disappeared from the dock immediately. Mojave changed that. Now it sticks around for a while. That’s irksome; I thought it was a bug until I realized it was a new Mojave feature. You can undo this feature by going into System Preferences -> Dock and disabling the checkbox labeled, “Show recent applications in Dock.” As a developer who builds new features for a living, I’m aware that developers love forcing their new code on users. But from a user’s standpoint, disruptive changes like this should be disabled by default.


There will always be a reason why the complexity is needed; why it’s an improvement, how it helps things. We as developers are attracted to complexity like a magnet, like a bug attracted to a deadly electric zapper. It’s a rite of passage; complexity means we’re smart, that we thought of it, and that we can handle it. But every time we introduce complexity, we don’t realize until later the complications we’ve added with it. The edge case bugs. The half dozen oh-I-hadn’t-thought-about-that problems.

Sometimes complexity is the only way to achieve the desired result. But often it’s not. Often you have a choice. Choose to keep it simple.

SMS Not Working on Mojave  

User rhettf, writing at the Apple Support Community:

Since updating to Mojave, iMessage on Mac is no longer able to send or receive SMS messages. You get the red exclamation point. I tried signing out of iMessage on the Mac. And also toggling the Text Forwarding to device on the iPhone. Is anyone else experiencing this problem?

My experience is a bit more nuanced than this on Mojave. When I send a text message to an Android user from my Mac on macOS 10.14, the message goes through — the recipient receives it successfully. But the Mac doesn’t recognize this as occurring. It eventually shows an error in the form of a red exclamation mark, as rhettf describes. Moreover, when the recipient replies, I get the reply on my iPhone but I do not get the reply on my Mac.

In other words, on Mojave, sending an SMS technically works, but receiving does not, and neither of these things work from a UI standpoint.

Update: I found a fix that works for my computer. As you can tell in the link, a lot of people have this bug still so my solution isn’t the canonical answer, but it did fix it for me. SMS messages now forward correctly to my Mac on Mojave. The secret was signing out of Messages on the Mac (Messages -> Preferences -> iMessage -> Sign Out) and on my iPhone (Settings -> Messages -> Send & Receive -> Apple ID: {email} -> Sign Out). After that, I signed back in, taking care to use the same email address everywhere. Technically I have a total of 3 different email addresses associated with iCloud, all with the same account, but you have to log in using the primary email address everywhere, and then it works. If you’re not sure which is your primary email address, you can view it here. The reason that it appeared that this problem began occurring on Mojave is because somehow my email address for Messages got changed to a different one. Maybe I messed that up when upgrading to an iPhone XS. In fact in hindsight, I’m not sure if the problem was upgrading to Mojave or getting a new iPhone. I did them both just a few days apart.

The Chapters  

If you’re into nerdery memory skills about the most popular book in the history of the human race, I made this for you using Svelte.

How I Clean My Computer Screen

I’m incessantly dismayed at how dirty are most people’s computer screens. This is avoidable. It makes no sense to spend thousands of dollars on a computer that you don’t keep clean.1

If you don’t keep your computer screen clean, it’s ugly in the short-term, and it’s downright damaging in the long-term. When it’s there for months on end, that grime has a way of eating the screen; you’ll never be able to fully get the scar tissue healed. A case can be made for meticulously cleaning your screen every week.2

After years of trial and error, I’ve come upon the perfect method for keeping my computer screen as spotless as it was the day I removed the protective paper. First I set the screen brightness to zero and turn the screen so it reflects the light. Then I use a Falcon Touch Screen Wipe to get the major stuff off. After that’s dried, I use a microfiber cleaning cloth to remove the dried water streaks. You can use one that came with your sunglasses. Or these on Amazon look promising. The key is to make small circular strokes and to stay gentle. I spend a few minutes with the microfiber cloth. It takes patience to get the screen completely spotless and lint free. It’s worth it.

If you don’t start with a wet wipe, you run the danger of scratching your display. If you don’t finish with a dry cloth, you can’t fully get rid of the water streaks. It takes both, in that order.

I do this every week, and my screen looks amazing. That’s all there is to it. You’re welcome.

  1. How many muddy Lamborghinis do you see cruising down the road? ↩︎
  2. Your mileage will vary depending on how much you travel with your computer, and how much you eat and talk near it. A weekly cleaning might be excessive if you’re a few levels of careful above me. In my case, spit, dust, and food are summoned to my screen on an almost daily basis. ↩︎

The iPhone Franchise  

Ben Thomas, two days ago:

Apple released a new flagship iPhone yesterday, the iPhone XS.

This is the time of year where your social circle rolls its eyes at the “lack of innovation” that Apple demonstrated with its new iPhones. It makes you smile wanly though, because you know they have last year’s iPhones, and somehow, by this time next year, they’ll own this year’s. That’s because the iPhone is a franchise. Ben Thompson does a fantastic job laying this out, and I recommend reading his piece in its entirety. It’s calm, objective, and adroit, as usual.

GitHub Removes jQuery From Its Frontend  

The GitHub engineering team:

We have recently completed a milestone where we were able to drop jQuery as a dependency of the frontend code for This marks the end of a gradual, years-long transition of increasingly decoupling from jQuery until we were able to completely remove the library.

jQuery played an important role back when the ecosystem of native JavaScript DOM APIs wasn’t as robust as it is today. At this point, I don’t think anybody really needs jQuery. I removed it from Drinking Caffeine last November. Rest in peace, once-useful thing.

GitHub’s iterative approach is perhaps the most important takeaway in this piece. The company has proven that big refactors are achievable if you’re willing to play a slow steady game.

Chrome Celebrates Ten Years With a New Look  

Ellie Powers and Chris Beckmann:

Today we celebrate Chrome’s 10th birthday, and just like a kid on the cusp of double digits, we’re constantly growing and changing. In the case of Chrome, those changes happen every six weeks to bring you new features and security updates, but our 10th birthday update is bigger than normal.

The new Chrome is awesome. It’s a fantastic update to the world’s greatest browser. Some Mac pundits have decried its look as being un-macOSy, but seriously, I think Chrome has a better UI and UX than does Safari for Mac. Specifically:

  • Safari’s address bar animation that occurs when you focus on it is distracting and time-consuming. It makes me feel inefficient. I know you can start typing in Safari’s address bar before the animation has completed, but still. Perception is reality.
  • Safari’s address bar is narrower and shorter than Chrome’s, which means it’s harder to click it. Small targets make for bad UI/UX.
  • Safari’s developer console feels 5 years behind Chrome’s. It has fewer options and it’s harder to do stuff in it. That might just be because I spend a lot more time in Chrome’s, but I don’t think so.

Apple should learn from Google how to build a good browser.

On Apple’s Discontinuation of the iPhone SE

Yesterday Thomas Brand wrote a piece that decried the removal of the iPhone SE on the grounds that it was the company’s only affordable iPhone for some customers. The underlying assumptions rubbed me the wrong way. I’m compelled to counter them here. He wrote:

If you are looking for a phone with a smaller screen, a phone with a headphone jack, or or a phone that costs under $400, Apple no longer makes an iPhone for you.

That’s fair, but the universe of people for whom any of this is true is small. Most people are happy with the screen sizes, port options, and pricing of the new lineup. Apple doesn’t like a product line with a long tail, and the time to remove the SE has come. Simplify, simplify, simplify.


In short, Apple has discontinued their entry-level iPhone SE in favor of larger phones that require additional adapters and cost upwards of $750.

I’d be curious how many people actually use adapters with their iPhones on a regular basis. I’m sure they’re out there, but my gut is that it’s a very small (albeit irksomely whiny) community. The puck has moved on.


The iPhone SE kept me invested in the iOS ecosystem, and enabled me to purchase a Apple Watch without approaching the ~$700 iPhone ASP I normally attribute to laptop computers. Now that an updated iPhone SE is no longer an option, I am evaluating alternative cell phone platforms. I am sure I am not alone.

I don’t know anybody who uses a $700 laptop. With tax included, I paid $3,037.39 for the MacBook Pro on which I’m writing this. A friend of mine paid around that amount for the Windows laptop he uses. If you use a laptop for work, you’re paying many multiples of Thomas’ figure. $700 will buy you a fairly decent Chromebook or a really horrific Windows machine. Both options are very pedestrian.

Apple made something very clear this week. If you don’t have $750 for an iPhone, you aren’t in its target market. Apple’s always been this way, directionally: to own an Apple product, you pay big money, often more than the competition, and in return you get a great product that has culture and taste. That’s the value proposition, the rule of engagement. If you find this appealing, you participate in Apple’s store. Otherwise you don’t. Apple isn’t that interested in people for whom money is the primary consideration. Apple was founded by a self-identifying hippie, and it wants customers who care about more than money. If everything in your life lives and dies by the almighty dollar, then you’re never going to understand or appreciate Apple. The company has sometimes managed to ensnare such persons by offering a low-cost product; but whenever it pulls it, their true colors show. Apple did everyone a favor this week by removing an iPhone priced as the SE was.

(Hat tip to Pixel Envy.)

Assign to New Variable Names in an Object Destructuring  

I had no idea until today that this was possible. But take this:

const user = {
  device: 'android',
  statement: 'iPhone X has the exact same OLED screen that Samsung phones have, albeit overpriced.',

Let’s say we want the statement piece of this object, but we don’t like the property name. We can do like so:

const { statement: claimChowder } = user;

Now, the claimChowder variable has the value:

iPhone X has the exact same OLED screen that Samsung phones have, albeit overpriced.

Groovy, right?

New iPhones to Be Announced September 12  

Juli Clover, writing at MacRumors:

Apple today sent out media invites for its annual iPhone-centric event that will be held on Wednesday, September 12 at 10:00 a.m. at the Steve Jobs Theater on the Apple Park Campus in Cupertino, California.

That’s the same date it was held last year. I’m stoked! Also, I wonder what they’ll call these new iPhones.

The Downsides of a Static Site Generator

Lately I’ve been concerned about static site generators. After using Jekyll and then Hugo extensively for a combined 2.5 years, I’m seeing things in new light.

First though, going from WordPress to Jekyll and Hugo is really popular. Here are the upsides of a static content generator:

  • It’s cheaper. You can host on GitHub pages, which is free.
  • It’s safer. A site that is nothing but .html files can’t be hacked, unless permissions are wonky.
  • It’s geekier. There’s a higher barrier to entry because it takes more knowledge than running a WordPress site. The exclusivity appeals to nerds with an ego. If we’re honest with ourselves, few of us who write software for a living are immune to this appeal.
  • It’s faster. There’s nothing faster than running a static HTML site.
  • It gives you version control via git. If you have a deploy process set up, pushing to your master branch is how you deploy a new blog post, which means git is a core part of your workflow.

But! But. There are downsides too. They’re a bit less tangible but they wear on you after a while. Let’s look at them.

  • Architecturally, database-driven design is superior to file-driven design. Marco Arment argued this point on the ATP show a while back. I disagreed with him at the time, but as I’ve gotten more experience and understand the nuances of the two systems, I’ve come to realize he’s right. Chris Pearson recently confirmed this during a Periscope episode. He argued for the superiority of a WordPress theme system being database-driven instead of file-driven. Thesis was built atop the database paradigm. It requires a different way of thinking, but it’s better for a few reasons.
    • Database-driven design gives you better flexibility. If you want to change the date structure or permalink structure of a static site’s posts, or if you want to introduce a new property to a post type, it’s a huge headache. You either have to be a regex ninja or make a lot of manual per-post changes or introduce confusing conditional logic in the render template. All of this is easier in a database-driven design. Same goes for complex things like search and per-month archive pages. Those things are a pain in static site generators compared to WordPress, and sometimes simply impossible given the constraints.
    • Similarly, database-driven design ensures maximum repeatability, whereas file-driven systems contain an innate amount of redundancy. If you’re having to repeat yourself a lot in a database-driven architecture, you’re doing something wrong; whereas in a file-driven architecture, you often don’t have much choice. For example, you often have to loop through a global list of posts and manually cherry-pick the ones you’re after for a given view, rather than just start out with the correct data like you could with a MySQL query.
  • Every time you do a new deploy in a file-driven system, you have to rebuild the entire website. That gets incrementally slower as you introduce more and more posts. Hugo is about 10x faster than Jekyll since it’s built in a compiled language (Go) rather than a scripting language (Ruby). Still, there’s a cognitive overhead in knowing that you’re slowing down the system with every new post you create. Database-driven designs are immune to this. Yes, there’s a slight performance cost to increasing the number of rows in the wp_posts table, but it’s infinitesimal compared to increasing the file count in a file-driven system.
  • Related, every time you write a new post in Hugo, you’re creating a new file in a flat directory. Pretty soon you have hundreds or thousands of files. This just feels wrong compared to having them elegantly tucked away in a paginated database table. Feelings matter.
  • WordPress has 28% of the global market. How much does Jekyll have? How much does Hugo have? A lot less than that. I’m not worried that Jekyll and Hugo will go away tomorrow. But they’re always going to be a fringe technology in the grand scheme of things. Building an empire on a fringe technology is a bad idea. I’ve seen it go awry too many times. And if I had to guess, WordPress will outlast these static content generators, ultimately, from a sheer numbers and sustainability standpoint. I want to use a platform that’s going to be around in 40 years.
  • In a similar vein, setup and configuration with a static file generator has a lot more pitfalls and obscure dependencies. It’s harder to get Go compiled and running than PHP and MySQL, simply because PHP and MySQL are more popular. You also have to support a deployment pipeline with a static site. I’ve personally found that the ongoing maintenance of a regularly-deployed static site is higher than the ongoing maintenance of a WordPress site. That is something I would not have expected. Live and learn.
  • Getting your content from WordPress is a lot easier than from Jekyll or Hugo. That’s because it’s easier to get importable data out of a database than it is from a collection of markdown files. I like systems that are easily exportable. Because of this, switching to a file-driven system seems like a step backwards in time, not forwards.
  • Bonus round: using a file-driven system means you don’t get to use Mars Edit to write your stuff. You’re stuck in Terminal and VSCode, which wouldn’t be a problem except that you’re in there 8+ hours per day already. Never underestimate the appeal of using a different set of equally elegant tools. It provides a mental break. That’s incredibly important. The most enjoyable tools are those dedicated to the job at hand.

On the whole, the cons of a static file generator seem less tangible than the pros. But I’ve been giving a lot of hard thought to this over the past few months. Intangibles matter. As a result, I’m seriously thinking about switching from Hugo to WordPress. Googling around, I’m not sure anyone’s done this yet. If I pull the trigger on the switch, I’ll be pioneering new ground and documenting the process as I go. Stay tuned. 😎

Update October 17, 2018: As I’ve given this more thought, the merits of a WordPress system are elusive compared to its downsides. A highly optimized WordPress site can only load as fast as a static HTML site does by default. And it costs substantially more, and it’s not stored in git, and you can’t use your IDE of choice. Why switch back to WordPress?

Thoughts on WordPress’ Gutenberg

First, watch this engaging Periscope by Chris Pearson, where he argues that Gutenberg is forcing a fork in the road for everyone. It’s well reasoned. But here are some counter-thoughts, from the perspective of an outsider.

  • Something is missing from Pearson’s narrative, the true meaning of which we often forget: simplicity is the ultimate sophistication. That doesn’t mean that things that appear simple are in fact truly simple. It means that things that appear simple require a lot of what Pearson would call “bloat” under the hood. While Gutenberg’s underlying architecture introduces greater code complexity, the resulting UI looks simpler. Gutenberg’s value proposition is to make things easier for the writer, in the same way that the original Gutenberg printing press introduced greater complexity but made book production easier. Making things easier (simpler) often requires added layers of underlying complexity (sophistication).
  • We’ve come to expect this sort of increased complexity in operating systems. macOS is infinitely more complex than it was when it debuted in 2001. So is iOS today compared to 2007. Does anyone really think that the original versions of these operating systems were superior compared to today’s? The “tell” in knowing where people stand on this is whether they upgrade. You can virtue signal all you want about the good old days, but when it’s all said and done, if you upgrade, you’re admitting that the latest is better overall. Are the rules of engagement that we set for operating systems different than what we expect from WordPress? If so then why?
  • I don’t agree that Gutenberg is more complex than what it’s replacing from a UX standpoint. That’s only the case if you have heretofore been creating simple blog posts and you’re now wanting to create more complex ones, and that isn’t a fair comparison. If you’re always doing simple, Gutenberg provides a simpler UI. If you’re always doing complex, Gutenberg provides an abstraction from the HTML. In either case, it’s better for people who don’t want to get into the HTML.
  • It’s not a winning strategy to avoid change simply because of the mere potentiality of it causing problems tomorrow. First you have to quantify the likelihood of those problems. What’s the probability that embracing Gutenberg today is going to cause debt tomorrow? In order to answer this, we have to look at Pearson’s concerns:
    • Using Gutenberg locks you into a complex, opinionated system. That’s fair. But we buy into new things all the time. I don’t have an elegant exit strategy if I ever want to move away from Apple’s walled garden. I’m ok with that. I don’t view that as debt. It’s a lifestyle choice. Sometimes the best things in life are strongly opinionated and locked down.
    • Pearson has high confidence that projects that rely on Gutenberg are going to break in a few years. But WordPress is here to stay, and Gutenberg is here to stay. Do I think individual implementations will get top-heavy? Sure they will. But that’s true of any technology. Your mileage with Gutenberg will be defined by what you make of it. You can ruin an ice cream cone by insisting on having 5 scoops of ice cream. Does that mean that the ice cream cone concept is fundamentally flawed?
    • “But Gutenberg makes your site load slower.” If that’s really true, I have confidence that the community will address it. In reality, I have a feeling that Pearson’s threshold of “unacceptably slow” is simply lower than the community average, and that Gutenberg is “good enough” in speed for most people and situations.1 And regardless, the way most people use WordPress is already slow. The low hanging fruit to making a WordPress site load faster is by reducing your JS and CSS footprint, and changing how those resources are loaded.
  • Clearly, Chris knows a lot of people who are not reaching their goals with WordPress, and Gutenberg is providing confirmation bias that the technology is the problem. I’m skeptical here. It makes a nice scapegoat, but technology is only one piece of the puzzle. Human factors are the primary make-or-break. You can have the greatest site in the world, but if you don’t have eyeballs, it means nothing. You can have the greatest technology in the world and have eyeballs, but if you don’t understand human psychology and marketing and you don’t have a stellar value proposition, it means nothing. The meta involved in how your website is served up is important, but it’s a detail in the big picture. It’s the process, not the product.
  • WordPress is moving where the puck is headed. Medium has made WordPress’ pre-Gutenberg editor interface look arcane and cumbersome. It’s time to move forward. This is what that looks like. Welcome to the future.

This saga reminds me a bit of the recent fallout some people had with Twitter. There was a small vocal minority that deleted all their tweets, and went to their blogs to whine about it. And there will be a similar minority of site owners that fork WordPress or switch to Ghost / Jekyll / Hugo / whatever. The terrier barks, but the semi keeps moving. Whether you view this as “the herd running off the cliff” or “that terrier is getting on my nerves, I wish I could run over it,” depends on whether you’re in the semi or not. Both viewpoints have merit, and only time will tell who is directionally more accurate. Either Pearson’s Periscope won’t age well, or it’ll be an uncanny prediction, a “told you so” moment. We’ll see.

  1. And after all, we wouldn’t want websites to get so fast that Google AMP is no longer useful, would we? 😜 ↩︎

Inspecting Elements in Chrome that Only Appear Via JavaScript Event Listeners  

Some DOM elements appear on hover because in CSS they’re targeted with a :hover entry. In those cases, you can use the attribute modifier in Chrome to synthesize :hover, which lets you inspect the element in its hovered state without having to physically modify the document.

In many other cases though, DOM elements appear on hover via a JS onmouseover event or similar, which hoverIntent (or a similar in-house solution) picks up and programmatically applies a CSS class or series of classes. In this scenario, freezing the DOM to a state where you can access the modal / popup / tooltip / whatever is harder. That’s where this Stack Overflow solution comes in. I wish I’d known about this years ago.

Slack’s Design Flaw

For as long as I can remember, I’ve hit the “+” next to “Channels” in Slack’s sidebar when I’m wanting to view a preexisting channel. This doesn’t result in what I’m expecting though. Instead, I’m taken to a screen where I can create a new channel. To get to what I’m after, I have to click the “Channels” text. This happens to me every single time and it’s frustrating. It’s also inconsistent with the “Direct Messages” and its corresponding “+” button, because both of those take you to the same screen, where you can chat with preexisting users.1

At a company meet-up last year, I noticed that my coworkers were making this same mistake. We’d been using Slack as our primary communication tool for more than a year at the time, and we were still making this mistake. It wasn’t just me. The UI was genuinely confusing and needed improvement. We kept going to the screen for creating a new Slack room when all we wanted to do was join a preexisting room.

I sent Slack a support ticket about this 10 months ago and got a “We’ll pass along this feedback!” kind of response. Nothing material has been done about it. Today I’m still making this mistake. For the most part, Slack is a very well designed application for an HTML product.2 But this one thing desperately needs improvement. Since you rarely want to create a channel, I’d recommend burying its button somewhere in the dropdown that appears in the top left corner of the screen. The “+” icon next to “Channels” is prime real estate and should let you choose a preexisting channel.

If Slack doubts I’m right, I recommend it Amplitude-log how many times people hit the “+” button and create a channel, versus how many people hit the “+” button, hit Esc, and click on “Channels.” I’m willing to wager that 98% of the time, people click the “+” and don’t mean to, because it doesn’t do what they think it does.

  1. Obviously these two sections — “Channels” and “Direct Messages” — aren’t quite the same thing. You can’t create a new user in the way that you can create a new channel. But having the same UI element perform different things when clicked based on where it’s at in a related section is a design flaw. ↩︎
  2. The “for an HTML product” here is key. More on that later. ↩︎