Loading Javascript and CSS mid-page, HTML5, WordPress & Passing Validation Part 1

Since WordPress version 3.3 it has been made a lot easier to load javascript and stylesheets mid-page.

Why would you want to do this in the first place?

Well a lot of plugins load their own CSS and Javascript files on the page and some of them do so at times when it’s not really necessary. As a plugin or theme developer if you are loading styles that only need to be loaded in certain cases (not on every single page), you want to avoid loading them when they are not needed.

If you’re not sure on which pages your scripts and styles will be needed, it presents a bit of a conundrum. This is a common problem for plugins that let a user add its functionality via a shortcode. Common examples are sliders, media players, galleries and forms.

The best way to load your scripts is to enqueue it with native functions WordPress provides. There are a number of advantages to this. For one, you can avoid scripts from being injected more than once, you can control where the script loads (in the head or in the footer) and it offers ways to deregister scripts and styles from loading altogether without resorting to hacks.

The problem with enqueueing used to be its inflexibility in relation to the load sequence of WordPress. Prior to WP 3.3 you had to enqueue your scripts and styles before the page content is constructed. While there were good methods for calling javascript mid-page and having it load in the footer, there were no palatable equivalents for loading CSS stylesheets. What you could do was:

1) Include the CSS on all pages
2) Rely on inline styles
3) Parse the page content for shortcodes before styles are enqueued and include your CSS with conditionals.
4) Use javascript to dynamically add your stylesheet to the head section
5) Set a postmeta field that is checked when a shortcode is added to a post and include a condition that loads your css if the postmeta field is present

Now it’s possible to enqueue scripts and styles mid-page through wp_enqueue_script() and wp_enqueue_style(), it will load your scripts and styles in the footer as a result.

By now you might be wondering, wait, can you have stylesheet links at the bottom of a page? Yes and no. Browsers are okay with this but validators are not. So while, in the wild it will work ok, your page isn’t going to validate.

But you’re theme is HTML5 you say? Good news, HTML5 is supposed to be fine with styles inside the body of the HTML…or is it? After some experimentation I found that my stylesheet reference in the footer was still bringing up validation errors for HTML5. The LINK element can’t be used for stylesheets in the BODY it seems…but you can use STYLE, in fact there is a new attribute on the horizon called “scoped” which will allow style declarations for certain sections of a page. It has virtually no browser support at present…but the code does validate according to HTML5 specs and the browser will recognize the style declarations itself. The trick then is to use the import statement to load your css file instead of using the LINK element, like so

But how do we do this?

We could still use wp_enqueue_style and modify our output with a custom function. WordPress will output a LINK element by default but you can adjust the output by hooking into the ‘style_loader_tag’ filter.

function print_html5_style( $output ) {
// some regex to find the url to the stylesheet
$url = preg_match(“/(href=’)(.+)(‘ type)/”, $output, $styleurl);
// the new output based on a HTML5 valid

return $output;
Because we only want to modify those CSS styles that are placed in the footer, we make our filter run conditionally.
function html5_style_filter (){
add_filter( ‘style_loader_tag’, ‘print_html5_style’, 10, 2 );
add_action( ‘wp_head’, ‘html5_style_filter’); // the wp_head hook runs after the header scripts are printed

And voilá now we can load our CSS mid-page by calling wp_enqueue_style and get validating markup for our HTML5 page.

There’s just one disadvantage…

Because the CSS is loaded later in the page, the HTML you are wanting to style may not show proper styling straightaway, it has to wait for the CSS to load. But since we’re allowed to in HTML5 we might as well load our CSS right before we render the rest of our shortcode output. So let’s say you have a slider somewhere on your page, the STYLE element can be placed just before your slider is printed. That resolves a lot of the styling issues a visitor might see during pageload, because your CSS is loading much earlier.

How do we do this? We can’t rely solely on wp_enqueue_style because it just prints styles in the header or footer. We’ll need another custom function and we also want to make sure we retain all the benefits of enqueuing a style with wp_enqueue_style. This is covered in part 2.

One comment

  1. Ryan says:

    Thank you! I’ve been struggling with this for hours. We are building a theme with several short codes and we didn’t want to load the .js or .css unless the short code was called. This resolves that issue nicely. Next up: turning this into a global function or class so that we don’t need to include it in every short code script.

    Thank you again for taking the time to post this. If you lived nearby I would buy you a beer.

Leave a Reply

Your email address will not be published. Required fields are marked *