Why Light Modes Are Better for the Eyes  

Turns out, there’s scientific reasons backing up the argument that light modes (dark text on light backgrounds) are better than dark modes. We live in an an era in which websites, apps, and operating systems are trying hard to accommodate both. But they’re not created equal.

CSS-Only Async Chat  

Add this to the list of “using CSS for things that most people would say require JS.” This is one of those incredibly innovative things that you would never do unless you were truly resource-constrained and couldn’t use WebSocket and Ajax. But knowing that it is possible and how it’s possible is worth the read.

8-Digit Hexadecimals  

I’m not sure how I never knew about this, but you can specify transparency in a hexadecimal color in CSS. Keep in mind that IE 11 and Edge don’t support this yet, but you can get around that by using something like SCSS that then compiles this into a more compatible and recognizable rgba() output. Serious levels of Unobtanium, this.

Chrome 73 Brings Dark Mode Finally  

This looks so good. I refused to use a dark Chrome theme because I just couldn’t stomach the gradients. So I’ve gone from the native light mode to this native dark mode after many moons of waiting.1 The new breakpoint editor is also amazing.

  1. Ever since Dark Mode came out in Mojave last fall. ↩︎

Navigating macOS Dialog Boxes Using Keyboard Only  

Dave Land:

tab moves between buttons
space presses focused button (with blue outline)
return presses default button (with blue background)
⌘+first letter on button presses that button (works sometimes)
⌘+. cancels
esc cancels (works sometimes)

I’d forgotten ⌘+first, and I don’t think I’ve ever known about space and ⌘+.. Definitely going to be using this.

January 2020 Will Be End of Life for IE10  

From the Microsoft blog:

You will have until January 2020 to complete the transition from Internet Explorer 10 (IE10) to IE11. After this, we will not release any security or non-security updates, free or paid assisted support options, or online technical content changes for IE10.

Once IE10 and eventually IE11 die the death, it’s not clear what we’re going to be doing with all of our free time. It will feel weird only having to write code for browsers that actually adhere to web standards.

Confusionsoft Changes Its Name  

Whenever you see one of these announcements, keep this in mind: a name change usually means that a company wants to change the perception of its brand.1

Back in my college days when I did a lot of freelancing, I worked with Infusionsoft on a number of client projects. It was a hefty piece of machinery and nowadays the much simpler GetDrip.com does everything it did, except it doesn’t come with a $2,000 initiation fee and a steep learning curve.

  1. Case in point: Apple isn’t going to be changing its name any time soon. ↩︎

How to Connect Your Old Thunderbolt Display’s Magesafe to Your 2018 MacBook Pro  

If you have an old Thunderbolt Display and a 2017 or 2018 MacBook Pro, I can’t recommend this $20 cable too highly. It allows you to recharge your laptop using the Thunderbolt Display’s Magsafe connector, which means you don’t have to take your laptop’s power adapter out of your bag.1

  1. It’s also a useful cable if you have some old power adapters lying around that are based on the old Magsafe connection. This cable will make those power adapters compatible with your new MBP. ↩︎

New Beginnings  

Drinking Caffeine has always been technology-focused, and it will continue to be so. But I might be writing at it a bit less in the future. I’ve dusted off an old domain of mine, martynchamberlin.com, and I’m using it to write about something that matters more than technology. See you there.

Aws Replaces MongoDB With Proprietary DocumentDB  

You can assume that when a company gets to a certain size, it’s going to replace its open-source version of something with a company-flavored version that is better tailored to its needs. I think if AWS had chosen to fork MongoDB in a way that was open source, the optics would’ve been better. That didn’t make business sense though because Amazon had already spent its open source budget on a Wikipedia donation. Sorry, fam. Next time1

  1. I’m being cavalier here but make no mistake: it costs a lot more money doing something open-source than it does doing it closed-source. Anyone who’s worked at a company that actually did something open-source knows this. Not only do you have to do the same amount of work but you have to do it in a community-driven fashion, and that’s always less efficient. I assume there were also strategic reasons why closed-source made more sense for the AWS. ↩︎

Slack Gets a New Logo  

Instant win. Looks so much better on my iPhone home screen. Some people don’t like it, but they’ll get over it.

Things Dan Abramov Doesn’t Know  

