On web browsers ignoring autocomplete="off" for passwords (and, on devbros ignoring the messiness of reality)

A couple of frustrating things have occupied much of my afternoon: unexpected web browser behavior, and annoying devbro behavior.

The unexpected web browser behavior was a stubborn, persistent refusal to honor the autocomplete="off" attribute for passwords. The annoying devbro behavior was a stubborn, persistent refusal to honor the legitimacy of a question. In this thrilling post, I’ll be looking at both.

tl;dr

If you’re just trying to find a simple way to get browsers to honor autocomplete="off" on password fields, here you go: THERE ISN’T ONE. Browsers ignore it for a legitimate reason, but I feel they’re overzealous in their implementation.

However… if you’re trying to do what I was trying to do — basically using a password field as a write-only input — it’s never going to work, for a completely different reason. Why? View source and get back to me.

The only way to really create a write-only input is to not pass the value into the form at all, and have some other mechanism on the back end to detect whether or not the user entered a new value.

I was working on an admin page for a site I built; specifically, a page for editing some low-level configuration settings on the site.

One setting is the “client secret” for authenticating with an external API. I realized having that visible on-screen (even if it’s only on pages that require an administrator-level login) was a bit of a security issue, so I thought I’d quickly solve it by changing the input from type="text" to type="password".

Well, not so fast. Because while it worked, it also triggered Safari’s autocomplete feature, replacing the value in that field with my password for the site, and, maddeningly, replacing the value in the field before it with my username.

Then I remembered an attribute I almost never use: autocomplete="off". I figured I’d just stick that on those fields and, boom, problem solved. Only then I realized, Safari (and as it turns out, every other modern browser) completely ignores autocomplete="off" on passwords.

