27

I recently released a plugin, WP Coda Slider, that uses shortcodes to add a jQuery slider to any post or page. I am adding an options page in the next version and I would like to include some CSS options but I don't want the plugin to add the style choices as inline CSS. I want the choices to be dynamically added to the CSS file when it's called.

I would also like to avoid using fopen or writing to a file for security issues.

Is something like this easy to accomplish or would I be better off just adding the style choices directly to the page?

5
  • @Chris_O: I have been thinking about almost exactly the same thing. What I'm wanting is a way to call wp_enqueue_style() (and wp_enqueue_script()) with a function name instead of a filename and have my function generate the CSS (or JS) but still have it ultimately included via a linked stylesheet. As far as I know this isn't possible with the wp_equeue_*() functions. Maybe we should submit a trac ticket? Sep 7, 2010 at 6:44
  • @MikeSchinkel: That would be a very logical way to use the wp_enqueue functions. I would add support to that ticket.
    – Chris_O
    Sep 7, 2010 at 7:24
  • @Chris_O: I just saw @Doug's answer; I made a bad assumption you already knew that. Had I realized that was not the case I would have pointed you to here: wordpress.stackexchange.com/questions/556/#562 Sep 8, 2010 at 0:12
  • @MikeSchinkel I knew about wp_register and wp_enqueue. I was looking for a way to build the style sheet based on the values from the plugin options page.
    – Chris_O
    Sep 8, 2010 at 0:37
  • @Chris_O: Ah. I like to think of myself as someone who can still see what others are missing in a solution even after I learn the solution (i.e most experts are not good teachers and though I'm not the best expert I'm generally a good teacher.) OTOH, this is one that I missed, sorry. :) Sep 8, 2010 at 0:40

5 Answers 5

28

Use wp_register_style and wp_enqueue_style to add the stylesheet. DO NOT simply add a stylesheet link to wp_head. Queuing styles allows other plugins or themes to modify the stylesheet if necessary.

Your stylesheet can be a .php file:

wp_register_style('myStyleSheet', 'my-stylesheet.php');
wp_enqueue_style( 'myStyleSheet');

my-stylesheet.php would look like this:

<?php
// We'll be outputting CSS
header('Content-type: text/css');

include('my-plugin-data.php');    
?>

body {
  background: <?php echo $my_background_variable; ?>;
  font-size: <?php echo $my_font_size; ?>;
}
3
  • 3
    Additionally - as the values only change when the values on the option page are changed - you could generate the CSS file on save. You can store CSS files in the plugin directory as well, so this is a bit more performant then to run a PHP file on each CSS request with includes etc. .
    – hakre
    Sep 7, 2010 at 21:44
  • 1
    Thanks! worked well. But I got the fatal error get_option()... is undefined. Then I loaded the wp-config.php file and then fixed the issue. Jan 2, 2014 at 13:43
  • Sumith, could you explaing how youhave used the get_option inside the custom CSS file? Many thanks! Sep 9, 2015 at 11:50
10

Dynamically building a CSS file and then loading it adds a HUGE performance burden to what should be a very low bandwidth deal of adding a CSS file, especially if there are variables in the CSS that are going to be processed through WP. Because it is two different files being created for one page load, WP starts up twice and runs all the DB queries twice, and it's a big mess.

If your slider is only going to be on one page, and you want the styles set dynamically, then your best bet is to add a style block to the header.

In order of performance:

  1. Add small block of styles in header, dynamically created - Very fast
  2. Add a non-dynamic stylesheet via wp_enqueue_style - Medium
  3. Add a dynamic stylesheet via wp_enqueue_style - Very Slow
3
  • @Dan-gayle Very good point. The plugin can be used on more than one page and some users are using it on 2 or 3 pages. It only enqueues the current static style sheet and js on pages that have the shortcode.
    – Chris_O
    Sep 7, 2010 at 17:25
  • I agree with Dan Gayle, even though you voted up my answer. Adding a small CSS block to wp_head would be much better performance-wise than requiring a separate stylesheet be downloaded on every page view (even if restricted to the few posts/pages with the shortcode). The only reason to use separate stylesheets in the first place is that they can be cached by the browser. Dynamic stylesheets can not be cached.
    – Doug
    Sep 7, 2010 at 17:56
  • 2
    Is this still the right way to go about things?
    – Dave Kiss
    May 21, 2013 at 14:26
2

This is how I usually do it:

function build_stylesheet_url() {
    echo '<link rel="stylesheet" href="' . $url . 'stylesheetname.css?build=' . date( "Ymd", strtotime( '-24 days' ) ) . '" type="text/css" media="screen" />';
}

function build_stylesheet_content() {
    if( isset( $_GET['build'] ) && addslashes( $_GET['build'] ) == date( "Ymd", strtotime( '-24 days' ) ) ) {
        header("Content-type: text/css");
        echo "/* Something */";
        define( 'DONOTCACHEPAGE', 1 ); // don't let wp-super-cache cache this page.
        die();
    }
}

add_action( 'init', 'build_stylesheet_content' );
add_action( 'wp_head', 'build_stylesheet_url' );
0
1

I've had difficulty with all the recommendations of this ilk - maybe I'm a bit thick, or maybe contributors have lost the common touch.

I settled on coding this in the plug-in php file:-

echo "<link href='http://www.brittany-gite-holidays.co.uk/wp-content/plugins/flexavailability/css/css.css' type='text/css' rel='stylesheet' />";
echo "<link href='http://www.brittany-gite-holidays.co.uk/wp-content/plugins/flexavailability/css/public.css' rel='stylesheet' type='text/css'/>";

It seems to work. It only loads on those pages which use the plugin. It loads after the h1 tag which is fine by me. I can't see how it could be more efficient or more clear.

....but perhaps I'm wrong - I did say I was a bit thick.

3
  • You should only load <link> elements in the page head
    – shea
    Jan 18, 2013 at 20:37
  • Yerss. That would be because your css is wanted to affect everything from the top of the page downwards. I'm happy to affect only what comes after the h1 tag. I couldn't make any of the examples work (I think they may be badly explained).Try it for yourself on some piece of test html. If i'm wrong tell me :)
    – chazza
    Jan 19, 2013 at 18:56
  • @chazza That's not the only reason. When a browser detects any styles after the body tag is written, it stops whatever else it is doing until that style is loaded and applied, which is bad for performance and leads to screen reflows and flashes of unstyled text. However, if it doesn't really matter, throw those css files in like you said. I do it all the time, and at the end of the day it's fine. Not optimal, but fine.
    – Dan Gayle
    Feb 1, 2016 at 19:40
0

Update since Wordpress 3.3

There is a function called wp_add_inline_style which can be used to dynamically add styles based on theme/plugin options. This can be used to add a small css file in the head which should be fast and efficient.

<?php
function myprefix_scripts() {

    wp_enqueue_style('name-of-style-css', plugin_dir_path(__FILE__) . '/css/ccsfilename.css');

    $css = get_option( 'loader_css', 'default css goes here for when there is no value' );

    //or for Example
    $color = get_option( 'custom_plugin_color', 'red' ); //red is default value if value is not set
    $css = ".mycolor{
                background: {$color};
           }";

    wp_add_inline_style('name-of-style-css', $css);

}

add_action( 'wp_enqueue_scripts', 'myprefix_scripts' );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.