Close to the bottom of last week’s issue of JavaScript Weekly, this article caught my eye. It’s a list of things that Dan doesn’t know. This one particularly stuck out to me, mostly because I know Flexbox very well nowadays:

  • Modern CSS. I don’t know Flexbox or Grid. Floats are my jam.

It’s always a weird feeling when someone who you consider an intellectual giant has a gap that you don’t. This is a great article.

A Horrific Javascript Bug in Safari  

This Stack Overflow thread talks about a JavaScript bug where the state of a JavaScript variable persists across multiple page sessions which is something I have never seen in nine years of web development.

MultiplyByZer0, writing on Sack Overflow:

It’s definitely a BUG! And it’s a very serious bug.

The bug is due to the optimization of array initializers in which all values are primitive literals.


The reverse() method mutates the array, so it should trigger a copy-on-write. But it doesn’t, because the original implementor (Keith Miller of Apple) missed the reverse() case, even though he had written many testcases.

Safari may be blazing fast and battery efficient, but in order to achieve that, the engineers are having to introduce a level of complexity and shenanigans that allows this sort of bug to creep into the mix. Not groovy.

And no, this bug is not fixed on all of Apple’s latest stable releases. You can still demo this bug in action on Safari on a Mac. [Update January 11: ok, it looks like this bug is fixed with macOS 10.14.2. But the reality is that millions of Mac users aren’t on this version yet (including yours truly). If you run a website that uses Array.prototype.reverse(), just because you’re on the latest version doesn’t mean that your users are. In this vein, Safari shouldn’t be held hostage to Mac software updates. In other words, you shouldn’t have to restart your computer in order to get the latest version of Safari. Browser updates should be fast and seamless and independent of OS version, similar to how Google Chrome and Firefox operate. That way, when Apple makes blunders like this, it can bring the fix to a higher number of users with a faster metabolism.]

It’s this kind of nonsense (as well as Apple’s stubborn position to be the only browser that does not support pointerdown) that makes frontend developers mock Safari and refuse to take it seriously.

GitHub Free Users Now Get Unlimited Private Repositories  

I’d be $411 richer if GitHub had started doing this back in 2013. This is great news though. I’ll no longer recommend anyone use BitBucket for any reason whatsoever. It was an inferior service in every way except one, and now that’s gone.

Yearly Reaches 97th Overall in Reference Category in App Store

After having dabbled in iOS development since 2013, about a year ago I finally had the urge to put an iPhone app into the App Store for others to enjoy. On December 31, 2017, I announced the launch of Yearly, a simple app that lets you read the Bible in one year. I’d built most of it in a single day, on Christmas, in Swift. My expectation was that a few family and friends would download it, and that would be that. What I wasn’t expecting was for it to steadily average a few downloads every day. People were discovering the app without any effort on my part; they were using it, leaving reviews, and emailing me with questions and requests.

I’d originally built the app with just my use case in mind; but as other people downloaded it, I started building out features that would be helpful for others. Midway through 2018, I released an update that allowed you to change your start time to something other than January 1. To achieve this, I had to overcome the complexity of supporting leap year. If you encounter a leap day (February 29) in the rolling 1 year window of your current schedule, you should spend 366 days reading the Bible. Otherwise you should spend 365. That sounds simple but the date math is a bit harder than you’d think. I created a dedicated open repository on GitHub with Jest unit tests to properly solve this complexity. Being more familiar with JavaScript than Swift, I explored the problem in JavaScript and then ported the solution to Swift once I was satisfied with my test suite. Yearly was positioning itself as a simple, elegant Bible reading schedule with a degree of sophistication behind the scenes that set it apart from its peers.

About 3 weeks into August, less than 9 months after Yearly’s debut, it reached 1,000 unit downloads. This wasn’t bad for an app with limited functionality and for which I was doing zero marketing.

Then in December, I got an idea based on some feedback I was hearing from different people: Yearly should support deep linking its daily reading to the corresponding book and chapter in YouVersion, the number one Bible app on the App Store. On Wednesday, December 7, 2018, I arrived at my co-working space in the cold 7:00 AM darkness, and began working on this. I finished this on the 8th and submitted the change to the App Store for review.