I set off for StackOverflow in search of an answer to my conundrum, and as is often the case, I stumbled upon another maddening thing: a devbro offering a “You’re doing it wrong” answer. (Seriously… I mean, I know nothing about the author of this post, so I wouldn’t use that epithet, but he literally said this:

It is so wrong that browsers are intentionally ignoring anyone who tries to do it. Those people should stop doing the wrong thing.™

This was at the end of a 600+ word answer that demonstrated classic devbro reasoning:

  1. Rejecting plausibly legitimate use cases as invalid.
  2. Denying obvious design flaws in the existing solution.
  3. Blaming the user for “doing the wrong thing.™”

Back to the specific matter of browsers ignoring autocomplete="off", there are some real problems here:

The autocomplete attribute is standard HTML that browser developers have deliberately chosen to ignore. I understand that browsers are constantly evolving, especially in response to unscrupulous web developers who find ways of exploiting features, and there are definitely ways this feature could be exploited. But!

Browsers are absurdly overzealous in their rejection of autocomplete="off". I was in a situation where the password field was in the middle of a form with 9 text inputs and 5 sets of radio buttons. How often does a login form have all of that? And, none of the fields had “username” or “password” anywhere near them… not in the name or id attributes, nor in their associated <label> fields. AND, there were already prefilled values in the form that got overwritten by autocomplete. AND, Safari is even programmed to aggressively fight any efforts at a workaround, such as extra password fields, hidden with CSS.

It was the last bit that really irked me, because my experimentation showed that Safari is programmed to detect very specific CSS attributes being applied to other fields in the form to determine whether or not there’s a second password field (i.e. that this is a form for resetting your password). If it detects any of various ways of making the field invisible, like display: none; or visibility: hidden; or position: absolute; left: -9999px;, then it will still autocomplete the password. The only CSS I was able to fool it with was opacity: 0; but I suspect that will change soon too.


It’s fine to argue that web developers shouldn’t use autocomplete="off" on password fields, and I even agree, to an extent, for login forms. But if browsers are going to ignore it, and have intricate means of detecting efforts at circumventing that, then they should also recognize that there are legitimate uses for <input type="password"> outside of login forms, and in those cases, honor autocomplete="off".

Here are some suggestions:

Don’t ignore autocomplete="off" if the form contains more than three or four visible input fields. Most login forms only contain two fields. I’ve seen some with more, so I’m being generous here. But how often does a login form contain ten or more fields? Come on.

Look for additional context before autocompleting login fields. Yes, developers can find ways to circumvent this, but if the only clue that this is a login form is the presence of a single password field, then maybe it’s not a login form. Look at the name and id attributes, the <label> tag, and the form’s action attribute. If it really, really doesn’t look like a login form, especially if the developer has also added autocomplete="off", maybe give them the benefit of the doubt and settle down with the autocomplete. At least, maybe in these cases ask the user if they want to autocomplete instead of just doing it. I mean, in some cases the form may be long enough that the autocompleted fields are off screen and the user didn’t even notice they turned yellow.

Don’t replace prefilled values with autocomplete values. I would sincerely appreciate if someone could explain to me the logic behind this one. If a form already has values in the fields, then autocomplete should never overwrite those values. Maybe it’s because I mostly work with HTML forms that are really data editing screens, rather than submission forms, so my perspective is skewed. But the fact that web-based data editing screens are a common thing makes this a valid use case. If a form loads with most or all of the values prefilled, a browser should not presume that it’s OK to autocomplete any of the values.

Check for an indication that the user is already logged in. I suppose there’s a murky security issue here somewhere, but if the browser could detect a cookie with a session ID, or a “log out” link on the page, it would be a way of indicating that the user might already be logged in, and so autocompleting passwords wouldn’t make sense.

Implement support for autocomplete="new-password". Apparently Chrome supports this already, and admittedly it reeks of workaround, but at least it’s something.

With all of these suggestions, I am not saying browsers shouldn’t autocomplete password fields… I’m just suggesting that they look for signs that a password field is not part of a login form, and in those cases, honor autocomplete="off" on password inputs.

The Obligatory WordPress “Gutenberg” Editor Hot Take

Of course you knew I’d have to make a Steve Guttenberg joke to start this off. But maybe there’s something to it. (Side note: I just realized his last name has two “t”s, unlike Johannes, the inventor of movable type.)

I’ve been a professional web developer since before the term existed (1996, to be specific). I’ve been using WordPress for my blog since 2006, for occasional work projects since 2008, and as my primary web development platform since 2014. Working solo and being an introvert disinclined to participate in conferences, my contribution to the WordPress community has come mainly in the form of submitting a handful of plugins to the Plugin Directory. And, of course, writing a ton of blog posts here on various obscure problems I’ve encountered along the way.

I say all of this solely to establish whatever credibility I may or may not need in offering my half-baked assessment of what is, at the time of this writing, a half-baked WordPress plugin… but one that is destined — in short order, and for reasons that are up for much debate — to become the fundamental user experience of writing in WordPress.

If you’re unfamiliar with Gutenberg, here’s the plugin project in GitHub, and here’s a recent blog post by Automattic founder and WordPress development lead Matt Mullenweg defending the rationale for the project, and here are a bunch of other reviews of the project, both pro and con, that I’ve read over the past three days.

So far documentation is (understandably) scarce, but I’ve poked around a bit to learn what I can and see how I might be able to customize it to meet my needs as a web developer building custom themes for clients.

I have a few things about Gutenberg that I’d like to explore with this post:

  1. My initial reaction to the Gutenberg interface itself
  2. Thoughts on how this will affect the work I do
  3. Opinions and speculation on the motivation behind the project

Getting to know Gutenberg

Some of the reviews I linked to above are critical of Gutenberg, in ways I don’t think are entirely fair. Mainly because, yes, this is beta software. In fact, at this point I’d say even calling it beta is generous. This feels more like alpha testing, given how much of the development is still incomplete, and how much things are changing. I just downloaded version 0.9 yesterday and version 1.0 is already out, with a number of significant changes, including some that broke work I was doing on custom CSS styling for Gutenberg output just this morning.

The point is, there are plenty of things to criticize about how Gutenberg works at this point. But it’s important to consider whether or not those are things that are intended to be the way they are, or if they’re just incomplete features or unaddressed bugs. Here are a few of my favorite examples:

First, a screenshot from the special “Demo” page included with the plugin to help users familiarize themselves with how Gutenberg works.

Um… OK. Which “really wide” button would that be now?

One of the demo blocks is an image, and its caption suggests you try out a feature that — as far as I can tell — doesn’t yet exist. This should be your first sign that criticism of the tool may be, at this point, a bit premature.

Gutenberg is full of fun surprises, like things randomly breaking with no real explanation. Welcome to beta software!

Oh this poor, suffering block. Also “previewed” is an understatement. When this error appears, it also means you can’t edit the block in question. Hit Refresh and hope for the best!

But I think the real coup de grâce is the lack of polish on some fringe elements, such as how the text block you’re editing might randomly bounce around the page if there’s a floated image preceding it, as the editing tools surrounding the block you’re typing in appear and disappear. Or this… the beloved triple scrollbar!

Which one does what? Just scroll and see!

I’ve also discovered a fun bug that randomly inserts question marks when you switch italics on/off with keyboard shortcuts. But you don’t see them in Gutenberg, only in Preview mode. And then if you try to delete them in Gutenberg, it just starts randomly eating your text. That’s forced me to go into raw Text mode a few times in this very post to clean up Gutenberg’s mess. (Yes, my secret is out… I’m using Gutenberg to write this post!)

Many other reviewers have noted some of the drawbacks of Gutenberg’s features. It’s still not true WYSIWYG. It seems to want to be direct in-page editing, so why isn’t it that? Many elements are still dependent upon your theme for proper styling (like the margins below captions on this post — but I will probably have fixed that in my CSS before you are reading this). A lot of the blocks don’t really offer many styling options, which seems a bit self-defeating.

And, of course, it seems at this point that it will completely break the old “metabox” concept of the editing screen, and thousands of plugins and themes as a result. I really don’t know how the core team intends to resolve that issue, although sidebar metaboxes seem to be handled under the Document tab in the Settings sidebar. A lot of popular plugins (Yoast SEO, anyone?) that rely on more horizontal width will need to be drastically rethought to work in that context, though.

This leads into my next topic: how will Gutenberg affect the work I do as a web developer?

So… how will Gutenberg affect the work I do as a web developer?

My initial gut reaction to the news of Gutenberg was that it seemed to be eliminating the reason I exist in the WordPress ecosystem. As a developer specializing mostly in custom theme development for clients, it looked like Gutenberg was going to destroy my business. And as an occasional contributor of free plugins to the WordPress community, it looked like Gutenberg was going to create a lot of unnecessary (and unpaid) work for me, rebuilding my plugins to function in this new paradigm.

The latter may well be true, but the former won’t. Gutenberg does nothing at all to eliminate the need for theme developers — it just changes how we do a few things. And, importantly, the ability to create custom block types opens up new opportunities for developers of both themes and plugins to invent new ways of both displaying and working with content in a WordPress site.

The two big questions I’m left with, which are not yet answered, are:

  1. Is this really an improvement over the existing TinyMCE editor, for developers and clients who are using WordPress not as a blog platform but as a general-purpose CMS?
  2. Is it worth adapting to this new way of doing things? Or is this effectively Automattic showing me the door?

Pondering these questions takes me to my final topic…

Why this? Why now? Why at all?

I suppose there’s a “Who moved my cheese?” element to this. After all, I’ve spent the past two years honing my concept of modular design and the first eight months of 2017 perfecting a reusable core theme that relies heavily on Advanced Custom Fields (specifically, Flexible Content blocks) and the WordPress Customize API to achieve many of the same things Gutenberg does. My theme offers considerably more flexibility and formatting options than Gutenberg does, though I will readily acknowledge that Gutenberg seems easier to use than my heavily customized ACF Flexible Content blocks are.

The point is, I am already deeply immersed and heavily invested in a particular set of tools that are intended to achieve many of the same aims as Gutenberg, and that, in some ways, do a better job of that.

But wait, what really are the aims of Gutenberg? Who asked for this? Who is it benefitting?

While Matt Mullenweg talks big about how it will benefit practically everyone in the WordPress ecosystem — developers and agencies, plugin developers, theme developers, core developers, web hosts, and (last, but… not least?) users — it seems clear to me and to a lot of other critics of the project that the primary beneficiary is Automattic itself.

I find it curious that this project is named after the inventor of movable type, since one of the earliest WordPress competitors is called… Movable Type. This project is transparently an effort at fighting back against the likes of Wix, Weebly, Squarespace and Medium, each of which has in its own way been eating away at the potential market for WordPress.

But, you know, I cringe a bit at talking about “markets” when we’re discussing open source software. And that’s the crux of the problem. WordPress has, for many years, existed as a Jeckyll-and-Hyde duo of WordPress.org — the open source project underlying self-hosted WordPress sites and the huge developer and designer community of which I am a part — and WordPress.com — the commercial, hosted, software-as-a-service (SaaS) platform owned by Automattic.

That list of SaaS platforms I mentioned above — Wix, Weebly, Squarespace and Medium — represents competition to both sides of the WordPress dichotomy, but in significantly different ways.

To the open source WordPress.org community, they’re — mostly — competition in that they represent the “low end”. Small businesses and organizations that have limited budgets or a determined DIY ethic are inclined to use them, until they realize how quickly they are hamstrung by the limitations of the tools they offer. Then those businesses and organizations hire designers and developers like me to take their websites to the next level, and we use WordPress as a way to build exactly what they need, because its open architecture and self-hosting mean there’s no limit to our ability to customize WordPress to do exactly what we need. They are also a more ominous existential threat to our businesses, because they’re constantly improving, and eventually they won’t be so limited in ways that work to our advantage. So to that end, we need WordPress to evolve. But Gutenberg seems in some ways to be WordPress skating to where the puck is, rather than leapfrogging the competition, to mix metaphors.

But to WordPress.com, those SaaS platforms are much more direct competition, because they are offering exactly the same thing that WordPress.com offers: a hosted platform with limited customization capabilities. I have steered a number of clients away from Wix or Squarespace over the years, but I have steered just as many away from WordPress.com, and for the exact same reasons.

Medium is another story. In that it’s literally about stories. Automattic is definitely feeling the heat from Medium, but this is a world apart from the scenarios I described in the two preceding paragraphs. Medium is challenging WordPress.com specifically as a blogging platform.

It’s true that WordPress started as blogging software. But over the years it has become so much more than that. I have built over 100 websites on WordPress since switching to the platform full-time in 2014, but every single one of them has used WordPress as a CMS, not as a blog. Hardly any of those sites even have blogs. A key feature of one of the plugins I created, in fact, is to hide the Posts and Comments items in the WP admin interface, since hardly any of my clients use them.

Anecdotal evidence is not data. I wouldn’t suggest that my business use case for WordPress as a CMS necessarily means it should no longer be thought of primarily as blogging software. But I am hardly alone, and I’d be willing to bet that a large majority of my fellow developers who have made a substantial part of their career in client services, using WordPress as the underlying technology, would agree with me. Because… wait for it… blogs don’t make money. OK, a few do. But there aren’t enough profitable blogs to warrant an entire industry of paid designers and developers to build them.

This has been the most jarring aspect of the whole Gutenberg debate for me… the realization that Matt Mullenweg still thinks of WordPress primarily, if not exclusively, as blog software. And it seems that his singular passion is really what’s driving Gutenberg, above all else.

I do think Gutenberg, when it has a few more layers of refinements and polish, will be a superior content editing experience to what the current implementation of TinyMCE offers. But it is a huge change, and I don’t think it jibes with the way most WordPress.org sites use the platform. That’s not to say they can’t or won’t adapt. But it also says nothing about why they should.

Stravinsky on that chord

Up to now I’ve only really been documenting it on Facebook (for some reason), but over the past 3 months I’ve been working on one of my most ambitious music projects yet, a prog/post-rock interpretation of Stravinsky’s Rite of Spring. It’s been an interesting exercise that has helped me to get very (very) familiar with the piece, and encouraged me to research more about its origins.

Today I discovered this delightful video of Stravinsky humorously recounting the early history of the piece. Specifically, demonstrating the chord at the beginning of “Augurs of Spring” to Sergei Diaghilev, the ballet producer who had commissioned the work.

I like very much this chord. It was a rather new chord, you know? An 8-note chord. But the accents were even more new. And the accents were really the foundation of the whole thing.

When I finished composing The Rite of Spring, I played it for Diaghilev, and I started to play him this chord. Fifty-nine times the same chord. Diaghilev was a little bit surprised. He didn’t want to offend me. He asked me only one thing, which was very offending. He asked me, “Will it last very long time this way?” And I said, “’Til the end, my dear.”

And he was silent. Because he understood that the answer was serious.

What is that chord? I think just to mess with us, Stravinsky notated it rather absurdly with F♭s and C♭s. From the bottom up, the notes are: F♭ A♭ C♭ F♭ G B♭ D♭ E♭. So, that’s… um… well, if it were written as E instead of F♭, with ♯s instead of ♭s, it works out to an Emaj7/♯9/♯11/13 chord. Another way to look at it is an E (F♭) major chord with an E♭7 (in first inversion) stacked on top of it. Since Stravinsky was exploring bitonality, this is the most likely explanation, but really there’s no good way to notate it. Over a hundred years later, this is still difficult to grasp.

When WordPress Treats an Administrator Like a Contributor

The first sign that something was wrong was when I tried to create a new page on the client’s site. The blue Publish button I normally see was replaced with Submit for Review. What the…? That’s what WordPress users with the lowly Contributor role usually see. But I’m an Administrator — the most mighty role known to the world of (single-site) WordPress. (Yes, multi-site installations also confer the fearsome title of Super Admin upon a select few.)

Worse still, if I tried to click Submit for Review, it wouldn’t actually save!

Other problems abounded — I tried to create a new user with Administrator privileges, just to see if my own user account was corrupt. Couldn’t save that, either.

I had Debug Bar installed, and I noticed it was giving an error:

WARNING: wp-admin/includes/post.php:641 - Creating default object from empty value
get_default_post_to_edit

Well, that’s not good. Googling the error didn’t lead to anything immediately helpful, besides this comment that led me to explore the database structure in phpMyAdmin for any problems.

Yes, there were problems. Many of the tables, including wp_options, wp_posts, wp_postmeta and wp_users were missing their primary keys. A bit more digging into the WordPress core showed that, for complex reasons (i.e. I don’t totally get it), without primary keys on these tables, WordPress can’t determine the post type of a new post, and if it can’t determine the post type, it can’t determine the user’s capabilities with regard to that post type, which all comes back to…

WARNING: wp-admin/includes/post.php:641 - Creating default object from empty value
get_default_post_to_edit

Googling on the matter of WordPress tables missing their primary keys (or, perhaps more pertinently, their auto-increments), led me to a solution!!

Fixing WordPress indexes, foreign keys and auto_increment fields

Well, a partial solution. Because the database I was working with was not damaged in exactly the same way as the one the OP was working with, I couldn’t use the sample code directly. I had to go through the database and manually create a few primary keys, delete a bunch of auto-draft posts that all had an ID of 0, etc. Then I had to skip a few lines of the OP’s SQL code because they referred to tables that hadn’t lost their keys in my case, for whatever reason. But this is the… key… to solving the problem.

Now then, how did the database get this way? Well, the site lives on a fairly creaky old Fatcow (ugh, that name) shared hosting account, running an old version of MySQL and an almost unrecognizably ancient version of phpMyAdmin. We were undertaking major content changes on the site, so I copied it over to my own sleek, modern staging server running the latest and greatest of everything. The idea was that we’d get all of our changes in place just the way we wanted on the staging server, rather than mess up the live site for 2-3 weeks, and when we were done, we’d just copy everything back over.

Slick. Right? Sure, if both servers are running reasonably identical software versions. Which of course is never the case. Ever.

Apparently when I copied the site back to Fatcow, due to the older MySQL (or possibly phpMyAdmin) version, certain things like the primary keys and auto-increments — and, I’d be willing to bet, but I’m not sure it matters, the collation as well — got lost along the way.