Category: Coding And Design

Loading CSS mid-page, HTML5, WordPress & Passing Validation Part 2

With HTML5 it’s possible to declare CSS stylesheet inside the body tag. This gives WordPress developers a better solution for including CSS on the fly, such as via a shortcode. It instantly makes several workarounds redundant. The native WordPress function wp_enqueue_style can now be called mid-page, which will print a stylesheet in the footer. Two disadvantages arise from this method and here is an alternative solution that solves it.

In part 1 we learned that

<link>

elements inside the body tag don’t validate at the moment. While browsers handle them just fine, it’s always nice to pass validation without errors. An alternative to this was to alter the output and use the style tag with the new scoped attribute instead. Then, the code will show up valid like:

<style scoped>@import url(stylesheet.css); </style>

The second disadvantage is that our CSS now loads at the end of the page, after the content we want to style. This may cause some styling issues during pageload. Since we can load the CSS anywhere inside the body tag, there is no real reason why it needs to be printed in the footer. If we do that, we also limit the styling issues on pageload.

We can write a function that prints the stylesheet declaration immediately. Let’s say you have a shortcode that inserts a slider, your shortcode would include a special function that prints the CSS before the rest of the slider output. The easy way would be simply to write a function that outputs the required html directly and this is what many developers tend to do. WordPress has specific ways of dealing with styles and scripts to help reduce conflicts and redundancies, so it is important we take advantage of that. So what we are going to do is tap into the API WordPress uses.

The first step is to register your CSS stylesheet with wp_register_style by wrapping it into a function and loading it into the wp_enqueue_scripts hook. Here is an example where we are including the Media Element Player.
<pre>
function register_mediaelementjs() {
wp_register_script( ‘mediaelementjs’, get_bloginfo(‘template_url’).’/inc/mediaelementjs/mediaelement-and-player.js’, array(‘jquery’), ‘2.6.3’, true );
wp_register_style( ‘mediaelementjs’, get_bloginfo(‘template_url’).’/inc/mediaelementjs/mediaelementplayer.css’ );
}
add_action( ‘wp_enqueue_scripts’ , ‘register_mediaelementjs’ );

Next we want to make a function that runs through the styles API. In other words, we want to check if our style has been registered (this is important because a user might decide to deregister your style) and hasn’t been printed already. We also have to make sure that WP knows we printed the style to avoid duplication.

function print_inline_stylesheet( $handle ) {
	// continue only if the style has been registered and hasn't been printed yet. 
	if ( wp_style_is( $handle, 'registered') && ! wp_style_is( $handle, 'done' ) ) {
		// gain access the wp_styles object 
		global $wp_styles;
		// make sure the style is formatted with html 5 markup
		add_filter( 'style_loader_tag', 'html5_inline_stylesheet', 10, 2 );
		$print = $wp_styles->do_item( $handle );
		// set this style to 'done' status
		$wp_styles->done[] = $handle;
		// remove from to do just in case the style was invoked elsewhere for the footer.
		$to_do = $wp_styles ->to_do;
		if ( is_array( $to_do ) ) {
			foreach( $to_do as $key => $to_do_handle ) {
				if( $to_do_handle == $handle ) {
					unset( $wp_styles->to_do[$key] );
				}
			}
		}
	}	
}

If you are outputting functionality via a shortcode you will want to call print_inline_stylesheet before your output. The handle argument needs to be passed to it and coincide with the handle you passed to register_style for your stylesheet. All that is left here is our function for modifying the standard WordPress output.

function html5_inline_stylesheet( $output ) {
	$url = preg_match("/(href=')(.+)(' type)/", $output, $styleurl);
	$output = '<style scoped>@import url('.$styleurl[2].');</style>';
	return $output;
}

Notes:
– I haven’t tested this with CSS stylesheet dependencies – the code may need some alterations for that.
– If you are including the functions in your project, remember to add a prefix unique to your theme or plugin in front of all the functions.
– I haven’t tested this is in all browsers, but from what I’ve researched this should work universally.
– HTML5 is still in a working draft, the scoped attribute hasn’t been set in stone – it’s possible things may change.
– To validate, you need to make sure the validator is set to HTML5.

If you have thoughts on improving this solution or the code, please leave some feedback below!

UPDATE 5/05/2013
For copy pasters, in the above example I used Media Element JS which is now shipped by default with WP 3.6+. While the example was for demonstration purposes, if you are using media element js, don’t enqueue your own version, load the one that ships with WP.

Using CSS3 PIE with WordPress Plugins and Themes

UPDATE: I have posted an updated method for the latest version of PIE (v2)