Then something unexpected happened that threw me off guard. The team reviewed the app on the 9th and rejected it. I’d never had an app update get rejected. This was new territory for me. The explanation for the rejection was twofold:

  1. First, the deep linking wasn’t working for the reviewer because they didn’t have YouVersion installed. If you don’t have an app installed that’s being deep linked to, nothing happens by default. It just fails silently.
  2. The second stated reason was that the app was failing to meet minimum functionality guidelines.

I ignored the second message at first, thinking it was optional guidance, and not a big deal. I updated the deep linking process so that if you didn’t have the YouVersion app installed, you would get redirected in Safari to the equivalent on Bible.com, a website maintained by LifeChurch, the same outfit that produced YouVersion. This way, no matter what, tapping on the schedule for a given day would result in something happening. I updated the build number and resubmitted the app on the 9th.

On the 10th, the review team again reviewed and rejected the app. As I conversed with the reviewer in the Resolution Center it became apparent to me that this second guideline failure was indeed a sticky point. Here I was, extending the functionality of my iPhone app, and the purported reason this update was getting rejected was because the app didn’t have enough functionality. It made no sense to me. Going back and forth, I could tell we were getting nowhere. The canned, nebulous responses from the other end began to irritate me. My app was creating value for hundreds of people who were using it on a regular basis and my update was making it even more useful, and this update was getting rejected on the grounds that it failed to meet certain guidelines. I was experiencing the walled garden of Apple and starting to have sympathy for Android’s open stance on apps. Flustered, I threatened to submit an appeal to the App Review Board if the app weren’t approved. The reviewer took the hint and on the 12th scheduled for an Apple representative to call me and discuss my app’s review.

On December 19th at 6:17 PM CST, I got a phone call from San Jose.1,2 The person identified herself as Kelley from Apple. We talked for 17 minutes. She was very friendly and professional and I finally got clear answers. What I learned was this. Apple’s guidelines had changed. As its APIs increased in robustness, the bar for what’s expected likewise increased. The version of Yearly I had submitted in late 2017 would likely not have been approved had I submitted it today. The fact that people were getting value out of the app had no bearing on this. An app, no matter how useful to a segment of users, is either in compliance or it’s not, and Yearly was not in compliance. Because of this, Apple could pull the app from the App Store at any time it wanted, and in the interim it would only accept an update that brought it back into compliance. In order to achieve this, Kelly told me that the Yearly would need to allow users to interact with the content more. Some examples she gave me were:

  • It could allow people to share its readings on social media. Or,
  • It could offer a journal where people could write about a given reading for that day. Or,
  • It could have an in-app Bible so people could visit it directly without leaving the app.

This last part was a sticky point. By deep-linking to YouVersion and then sending people to the Bible.com equivalent as a fallback, I was breaking a few different guidelines:

  • An app cannot be dependent upon another app to meet its functionality, so shuttling you off to YouVersion like that was a no-no.
  • An app cannot take you to a website in Safari without a way to get back to the app. You’d need to use a UIWebView within the app itself, but doing that would require permission from the website if you weren’t its owner.

We finished the conversation on amiable terms. I had a clear picture of what I’d need to do in order to get Yearly back in compliance. I had two choices. First, I could do nothing, and freeze Yearly until the App Store finally decided to pull it from the store for being out of compliance. Second, I could roll up my sleeves and get to work bringing it back into compliance. It wasn’t hard for me to decide which of the two options I’d choose.

On Saturday, December 22, I began work on Yearly 2.0. I completely scrapped the StoryBoard I’d originally built it in and used programmatically-generated UIView's instead, learning how to set auto constraints programmatically (hint: it’s actually a lot faster than using StoryBoard once you get the hang of it). I made a lot of improvements, including switching the home screen to a scrollable UITableView for your entire year, with each day locking into place as you scroll.3 I added the ability to earmark each day as read. I added the ability to share on social media. I overhauled the screen for how to change your start day. And then I added an easter egg: by double tapping on the lower region of the screen, I deep-linked you to the YouVersion reading. The left half sent you to the Old Testament reading for the current day, and the right half sent you to the New Testament reading. That was a feature I wanted — I frequently listen to the YouVersion audio on my way to work — and I was going to get the last laugh on this.

