As @pieter-goosen and @birgire in other answer and comments, W3C specs do not allow css in footer, quote from specs page linked:
A link
element must have a rel
attribute.
If the rel
attribute is used, the element is restricted to the head
element.
Aside from that, you should note that when you add css in footer, when someone opens your page it appears unstyled until the full css is loaded: with slow connections your page will appear broken for some seconds, elements hidden via css will be visible, sliders appear like ul lists of visible images...
So, really, I think it's a bad idea.
That said, I don't like the "don't do that" kind of answers, I prefer the "you can do that in this way, but I suggest don't do that" kind.
So, here the way to do that, but hey, I suggest to don't do that.
Things are more easy as you can expect: scripts and styles should be added on wp_enqueue_scripts
hook, but if you enqueue styles after wp_head
hook has been fired, then scripts and styles are added in the footer.
An useful application of that is when scripts are enqueued inside a shortcode callback, adding possibility to add shortcode-specific scripts with ease.
Regarding styles, WordPress is not intransigent about W3C statements and will put styles on footer unblinkingly.
Workflow:
- hook
'wp_print_styles'
, when all scripts and styles are already enqueued, but not printed
- store current queue for scripts and styles in variables
- empty the queue for both scripts and styles, in this way, when WordPress look to print scripts and styles in head will find nothing to print
- hook
'wp_footer'
with priority 0, and restore the styles and scripts queue you stored at point #2, in this way, when WordPress look for styles and scripts to print in footer can find and print them.
All can be done in few lines of code:
add_action('wp_print_styles', function() {
if ( ! doing_action( 'wp_head' ) ) { // ensure we are on head
return;
}
global $wp_scripts, $wp_styles;
// save actual queued scripts and styles
$queued_scripts = $wp_scripts->queue;
$queued_styles = $wp_styles->queue;
// empty the scripts and styles queue
$wp_scripts->queue = array();
$wp_styles->queue = array();
$wp_scripts->to_do = array();
$wp_styles->to_do = array();
add_action( 'wp_footer', function() use( $queued_scripts, $queued_styles ) {
// reset the queue to print scripts and styles in footer
global $wp_scripts, $wp_styles;
$wp_scripts->queue = $queued_scripts;
$wp_styles->queue = $queued_styles;
$wp_scripts->to_do = $queued_scripts;
$wp_styles->to_do = $queued_styles;
}, 0 );
}, 0);
Note
Code above require PHP 5.3+ for the usage of closure and WP 3.9 for the usage of doing_action
.