CSS3 PIE is a fantastic tool to achieve support for CSS3 styles in versions of Internet Explorer, such as IE& and IE8. If you have been trying to include PIE with your WordPress project you might have had some problems with the way PIE is loaded. Below is an effective solution that works for plugins and themes without having to move “PIE.htc” into the root directory of a site and also without needing to dynamically insert the path to PIE using php in your CSS.

In our css, instead of using

[css]

behavior: url(PIE.htc);

[/css]

we use:

[css]

behavior: url(/?pie=true);

[/css]

If your website is located at http://yourwebsite.com/, the browser will look for the PIE file here http://yourwebsite.com/?pie=true, no matter what page you are on. What we need to do is make sure it retrieves the file based on that url. To do that we are going to add a Query variable for PIE and include a template redirect that checks to see if PIE is being called.

[php]

function css_pie ( $vars ) {

$vars[] = ‘pie’;

return $vars;

}

add_filter( ‘query_vars’ , ‘css_pie’); //WordPress will now interpret the PIE variable in the url

function load_pie() {

if ( get_query_var( ‘pie’ ) == “true” ) {

header( ‘Content-type: text/x-component’ );

wp_redirect( get_bloginfo(‘template_url’).’/inc/PIE.htc’ ); // adjust the url to where PIE.htc is located, in this example we are fetching in the themes includes directory

// Stop WordPress entirely since we just want PIE.htc

exit;

}

}

add_action( ‘template_redirect’, ‘load_pie’ );

[/php]

All you have to do is add the above functions in your functions.php or in your plugin file and adjust the path accordingly. If you are running into rendering issues in IE check with the other known issues documented on the CSS3 PIE site.

Updated 8 March 2012:

Changed example to use wp_redirect instead of an include statement.

How to truncate your WordPress RSS Feed at the More Tag

The More tag is a marker you can place in your WordPress posts that breaks up the post into two sections. It’s used to manually determine where the ‘read more’ link is placed when presenting a teaser of a post. WordPress doesn’t respect the More tag in RSS feeds by default, so if your rss feed is set to full or summary, it won’t break your posts as specified by the More tag. I have tried plugins that remedy this, but they fell short so I created my own function.
Read more

How To Query Multiple Custom Post Types with query_posts [WordPress Tip]

A very common WordPress function to modify the posts that are fetched on a page is called query_posts(). There are two ways to pass parameters to query_posts; you can pass an array or you can use the concatenated version. To display multiple post types on a page, the easiest way to do that is to pass parameters as an array argument to query_posts, like so:

$args = aray(
'post_type' => array ( 'post', 'page','event')
);
query_posts($args);

In some case you may want to use the concatenated version instead, for example because you are fetching posts using Ajax and are using GET variables. This is pretty straightforward if you are querying a single post type:

query_posts('post_type=event');

The question is, how do you query multiple post types? Looking at the WordPress codex, it doesn’t quite tell you how this works for post types. You could try similar examples for querying multiple category ids or tags, like this:

// like multiple category ids: doesn't work
query_posts('post_type=post,page,event');
// like multiple tags: also doesn't work
query_posts('post_type=post+page+event');

But you’ll quickly find neither of these examples work. I was about to give up and just use a serialized array for my use case, when I tried another simpler method for passing an array via a GET string:

query_posts('post_type[]=post&post_type[]=page&post_type[]=event');

Lo and behold, it works! In hindsight, this is a common way of passing arrays via a GET string, it just didn’t occur to me as an option because it wasn’t in the Codex.

If you have multiple post types on your WordPress site you can try it quickly by entering this as the url: ‘http://yoursite.com/?post_type[]=post&post_type[]=page’.

CSS Transition Problems with Display, Height 100% And Workarounds

CSS transitions are an exciting development in the world of web development, but it’s still a work in progress. I wanted to have a content block appear and hide on a hover event with pure CSS and a nice animation. My first thought was to animate the display property from display: hidden to display: block, but you can’t set a transition on the display property. In fact, if between the begin and end state there is a change in the display property, no transitions will work at all.

Looking for the next best thing, I decided to set a transition on the height property. Unfortunately that didn’t work as intuitively as it sounds either. If you have a content block with a variable height, you’ll want to use height 100% for the expanded state, but currently the CSS3 transitions don’t work with auto / height 100%, only with a fixed height.

Work Around

I needed my variable content blocks to fully display, so setting a fixed height was out of the question. A workaround to this is to set a transition on max-height instead and set the height to 100%. You need to set the max-height for both states (both need to be fixed) and on the expanded state you also set height: 100%. Now we have a working transition, as shown here: Demo

Quirk #2

I was happy to find the workaround, but in my case the transition still wasn’t working. I was driving myself nuts. The transition was expanding nicely, but not collapsing properly back to the begin state. The cause? I had set the height property on the collapsed state and this was causing the transitions to hiccup (at least in Chrome). Removing the height property on the first state solved the matter. See what makes the difference in another live example: Demo Comparison

