Stop Including Custom CSS in WordPress

One of the things that I think many, many young (that is: inexperienced) theme developers do is ship a custom.css file in WordPress. Years ago, I made the mistake so I’m just as guilty as the next person.

Unfortunately, this is something that’s still happening today – we need to stop including custom CSS in WordPress and use the native facilities to take advantage of the same functionality we’re trying to achieve with this particular file.

Here’s the thing: Normally I wouldn’t bother talking about something like this because the Codex does such a good job of outlining the proper way to introduce customizations into themes, but I recently received a comment (that I’ll paraphrase) in which I was told that:

In the real world not everyone uses child themes.

Odds are, many of us have heard the old cliché that:

The difference between theory and practice is that in theory there is no difference.

And when you’re talking about something like a complex algorithm for traversing, say, the shortest path across a graph over a large network, or when we’re talking about something like properly handling memory in embedded systems, talking about theory and the real world makes sense.

That is, all of those cases are important and are worthy of optimization, but we’re talking about a single CSS file.

We’re not talking about a complex system.

And it concerns me that those who are contributing to the WordPress economy through products aren’t taking the built-in features of the application seriously. It’s seen as some bit of impracticality that they don’t want to pursue.

But this introduces it’s own set of challenges that negatively affect theme development from both a developer and a customer standpoint.

The Problems With Custom CSS in WordPress

Anyone who has dealt with a custom stylesheet in a WordPress theme before either as a developer or as a customer knows the frustration that it causes.

First, upgrades can break the changes. If, for example, the developers ship an empty custom.css file and don’t change the name of the theme’s directory to include, say, the most recent version number (think mayer-1-0-0 and mayer-1-1-0), then it will overwrite the existing theme files including the custom.css file that was part of the original theme.

Next, let’s say that the developers include a routine to check for the existence of a custom.css file and only write it out if the file doesn’t exist. Again, sounds good in theory, but what if the markup has changed in any of the template files.

Will the changes in custom.css still work? It’s hard to tell until you install the new theme and then load every single template that exists on the site. If something is borked, does the custom have the ability to change the styles on their own or are they going to need to contact support?

This raises the question as to if customizations should even be a major support issue. I think it warrants its own discussion, for sure, but this isn’t the post for that.

Anyway, let’s say that the developers do ship a version of the theme that includes a different directory names (again, think mayer-1-0-0 to mayer-1-1-0), then the custom.css file is completely ignored when the theme update is activated because it’s essentially a different theme.

Thus, the problem still persists.

Now, to give a quick run down, I know that some of the points I’ve mentioned above aren’t handled well by child themes, either.

For example…

  • Creating a new directory for an updated theme version still requires that that the child theme properly reference the new theme.
  • If the markup changes in the new theme, then the customized child theme still needs to be updated in order to handle the newly changed markup.

This, of course, hits on the importance of user-friendly changelogs which, again, is the topic for another post.

Even still, despite these two points, we need to stop including custom CSS in WordPress and start pushing more towards the child theme implementation of customizations not only because it ultimately does ease the pain of upgrades, but it helps to further treat the theme more as a black box than something that can be hacked to pieces to fit the customer’s needs.

Wait, What? a Black Box in Open Source?

A Word About Our Freedoms

First, don’t get me wrong, I understand that one of the biggest benefits of of open source is the ability to learn from other people’s code. The WordPress Bill of Rights even grants (which is based on the GPL):

The freedom to study how the program works, and change it to make it do what you wish.

However, that doesn’t necessarily mean that the version of the code that we distribute has to include all of the raw development files.

Open Source Developers

Just, you know, hacking core.

For example, if I’m distributing a theme that includes a number of JavaScript files and stylesheets that make up a frontend framework, then I face a dilemma:

  • Include all of the files separately, enqueue the files one-by-one negatively impacting the load time of the theme at the expense of keeping all of the code easily readable,
  • Or minify, compress, and/or combine all of the files in order to help decrease the size of the theme, increase the load time and performance of the theme, but make it more difficult for others to study.

There is a third option, though: Leave the code completely open source on one of the popular repository sites from which others may learn, but distribute only the version of the code that’s smallest in file size, highest in performance.

