Color Options vs. Decisions in WordPress Themes

One feature I was particularly excited about in Twenty Fourteen is the “accent color” which lets you personalize your theme by changing the default green to whatever you like. Unfortunately the feature was removed in #26220, mainly due to the fact that it allowed users to make bad choices, like using a color with a bad contrast, rendering their website ugly and unusable1.

I’ve been thinking about this a lot after that commit, and even more lately. Many themes come with color options these days and the vast majority suffer from the very same problem — poor user choices.

Take Weaver for instance. The options panel will let you adjust the color of probably any single element on your site:

weaver-color-options

I can’t say I love Weaver’s default look and feel — it’s okay. But it’ll only take a few minutes for an average WordPress user to completely ruin it without even knowing it. Then again, Weaver is a pretty popular theme on WordPress.org and if I had to guess why — it’s the amount of freedom it gives its users via theme options.

But that freedom comes with a price. And I’m not talking about the theme’s pro version, no. I’m talking about the risk users take unknowingly. The risk that could result in poor usability, ugliness and insanely high bounce rates, even if the site looks “just perfect” to the owner.

So how can we protect our users from poor decisions, while still giving them their beloved color options? Providing a predefined set of color schemes is one way of doing it, but this post is about something different.

Contrast Correction with Sass or LESS

You’re probably already familiar with CSS preprocessors, so here’s an interesting piece on accessibility and contrast with Sass and LESS. You can use brightness() or lightness() to help you choose better contrasting colors. You can use darken() and lighten() to alter your colors for better contrast. You can take it a step further and calculate the color luminance and contrast ratios.

But building your WordPress theme stylesheet with Sass or LESS is one thing. Providing users with an option that could somehow magically change and recompile your CSS is another. One way is to bundle a Sass or LESS PHP-based compiler inside your theme, though I’m not sure if the folks over at the Theme Review Team would be very happy about that.

A better way would be to offload CSS compilation into a plugin, ideally one that’s already active on millions of websites, like Jetpack :)

Jetpack Custom CSS

One of the lesser known features in Jetpack’s Custom CSS module is the availability of both LESS and Sass preprocessors, which means that Jetpack already bundles the necessary PHP libraries, and exposes them via functions, such as jetpack_sass_css_preprocess():

$accent_color = get_theme_mod( 'accent_color', '#00ff00' );
$sass = sprintf( '$accent-color: %s;', $accent_color );
$sass .= get_the_rest_of_the_sass_code();
$css = jetpack_sass_css_preprocess( $sass ); // boom!

So in the rest of the Sass code you can use the $accent-color variable which is defined by the user:

.element {
    background: $accent-color;
    color: if( lightness( $accent-color ) > 50, 'black', 'white' );
    &:hover {
        background: darken( $accent-color, 5% );
    }
}

Where you get the rest of the Sass code is entirely up to you. You can store it as a string in a PHP file, you can query the file system for the actual Sass file (note that Theme Check won’t let you use file_get_contents()) or you can even wp_remote_get() it, perhaps as a fallback if nothing else works.

Sass and LESS compilation can take a while, especially when you start using math functions like pow() or nthroot() (you’ll need these for luminance), so make sure you’re not compiling your stylesheets on the fly on every single request.

Instead, you can grab a hash of the color choices, and perhaps the stylesheet version, and cache the compiled CSS forever in a theme mod, and if the colors are changed, you’ll simply overwrite the cached entry.

Example

Semicolon is a magazine theme I released earlier this year. It was built with Sass already, so I simply extracted all the color definitions from the main stylesheet into a new colors.scss file, and then used some basic regex to inject user color values and recompile the stylesheet with Jetpack.

I also added automatic contrast correction which is on by default. So if the user picks bad contrasting colors, Semicolon will lighten or darken them until a contrast ratio threshold is reached. This guarantees a certain level of readability, even if it means drastically changing the user colors, like yellow to almost brown.

So this:

semicolon-color-options

Becomes this:

semicolon-contrasted

Obviously this is purely experimental for now, and there are probably some edge cases where users would want to turn Auto Contrast off. For example, in Semicolon you can’t set that sidebar widget fill color to the same color you’ve chosen for your page background. In fact, here’s what happens when you set all three values to white:

semicolon-white

Which I don’t think is bad, but it will certainly surprise many users. I guess a little tooltip message about why they’re not seeing the colors they’ve picked could help them understand what we did there.

You can grab the theme from WordPress.org or browse the theme code on GitHub. The Sass magic lives inside css/colors.scss and the compilation and caching code is in functions.php (custom_colors() method).

It’s not meant to be perfect, but I think it’s a good start. Give it a spin and let me know what you think. You’ll need Jetpack’s Custom CSS module active. If you’re working locally, you’ll want Jetpack’s development mode.

I appreciate your thoughts and comments!

1. There’s a neat plugin for the default Twenty Fourteen theme called Fourteen Colors, which also adjusts contrasts using PHP.

An Alternative to @import in WordPress Child Themes

Using Child Themes in WordPress is a great way to modify an existing theme, however the CSS @import directive is slower than it has to be, so you should try and avoid it. Here’s why.

If it takes 200ms to load the child theme’s stylesheet, and 200ms to load the parent theme’s CSS, a modern web browser should take approximately 200ms to load both of them, because modern browsers load assets in parallel.