Another limitation

The max-height trick works but it’s not always convenient. You will have a problem if your content is larger than the maximum height that has been set. If you set a very large max-height to prevent this, it messes with the transition timing and the transition behaves less reliable – it gets worse the larger the difference between the actual height and the max-height.

Showing and Hiding Content By Clicking A Menu Link (jQuery Tutorial)

While working on the user interface of the WordPress Plugin I’m building, I needed to have something akin to a drop down menu. A user clicks on a menu item, and a related list appears elsewhere on the page (in my case it’s a tool menu). To achieve this functionality I first looked at existing jQuery scripts and plugins and considered Superfish, which I was already using for the tab navigation. Using multiple instances of Superfish on the same page didn’t look as straightforward as it should be so I looked to build my own jQuery script, how hard could it be?

On my first attempt I worked with my limited jQuery knowledge and wrote a lot of code. It worked, it was logical but I knew I wasn’t being efficient. One of the most common mistakes for beginners to jQuery is to assign click handlers more generously than needed. My first attempt resulted in a lot of redundant code – I had assigned click handlers to every link in the menu.

Later I revisited my first attempt (which did work) and went about refactoring the code to get something more efficient. My secondary goal was to lose the need for Superfish on my other tab nagivation as well. My first step was to apply event delegation properly. Instead of assigning click handlers to each link in the menu, I assign a handler to the menu. There are a couple of functions to achieve that in jQuery, such as click(), bind(), live(), delegate() and on(). They all have their own merits and optimal use cases. On() seemed the most attractive to me for my interface, but since it has only recently been introduced in jQuery 1.7 I’m using delegate() in my plugin since the current WordPress ships with an older version*. I’ll show how it works for both, since the difference is minimal.
* WordPress 3.3 will come with jQuery 1.7

with delegate():
[javascript]
$(“#divtoggle”).delegate(“a”,”click”, function(e) {
// do stuff
});
[/javascript]
with on():
[javascript]
$(“#divtoggle”).on(“click”, “a”, function(e) {
// do stuff
});
[/javascript]

#divtoggle is the id assigned to the menu containing the links. In my case, the menu with the links are separate from the content I want to show on a mouse click. I have the content in a separate div lower on the page, hence giving the menu the id of divtoggle. As a sidenote, you might be wondering why I´m using ID attributes. On my first attempt, I gave my elements classes to make it easy to target them with CSS styling and jQuery. If you have an element you need to specifically identify with jQuery/Javascript, it´s more efficient to select it based on an ID compared to a class name. The ID attribute is meant to be a unique identifier, which means there will be only one element on the page with that specific ID. If you have to search through a document looking for an ID, you can stop as soon you found it, if you´re looking for an element with a certain class, you have to go through the entire document because there may be multiple elements with that class name.

Here is example HTML markup of the scenario.:

[html]

This is the content inside the first container

This is the content inside the second container

This is the content inside the third container

[/html]

The links also have unique ID’s as this will give me a way of linking the id to the container.
[html]show div 1[/html]

What we want to have happen is to recognize when a link inside the menu was clicked and then ascertain what link it was. We can grab the id of the link that was pressed and then use it to identify what container to show. We can use the prop() function to get the ID properity of the link.

[javascript]
$(“#divtoggle”).delegate(“a”,”click”, function(e) {
// get the ID of the clicked link
var toggled = ($(this).prop(“id”));
});
[/javascript]

Now we know what link has been clicked there are a number of ways to set the visibility of our div content. In this scenario, I wanted to have only one of the three containers displaying at the same time. On my first attempt, I was assigning a css class directly to the div containers that toggled their visibility. I found this a little laborious, as you have to assign and remove classes for each of the relevant div containers. On my second attempt, I decided to simply set a class for the parent container, which in the example is the div with the ID ‘wrap’. In the CSS, we can then set the visibility of the div containers based on the class of the parent container.

[css]
// hide menu related content by default
#div1, #div2, #div3 {
display:none;
}
// display content related to menu item
.togglediv1 #div1, .togglediv2 #div2, .togglediv3 #div3 {
display:block;
}
[/css]

Now in our jQuery, we assign a class to the parent div container based on the link that was pressed.

[javascript]
$(“#divtoggle”).delegate(“a”,”click”, function(e) {
// get the ID of the clicked link
var toggled = ($(this).prop(“id”));
// assign the value of the link id as a class to the parent container
$(“div#wrap”).prop(“class”, toggled);
});
[/javascript]

Basically this is what happens when you click the first link in the menu:

1) menu link was clicked
2) the link had the id ‘togglediv1’
3) the class of ‘togglediv1’ was set to the ‘div#wrap’ element, which automatically makes the appropriate div content display because of our CSS rules.

Check the DEMO on jsfiddle.net.