Meanwhile, Back at the Main Point

Okay, so I still haven’t answered the whole idea of a “black box in open source” thing. The short of it is this:

I believe that the majority of people who are buying WordPress themes are those who want to have a great experience in setting up their site or their blog, and have access to high-quality support.

I don’t believe that they want to be able to access to code, read it, change it, and so on. Sure, that’s a luxury that comes with open source software, but it’s not the primary motivation for someone purchasing a theme.

They’re looking for a product to help them solve a problem or to help them with their online brand, for lack of a better term.

And yes, customization is something that’s possible with WordPress, and yes, despite how I might sound in this article, I’m all for people making adjustments to products that they purchase. It’s built into the foundation on which the products are built, so why would I be against it?

Simply put, I’m against hacking the core theme in order to make the changes because more often than not, something is going to change or break and then they’ll have to ask for support and now they’re asking for support on a product that was not shipped to them.

All About Maximum Customization

This isn’t some theoretical idea as to how themes work, either. I’m speaking from experience.

We’ve already covered most of the challenges that come when a user updates their theme, and this is no different of a situation.

After all of that’s said, child themes certainly can help to mitigate the problems that come with this, and though they aren’t without a few of their own challenges, they help keep the changes abstracted away from the core product which can make it much easier to port the changes to an update, to track changes via support, and to continue introducing your own changes.

Ultimately, I’m completely for giving users the ability to introduce customizations into their theme, but I want them to have as pleasant as experience doing it as they can have with using the theme itself.

This means that customizations to templates, styles, and so on need to be kept out of the core theme. Leverage features that are already offered by WordPress, make sure that themes are child-theme compatible, perhaps often with some instructions – or education – on how users can get started with creating child-themes, and make the changes there.

Though WordPress itself is open source, it’s never a good idea to try to touch core files in order to achieve our customizations. We do so via plugins. The same goes for themes: Don’t make the changes by touching core files, do so via child themes.

It’s easier, it’s safer, it’s something that is done in the real world, and it’s something that can help foster the development of even greater core products.

24 Comments

We have packaged Child themes with our themes and while it does lead to a bit more education up front, I find it really exciting to come across a customer who has been able to use the child theme to make their site really unique. When customers bridge that gap and start making their own little tweaks within the safe confines of the child theme, I start thinking of the child theme as one of the most enabling aspects of the products that we sell.

Thinking in terms of child themes has also led me to write clearer parent themes that are easier to override, and in that way I feel like it’s something that improves my work as a developer. Writing code with a child theme in mind forces you to think about how others – including people who have no programming experience – will read the code. If they can read the code and understand it enough to override it with their child theme, I’ve done my job well.

Cheers,
Eric

    We have packaged Child themes with our themes

    How has this worked out historically? That is, when they install the theme, is the child theme installed automatically?

    I’ve created child theme skeletons in the past and given customers access to them, but I’ve not really bothered doing that with Mayer. At least not yet. Demand for it is slowly, slowly increasing so I’m sure it’ll be part of the deal at some point.

    When customers bridge that gap and start making their own little tweaks within the safe confines of the child theme, I start thinking of the child theme as one of the most enabling aspects of the products that we sell.

    Absolutely. Love reading this.

    Thinking in terms of child themes has also led me to write clearer parent themes that are easier to override, and in that way I feel like it’s something that improves my work as a developer.

    100% agree. I think this is one of the more understated aspects of WordPress Theme Development in terms of what qualifies a person as a good WordPress Theme Developer.

    Knowing how to account for this is key especially if you want to introduce longevity into your product.

      How has this worked out historically? That is, when they install the theme, is the child theme installed automatically?

      The child theme is included as a separate folder + zip file, so the advice we give is that the user upload both the parent & child themes and then just activate the latter.

      The one thing that can be a hassle is that theme customisations don’t carry over from the parent to the child since they’re registered against the active theme’s slug. But I’m looking at writing a simple script for migrating between parent and child that preserves any settings entered.

First up I am more of a back end person than a front end person so my css knowledge is thin. I have however plenty of experience with code libraries and with CMS systems over the years and the underlying issue of a quick hack vs a considered this is how to do it more safely is very very common.

