How to design a good native-looking WordPress Admin icon

For my previous project, Popshop (which is, you guessed it, a WordPress theme), I wanted to produce a set of native-looking WordPress Admin icons. I like the WordPress admin panel a lot and I wanted my Theme to really blend in — I was also inspired by this post by designer Laura Kalbag. This post serves as a way of documenting what I did, and hopefully helps WordPress developers produce subtle icons that are consistent with WordPress’ native UI.

The End result, with Menu page selected (Left) and inactive (Right)

There are actually two different icons that you need to produce, at different sizes (see Figure below):

  • A Menu page icon, which is the icon that sits in the sidebar. You can easily set this icon from your Theme or Plugin, but be aware that it actually doesn’t work in the same way as the native icons with respect to their active/inactive behavior: native icons (i.e., Posts, Media, etc. up to Settings) have two sprited states, which is why they can be monochromatic or colored. Theme- or Plugin-defined custom icons, however, are applied a 0.6 CSS opacity when inactive (they are at 1.0 opacity otherwise).
  • A Screen icon, which usually appears on your Theme options or Plugin settings page.

Let’s start by resizing our full-size logo to a width of 32px, using Photoshop. I found that Photoshop’s bicubic downsampling algorithm works best, but in any case, the result won’t look too good:

Yes, it’s very blurry… The next step is to remove the excessive details, that look good at full-size but make no sense at 32×32. The “Pop” Flash on the Window is one of those details.

Then, you can slightly resize and move some elements of the object to make it more legible at small sizes.

A really useful thing to do to help you design an icon is to paste the native WordPress icons in the document you’re working on (here, the 16x16px Menu page icons). I find it really helps the style to blend in.

The next step is to repaint the blurry pixels, so that lines are not blurry or antialiased anymore. This sounds a lot more tedious than it really is, actually.

The one thing to be looking for here, is that, as hinted in the intro to this post, your custom menu page icon has to work on both a dark (when active) and a light (when inactive or on hover) background.

This means it’s a good idea to use a strong dark outline, and semi-transparent pixels (instead of hard-coded grey pixels). On the Figure above, see for example the difference between the first Popshop icon on the left, and the one on the right (which is the final one).

This is why it is really important to test your design on a dark background :

Another feature you might want to add to your icon to make it more WordPress-friendly is the grey drop-shadow below the icons. Again, don’t use hard-coded gray, use semi-transparent black pixels instead (to make sure they look equally good on light and dark backgrounds).

The Screen icon is larger (up to 34x37px), so you can add a few more details back into it (in my case, the door knob). Also, the surfaces are much larger now, so it’s a good idea to use very subtle color gradients on areas ; for example in the coloured icon in the image above, the wall is slightly gradiented, as are the red stripes.

The grey version of the icon above also seemed a bit too dark, so I had to tweak a little more to give it a more subtle, kind of “washed-out” look that’s consistent with WordPress’ native UI.

Voilà ! This is basically how I designed and produced my WordPress icons. You can find a working document I used here:

As I said, I couldn’t use the monochromatic version of the Menu page icon (the small one), but it ended up making for a pretty cool favicon 🙂

Extending Options Framework for WordPress

I’m currently building a WordPress Theme that is very versatile and has a fairly high number of Theme options (although I’m trying to abstract many of them from the end-user to keep things simple).

I was very surprised to see that WordPress itself doesn’t include a way to easily create your own Settings panels, in the same way that for example it includes a class/library for creating admin list tables (like the ones for Posts or Links, for example) that you can extend to build your own list tables without having to write any markup.

An example of an Admin List table, built on top of WordPress' native features.

There are however a couple of external libraries that you can use to abstract the creation of Options panels: the two most mature ones (at first glance) are Options Framework from Devin Price, and the UpThemes Framework from Themes developer UpThemes. Both look good, are well-coded, and have a decent following and activity on Github.

I chose to go for Options Framework because it is a little more “barebones”, its development is very iterative and ongoing, and most of all developer Devin seems to be really helpful and responsive to both Github pull requests and comments on his website.

There are actually two versions of Options Framework: a Plugin version, and a “Theme” version that you can actually use as a library. I am mostly interested in the Theme version because I want my theme to be self-contained and to be able to provide extra flexibility.