Unfortunately this is not true for CSS @import. Let me quote Google:

The browser must download, parse, and execute first.css before it is able to discover that it needs to download second.css.

Which means that instead of 200ms, with @import it’ll take the web browser approximately 400ms to load both stylesheets. Here’s a typical child theme’s CSS:

/**
 * Theme Name: My Child Theme
 * Template: parent-theme
 */
@import url(../parent-theme/style.css);

/* My Child Theme CSS */

We can drop the @import statement, and make good use of functions.php and the wp_enqueue_style() function:

// Faster than @import
add_action( 'wp_enqueue_scripts', 'my_child_theme_scripts' );
function my_child_theme_scripts() {
    wp_enqueue_style( 'parent-theme-css', get_template_directory_uri() . '/style.css' );
}

And we don’t need to re-declare dependencies because the child theme’s functions.php is loaded before the parent theme’s. Unless, of course, the parent theme uses a different action priority, in which case we should just match it.

That’s +1 to our PageSpeed score :)

MegaFon Moscow: Privacy & Advertising

Funny thing happened today. My car insurance expired, so I called my insurance company (RESO) from my cellphone. Nobody answered my call, it was Friday evening after all, so I hung up and decided to call them on Monday.

A few hours later, I received a text-message:

megafon-moscow-advertising

For those of you who can’t read Russian, it’s an advert from INHELP, a different insurance company offering its services. The message came from PROMO — the official MegaFon advertising channel.

At first I thought it was a coincidence, so I asked my wife to dial the same number and moments later she gets the exact same text advert!

I wouldn’t consider this a big deal if I had registered on some website online and given them my phone number. I would actually expect them to sell the number to third-party advertisers, but this is different.

Here’s what I think: MegaFon Moscow, one of the three largest network operators in Russia, is not only selling my phone number to advertisers, but also the fact that a phone call was made to a certain number. At this point I wouldn’t be surprised if a recording of the phone call was also handed over.

Talk about privacy.

WordCamp Russia 2014

The second WordCamp in Russia was a success, with almost 200 attendees and a great lineup of 14 speakers from all over Russia and abroad, including Ukraine and even Germany.

WordCamp Russia 2014

I’m not going to go into much planning details like I did last year. Everything was mostly the same, with the exception of having almost twice as many speakers, two tracks, pizza for lunch, a new logo (which everybody thought was a splash), as well as little irritating things that made planning more stressful — like the absence of parking spots close to the venue, problems with shipping anything from the US to Russia, and the fact that we bought about 10x more coffee than we ended up serving.

In any case, the post-WordCamp survey showed a 96% satisfaction rate, which definitely works for me. Now back to reading those new 4.0 commits, and still struggling for inbox zero, even though it’s been over a week now.

Photos from WordCamp Russia 2014 are on Facebook. Slides from my talk about scaling WordPress can be found here, the videos from all the sessions should appear on WordPress.tv in a few weeks.

Stay Tuned for WordCamp Russia 2014

Last year we had a blast and this year we’re planning to have an even bigger one. WordCamp Russia 2014 will be held on August 9th in Moscow.

WordCamp Russia 2014

We have a line up of 14 speakers ready to deliver some WordPress awesomeness in two simultaneous tracks, at the popular Digital October conference center in Moscow.

Tickets are available at $20, which includes a full day of learning and networking, food, coffee breaks, after-party and of course swag. See you in Moscow!

Introducing Semicolon

Semicolon is a brand new magazine theme for WordPress. It’s simple, clean, and it’s got quite a unique grid layout with support for featured posts.

Semicolon WordPress Theme

Semicolon was initially created for WP Magazine, an online news site about WordPress in Russian. It’s got support for featured posts, a social profiles menu, related posts, author bios, and a few widget areas.

Head over to the demo to take a look around. The latest version is always available for download on WordPress.org (don’t forget to rate it!), and if you ever get stuck, please visit the the FAQ and the support forums.

Semicolon is based on the amazing _s starter theme, and is distributed for free under the GNU GPL. Enjoy!

Knock knock! Who’s there? … 1Password.

I’ve been using 1Password for almost a year now and I love it.

1Password Mini (that thing that lives in the OS X menu bar) is my favorite, especially combined with the Cmd+Alt+\ (or ⌘⌥\) shortcut key that opens the menu, focused on Search. Type a few letters, hit the right arrow, hit the down arrow, hit Enter and boom — you have your password in your clipboard for 90 seconds. Amazing!

However, a recent update to 1Password added a nice little animation to the item details screen that pops up in 1Password Mini. The animation lasts for less than a second, but during that fraction of a second you have to wait before you can hit the down arrow and select your password.

1Password Mini

So now it’s more like type, right arrow, wait a bit… down arrow and Enter. And if you didn’t wait enough, you’ll copy your username instead, and now you have to do it all over again. Argh!

I counted the number of times I copy passwords from 1Password Mini on a daily basis, that’s around 30! Rounding that extra delay up to one second means that this animation now costs me approximately three hours per year!

It’s the little things.

Update: Here’s what 1Password had to say on Twitter:

As I already mentioned in the comments, I’m not really worried about the browser — my copy/pasting almost always goes to the Terminal for things like SSH, Subversion, etc.

But it seems like #2 gives me my 3 hours/year back. Thank you 1Password, did I mention you rock? Well, you rock.