By January 3rd I’d finished my development after 25.77 hours of intense focus over the holidays, and submitted the new build to the App Store for review. On the 4th the team reviewed and approved the 2.0 update. Yearly was back in compliance once more. In hindsight, the rejection it’d had weeks earlier was the best thing that could’ve happened to Yearly. It forced me to retool and make it better.

Meanwhile, something else was afoot. Yearly’s popularity was skyrocketing as Bible readers prepared for a new year. As I’m writing this, the most recent analytics I have in App Store Connect are for January 3. In the 7 day window ending with that day, Yearly was downloaded 2,372 times. On the 4th I noticed that it was 97th overall for the Reference category. Presumably its rank was higher on January 1 when it had 795 downloads in a single day. All of those downloads were for an app that, at the time, was out of compliance with Apple’s guidelines.

In the grand scheme of things these numbers are small potatoes. Yearly is just a side project. But I’ve learned a lot from it. If you haven’t downloaded Yearly for iPhone, you should. And if you’re not already on a good Bible reading schedule, I recommend starting today!

  1. The days leading up to this, I’d made the unusual step of keeping my phone’s volume turned on more frequently (normally, I keep my ringer off perennially), and paid closer attention to my calls. The annoyance of having to carry my phone with me everywhere and answering a myriad of robot calls reminded me of why call-based communication is one of my least favorite. But I didn’t want to risk missing that call, so it was worth it. ↩︎

  2. Thirty-six minutes earlier I’d finished a 10K run, at a pace that at the time was a record for me. The 6:57/mi pace effort had me in an exhausted but euphoric state of mind. Just nine days later I would break that record with a 6:49/mi pace. Of course, I didn’t know this at the time, and when the phone call was over that evening, I mused that this record wouldn’t have happened if the call had occurred less than an hour earlier. I would’ve resorted to a walk to field that call. ↩︎

  3. Having 365 rows in a UITableView is no laughing matter. At 200 pixels height per row, that’s 73,000 pixels in height. Programmatically detecting how far down you’ve scrolled becomes unreliable and caps around 25,000 pixels in my experience. Getting this UX to be smooth and knowing how to properly scroll was non-trivial. ↩︎

CSS Tricks’ New Scrollbar  

I’m glad Firefox no longer supports customizing scrollbars in CSS. That means that you still have one browser left that you can use to visit CSS Tricks whilst keeping your sanity. The CSS override that the site is attempting to make, which is sadly compatible with Chrome and Safari, is one of the least flattering scrollbar decisions I’ve seen. Thirty pixels is entirely too wide for a scrollbar. Skeumorphism is equally unwelcome here. In anything other than Firefox, you’re subject to both violations.

Xcode Theme for VS Code  

If you’re in a situation where you don’t get to spend all day in Xcode, but hope one day you can, this theme should get you by for now.

Derek Halpern Is Quitting Social Triggers  

Derek Halpern:

So, I have some BIG news…

I am going to open enrollment for each of my online courses one last time (on December 14th)… and then, I intend to never sell these courses again.

Derek started Social Triggers in 2011. That same year, I got to meet him at a conference in Los Angeles. It was before his business had taken off mainstream, and I remember his keynote audience being relatively small compared to the others. But it was clear he was on the cusp of greatness. The golden era of the web was in full swing, and those early years were truly amazing to watch.

Time has a way of changing things. No matter how good your what is, if you don’t have an equally good why, you’ll eventually quit.

Crying Foul  

Elliot Condon, founder of the wildly popular Advanced Custom Fields plugin for WordPress:

The honest truth: WordPress 5.0 is not ready, and neither is ACF. Hats off to all the amazing web developers working on updates to their plugins, themes and client projects when they should be enjoying some well earned time off with family and friends. ❤️👨‍💻👩‍💻

That’s not something to celebrate.1

  1. It’s telling that Matt Mullenweg felt the need to respond. ↩︎

Goodbye, EdgeHTML  

Chris Beard, writing at the Mozilla blog:

Microsoft is officially giving up on an independent shared platform for the internet. By adopting Chromium, Microsoft hands over control of even more of online life to Google.


We compete with Google not because it’s a good business opportunity. We compete with Google because the health of the internet and online life depend on competition and choice.

There’s a minority of people who are concerned about Microsoft’s announcement. Everyone web developer I know who actually has to comply with browser standards is very happy to hear it though. In a perfect world, there would be one open source browser with 100% market share.