Which brings us to the core of this post: how to actually extend Options Framework to make it more customizable and be able to add more functionality?

First, Options Framework is already reasonably extendable in the sense that it uses filters (notably, for data sanitization) and WordPress-type pluggable functions (i.e., functions definitions are enclosed in if ( ! function_exists( 'optionsframework_mlu_init' ) ) { } branchings).

However, for a few of my needs, I had to hack into Options Framework and add extensibility “hooks”. This post serves as a reference as to how I implemented these hooks.

First, I want to have my Theme Options WordPress submenu inside my Theme’s menu in the Admin panel sidebar, not under Appearance. This is actually documented by Devin (see Figure below), but still requires hacking the code directly, as there are several places where the appearance menu hook ('appearance_page_options-framework') is hardcoded. The way I propose to add extensibility on this point is through the use of a constant named OPTIONS_FRAMEWORK_ADMIN_PAGE (Options Framework already uses constants like OPTIONS_FRAMEWORK_URL and OPTIONS_FRAMEWORK_DIRECTORY).

Then, there are things that I wanted to configure in the Frontend behavior of Options Framework, that were hardcoded in the JS file. I think it makes sense to be able to configure or extend the JS behavior from outside Options Framework. For example, I don’t like the fading effect on Options tabs, so I added a fadeDuration setting (that you can set to 0 from outside the library), but kept its default value of 400 inside Options Framework.

To do this elegantly, I actually used the jQuery extend function, which is what jQuery plugins use to define defaults and options. In turn, I am able to configure the JS values from outside Options Framework, with code like the following:

add_action('optionsframework_custom_scripts', 'optionsframework_custom_scripts');

function optionsframework_custom_scripts() { 
    
    // The following is my attempt at adding some (more) parametrability to Options Framework's JS.
    
    $of_options = array('fadeDuration' => 0,
                        'navTabSelector' => '.nav-popshop-settings a');
    
    echo sprintf('<script type="text/javascript">/* <![CDATA[ */ var Of_options = %s; /* ]]> */</script>', json_encode($of_options));
    
}

In my theme, I also want to keep a toplevel set of tabs (“Dashboard”, “Orders”, “Settings”) on the Settings page, so I need to be able to specify to the Javascript file that the set of tabs generated by Options Framework is hooked on a different CSS selector. I also style the set of tabs a little differently (from outside the library as well):

My Theme also have a “Getting Started” page that is integrated with the Options Framework page. This “subpage” interacts with the options page (for example, it has a different styling), and I needed to know when tabs were clicked. I did this by triggering custom jQuery events (named of-tab-active) from Options Framework. That way, I can hook on this event like this:

// Hook into Options Framework's custom tab selection event, in order to style specific options groups differently.
$(".nav-popshop-settings a.nav-tab").bind('of-tab-active', function(){
    $('#optionsframework').removeClass().addClass('postbox').addClass($(this).attr('id'));
});

My differently styled Options "Getting Started" page

Another thing I did (but which didn’t require any change to Options Framework) was to duplicate the “Save Options” button in Javascript, and place it on top of each subpage. When the button is only at the bottom of the page, I’ve found that it’s easy to miss it and forget to save changes (in particular as more and more apps save settings “transparently”). This is pretty hackish, but this is how I did it:

// Copy "Save Options" submit buttons at the top of pages (Settings page)
var submit_button = '<input class="button-primary top-button" type="submit" value="' + $("#optionsframework-submit input[name='update']").attr('value') + '" name="update">';
// Sadly there is no jQuery outerHTML function so we have to reconstruct the markup ourselves...
// We also add a custom class ("top-button").
$("#optionsframework h3").append(submit_button);
// We append into h3 tags, although this is not semantically ideal.

Another thing that I thought about (though I ended up not needing it at this point) was the ability to extend the types of interface elements used in Options Frameworks (text, textarea, select, etc.) and defined in optionframework_fields(), so that plugins would be able to define their own interface elements (sliders, etc.) without having to hack into Options Framework.

This is basically what I did to extend Options Framework. All in all, this is a great library! And it has helped me develop my Theme considerably. My Pull request can be found on Github.