From reading other posts on your blog I am pretty sure that you have come up against the MVC evangelists that would have you believe that the only true path to web based development happiness is MVC. I am also pretty sure that you don’t believe them, I sure don’t.

I have just finished working at a company where there was a small development team the senior developer of which was such an MVC believer. Unfortunately the code that they produced was unbelievably awful. There were work arounds everywhere, quite frankly it was a mess and I am very glad not to be associated with it anymore.

The point I am trying to make is that you are totally correct in your post and that it is right to push for better standards. Just don’t get conned into thinking that other systems/platforms fare any better…

    From reading other posts on your blog I am pretty sure that you have come up against the MVC evangelists that would have you believe that the only true path to web based development happiness is MVC. I am also pretty sure that you don’t believe them, I sure don’t.

    Yes, I’ve come up against them. I’d say when I was much younger in my career, I flirted with being one of those evagenlists.

    The short story, for me, is this:

    • I love the MVC pattern, I don’t hate other patterns
    • I don’t think MVC is the one true way for web applications
    • I’ll use it when necessary, but don’t mind not using it at other times :)

    Unfortunately the code that they produced was unbelievably awful.

    No matter how pristine a pattern appears, imperfect people can always generate imperfect solutions. In fact, I think some programmers strive for the path of least resistance is it relates to writing code.

    Maybe I’ll write about that in a future post.

    The point I am trying to make is that you are totally correct in your post and that it is right to push for better standards. Just don’t get conned into thinking that other systems/platforms fare any better…

    LOL, thank you very much. And don’t worry – I’ve been around enough other languages, libraries, frameworks, and forums to when to watch for cons, trolls, and valuable discussion ;)

I’ve always thought that either:

1) Child themes should ship with themes
2) There should be a built in WordPress function for creating a child theme in one click.

The average person that knows a little CSS and wants to customise their theme are likely daunted by the instructions on how to create a child theme – editing either the default css file or a custom css file is the easy way out.

    If you use Jetpack, there’s a custom CSS option that is pretty good, and is one-click. That’s a way to avoid touching the css file or having to create a child theme, or a custom.css file. Of course, if the user refuses to run Jetpack for some reason, that’s out.

    But, many theme authors include child theme templates. The authors may not advertise the fact, but if you look around the theme files and directories, often you’ll find them. It’s not as though creating one is hard for an author, and it definitely is valuable to someone like you describe. (And then, even if not, if you contact the theme author, I’ll bet they would even throw one together for you if really needed.)

      That’s a way to avoid touching the css file or having to create a child theme, or a custom.css file. Of course, if the user refuses to run Jetpack for some reason, that’s out.

      Nailed it.

      I’m a fan of this feature as long as people are running Jetpack, but I wouldn’t recommend people install that plugin just for this feature.

      (And then, even if not, if you contact the theme author, I’ll bet they would even throw one together for you if really needed.)

      Agreed. More often than not, I’ve seen this happen.

    1) Child themes should ship with themes

    Yes and no – I think that child themes should be available for those who purchase themes (at least, if the theme developer so desires); however, I’m not sold on if they should be part of the theme or a separate download.

    The average person that knows a little CSS and wants to customise their theme are likely daunted by the instructions on how to create a child theme – editing either the default css file or a custom css file is the easy way out.

    Couldn’t agree more. This is partially part of the core problem, too.

I couldn’t agree with you more Tom. I’ve been teaching to the child theme concept for years to the meetups in Arizona. I’ve given the “how to build a child theme” presentation at least 3 times now.
Its also why I’ve invested a large part of my time into theme frameworks. I have 2 themes on Github (Whitelabel Framework & Div Framework) that I currently work with developing but I’d love to hear from you about theme frameworks in general. Oh, and thanks for writing so often. I find myself coming back to your blog every time you write as a refreshing way to make sure I’m doing everything “the WordPress way”.

    I’ve been teaching to the child theme concept for years to the meetups in Arizona.

    Awesome. Love hearing that.

    FWIW, I think there’s something to be said for giving a single presentation on a single topic and really getting great at presenting it. You also kind of become a local expert in that area, which can help generate business (if you’re self-employed, of course :).

    I have 2 themes on Github (Whitelabel Framework & Div Framework) that I currently work with developing but I’d love to hear from you about theme frameworks in general.

    I’ll consider writing about theme frameworks. I know I’ve been talking to Nick Worth about his framework (I’m assuming you two are collaborating on Div Framework) so ask him to share my email with you a little bit :).

    Oh, and thanks for writing so often. I find myself coming back to your blog every time you write as a refreshing way to make sure I’m doing everything “the WordPress way”.

    I appreciate that, but know that I’m learning just as much as the rest of you guys. That means I may change my opinion in the future on something I’ve written about today.

    When that happens, I always try to link back to the older post to show how I used to do something, and how I do it now.

