Ever wanted to create dynamic CSS? Here's an example of how to render a template-based string of CSS that you can populate with variables.
For this example, let's say we want to generate CSS to change the font size of a page title.

  1. Create your CSS template (style.css.php):

    @CHARSET "UTF-8";
    #content h1.title{ font-size: <?php print $font_size; ?>px;}
    
  2. Write code to render the template and get the resulting string:

    <?php
    $variables = array(
      'font_size' => 20,
    );
    
    extract($variables, EXTR_SKIP);
    ob_start();
    include('style.css.php');
    $css = ob_get_contents();
    ob_end_clean();
    
    // the resulting $css variable can be used to include or print the style in various ways:
    print '<style type="text/css">'.$css.'</style>';
    ?>

Generously borrowed from phptemplate

Comments

Kars-T’s picture

Hi,

I appriciate the wish to share knowledge but this page lacks a real discussion about this issue. I don't think it is such a good idea to rip somepart out of phptemplate and put it here. This is one way to achieve some CSS templates. But for example dynamic classes or ids in HTML with static CSS would be a better solution than inline CSS or some dynamic CSS solution imo. And you can't use drupal_add_css with this easily.

Please no offense but I vote for removing this node.

--
Best regards

Karsten Frohwein

Scheepers de Bruin’s picture

This is especially useful if you happen to be a themer and a developer. It also removes the need to create huge css files that cater for absolutely any font-size, column width, page width etc. imaginable.

Pilot’s picture

Actually, there are some cases where it would really nice to set certain variables in the CSS, for example from the theme-settings page. For example, if you want to be able to set block or column widths.

Or perhaps I am missing something...

Cheers!

ss81’s picture

Hi All

I use a bit another way:

style.css.php:

<?php 
header('Content-type: text/css');
ob_start("compress");
function compress($buffer) {
  $buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
  $buffer = str_replace(array("\r\n", "\r", "\n", "\t", '  '), '', $buffer);
  $buffer = str_replace(array(', ', ' {'), array(',', '{'), $buffer);
  return $buffer;
}
?>

CSS CODE HERE

<?php ob_end_flush(); ?>

Best regards,
Sergei

ridgerunner’s picture

The comment matching regex in your code is fatally flawed (for most NFA regex engines - including PHP/PCRE). Although this regex does work very well when matching valid comments, it fails and goes super-linear (i.e. experiences "catastrophic backtracking") when faced with an invalid comment such as this one:

'/************************ /'

The regex engine requires more than 400,000 steps to determine that this short string does not match. (Adding just two more asterisks kicks this up to over a million!) Fortunately, the regex is easily fixed by adding just one character...

Bad:
/\*[^*]*\*+([^/][^*]*\*+)*/
Good:
/\*[^*]*\*+([^/*][^*]*\*+)*/

The fixed regex requires only 9 steps to declare a non-match. Please refer to the book: "Mastering Regular Expressions (3rd Edition)" by Jeffrey Friedl for a complete description of this regex and the advanced "un-rolling-the-loop" technique that it employs. (Friedl is the one who originally wrote this regex and came up with this technique).

For more info an Catastrophic Backtracking see:
http://www.regular-expressions.info/catastrophic.html

Hope this helps. =^)

mshepherd’s picture

[Edit : I did this in Drupal 7, but it's mostly pretty version independant I think]

I used this idea so I could keep the PIE.htc file in the theme. When I specified
behavior: url('PIE.htc');
in my CSS file, I was expecting that it would find PIE.htc in the same directory as the CSS file. But it expects the file to be in drupal's root directory, along with index.php. I didn't want to specify the full path to my theme folder as it immediately becomes quite unportable.

So I made pie.css.php:

#selector,
#another-selector
{
behavior: url('/<?php print drupal_get_path('theme', 'MYTHEME') . '/pie/PIE.htc';?>');
}

And put this into the relevant template (in my case html.tpl.php):

  // add in support for CSS3PIE for CSS3 prettiness in IE browsers
  ob_start();
  include('pie.css.php');
  $css = ob_get_contents();
  ob_end_clean();
  print '<!--[if lte IE 9]><style type="text/css">'.$css.'</style><![endif]-->';

If anyone has a neater way of doing this, I'd be pleased to hear of it.

tsi’s picture

You can use drupal_add_css() with all its benefits :

  ob_start();
  include('styles/dynamic.css.php');
  $dcss = ob_get_contents();
  ob_end_clean();
  drupal_add_css($dcss, array('type' => 'inline', 'preprocess' => FALSE));

http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_ad...

Tsachi Shlidor (@shlidor)

themesidea’s picture

for example, you create a dynamic.css.php and put inside this code

  // start output
  $styles = '<style type="text/css">'."\n";

  $styles .= 'body { background color: #'.theme_get_setting('body_color').'; }'."\n";

  $styles .= '</style>'."\n";
  // end output

  print $styles;

in template.php you put this code:

function theme_dynamic_css() {
  global $theme_path;
  require_once $theme_path . '/my-folder/dynamic-styles.css.php';
}

and you call theme_dynamic_css() directly from html.tpl between tag

For me work fine and is more flexible.