Good read. I use child themes like all the time. Even if I’m screwed with some **it such as a bad premium theme (I know there are good ones). It’s not so rare to see multiple updates with these themes.

You said “if the markup change” then child theme must be updated. But to me this case is a huge fail. There are proper ways to prepare a theme for child themes, some techniques that every single theme maker should use. And to me a good theme, I mean well prepared for child themes, requires just a few changes and most of the time with class extends and/or some overriding.

One of the thing that keeps me away from premium themes is the following : developers do not include some if( !function_exists(”) ) before their callbacks in functions.php so they do not seem to know that the child functions.php is loaded before its parent.

They also put all the functionnalities in functions.php => nobody can work with that ! But that might be off topic here ^^

What about offering an option the way that Automattic does with, Jetpack Custom CSS?

I wonder if this goes to the recent articles about implementers versus developers.

Seems to me that themes that offer a lot of theme options are geared towards the click-and-configure idea. These themes assume little actual extra-theme configuration. That is, they don’t want users to make any changes.

There’s a market, a big market for that.

One theme to rule them all, Frodo?

    Seems to me that themes that offer a lot of theme options are geared towards the click-and-configure idea. These themes assume little actual extra-theme configuration. That is, they don’t want users to make any changes.

    That’s true – and I typically am of that mindset. I don’t like and I try not to support themes that offer tons of customization options within the dashboard (I’ve covered why in a previous series).

    This isn’t to say they don’t have their place with a certain type of customer, but I’d rather see lean, focused themes that have a very tailored, specific look rather than a huge set of options.

    There’s a market, a big market for that.

    And those themes definitely exist.

    One theme to rule them all, Frodo?

    They through that ring into the fire and I agree with that choice :).

I’ve been including child themes in client projects for a few years and I agree wholeheartedly that it’s the right way to go.

One other alternative I had read recently that I was really intrigued by is, instead of using child themes, adding custom CSS and functions via a plugin rather than a theme, so customizations persist beyond theme changes.

What do you think of that approach?

    This goes against “the WordPress way” as you are greatly blurring the line between the Appearance Layer (theme) and the Business Function layer (plugin). Its not to say that it doesn’t work, or that its somehow functionally flawed, but I think it my introduce confusion to the general standards of where things should be on your WordPress install.

      “This goes against “the WordPress way” as you are greatly blurring the line between the Appearance Layer (theme) and the Business Function layer (plugin).”

      Hugely popular plugins (actually applications in their own right) like Woocommerce HAVE to include their own CSS or they wouldn’t be usable by most customers. It’s an absolute good that you can install WC and the product listings, cart and checkout screens are all styled out of the box by the plugin’s CSS. You can certainly easily override it as you can with the WC templates.

      But further, and more to the point of this thread, many themes are written specifically with WC support built in. They use WC’s hook and filter system along with the theme options to re-style and re-template the plugin. But if WC didn’t ship with its own CSS and templates most people wouldn’t bother with it, I’m sure.

        Yes, but you switched subjects. @Skip references “plugin instead of child theme” not “custom post types with default CSS deployed”. I’m simply talking about the concept of moving the presentation layer of the child theme into a plugin… which I don’t believe is a good practice.

I find some premium themes I have purchased come with a default.custom.css so if you want to make any changes you rename the file to custom.css and if there are any updates to the theme this does not affect the custom.css file as the theme is shipped with the default version. But really I should be using child themes I suppose

Leave a Reply

Name and email address are required. Your email address will not be published.

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>