I have a site with many page templates, and its having some format issues in IE7.

What I'd like to do is take Garland's cue and add a clause to check for the correct IE stylesheet based on browser. But rather than make this adjustment across 20 page templates, wondering if I can add to $styles in template.php... and have it always be called.

I see in Garland they added something like this into the of page.tpl

print drupal_get_path ( 'theme' , 'realself_default' ) /ie6.css" />
print drupal_get_path ( 'theme' , 'realself_default' ) /ie7.css" />

In my situation it would be more efficient to do this once in template.php in a little function that does this:
> gets called on every page template load (before pages render)
> check which browser version
> adds the correct stylesheet to the $styles variable.

Thanks for ideas,
-Greg

Comments

Chill35’s picture

If it is, then you can use conditionals in page.tpl.php. Each IE-readable conditional comment will link in the appropriate stylesheet.

The idea is as follows :

<!--[if IE]>
<p>You are seeing this sentence because you are using Internet Explorer.</p>
<![endif]-->

To deliver code to different versions of Internet Explorer, you can use the browser version and either gte, gt, lte or lt or none of these :

<!--[if IE 5]>
<p>You are seeing this sentence because you are using Internet Explorer 5</p>
<![endif]-->
<!--[if IE 5.0]>
<p>You are seeing this sentence because you are using Internet Explorer 5.0</p>
<![endif]-->
<!--[if IE 5.5]>
<p>You are seeing this sentence because you are using Internet Explorer 5.5</p>
<![endif]-->
<!--[if IE 6]>
<p>You are seeing this sentence because you are using Internet Explorer 6</p>
<![endif]-->

To deliver code to version of Internet Explorer 5 for Windows and higher :

<!--[if gte IE 5]>
<p>You are seeing this sentence because you are using Internet Explorer 5 AND up</p>
<![endif]-->

To deliver code to version of Internet Explorer 5.5 for Windows and lower :

<!--[if lte IE 5.5]>
<p>You are seeing this sentence because you are using Internet Explorer lower or equal to 5.5</p>
<![endif]-->

To deliver code to version of Internet Explorer for Windows below Internet Explorer 6, use this code:

<!--[if lt IE 6]>
<p>You are seeing this sentence because you are using Internet Explorer lower than 6</p>
<![endif]-->

Just replace the paragraph element with a style element, and put that in the head of page.tpl.php :

For example, to link in a stylesheet that will only be applied in Internet Explorer 6 :

<!--[if IE 6]>
<style type="text/css" media="all">@import "<?php print base_path() . path_to_theme() ?>/fix-ie-6.css";</style>
<![endif]-->

And of course, you have to consider :

- specificity : the order in which you link in these stylesheets
- creation of these stylesheets to be put in your theme folder

Caroline

Chill35’s picture

Just to clarify on the meaning of the keywords :

  • gte : greater than or equal
  • gt : greater than
  • lte : lesser than or equal
  • lt : lesser than

So to create a ie6/ie7 switcher you put that code in the <head> of page.tpl.php :

<!--[if IE 6]>
<style type="text/css" media="all">@import "<?php print base_path() . path_to_theme() ?>/fix-ie-6.css";</style>
<![endif]-->
<!--[if IE 7]>
<style type="text/css" media="all">@import "<?php print base_path() . path_to_theme() ?>/fix-ie-7.css";</style>
<![endif]-->

Caroline

Chill35’s picture

But rather than make this adjustment across 20 page templates...

I don't know how you could avoid this.

Something like that can probably be done (sorry to have hi-jacked the thread) :

In my situation it would be more efficient to do this once in template.php in a little function that does this:
> gets called on every page template load (before pages render)
> check which browser version
> adds the correct stylesheet to the $styles variable.

I just don't know how.

The thing is php cannot really "know" which browser is used, it's on the side of the server. That detection can (I THINK!) only be done using javascript or HTML conditional comments.

Caroline

Chill35’s picture

drupal_get_css() in includes/common.inc to do what you want.

Here is the function you would modify :

 function drupal_get_css($css = NULL) {
  $output = '';
  if (!isset($css)) {
    $css = drupal_add_css();
  }

  $preprocess_css = variable_get('preprocess_css', FALSE);
  $directory = file_directory_path();
  $is_writable = is_dir($directory) && is_writable($directory) && (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC);

  foreach ($css as $media => $types) {
    // If CSS preprocessing is off, we still need to output the styles.
    // Additionally, go through any remaining styles if CSS preprocessing is on and output the non-cached ones.
    foreach ($types as $type => $files) {
      foreach ($types[$type] as $file => $preprocess) {
        if (!$preprocess || !($is_writable && $preprocess_css)) {
          // If a CSS file is not to be preprocessed and it's a module CSS file, it needs to *always* appear at the *top*,
          // regardless of whether preprocessing is on or off.
          if (!$preprocess && $type == 'module') {
            $no_module_preprocess .= '<style type="text/css" media="'. $media .'">@import "'. base_path() . $file .'";</style>' ."\n";
          }
          // If a CSS file is not to be preprocessed and it's a theme CSS file, it needs to *always* appear at the *bottom*,
          // regardless of whether preprocessing is on or off.
          else if (!$preprocess && $type == 'theme') {
            $no_theme_preprocess .= '<style type="text/css" media="'. $media .'">@import "'. base_path() . $file .'";</style>' ."\n";
          }
          else {
            $output .= '<style type="text/css" media="'. $media .'">@import "'. base_path() . $file .'";</style>' ."\n";
          }
        }
      }
    }

    if ($is_writable && $preprocess_css) {
      $filename = md5(serialize($types)) .'.css';
      $preprocess_file = drupal_build_css_cache($types, $filename);
      $output .= '<style type="text/css" media="'. $media .'">@import "'. base_path() . $preprocess_file .'";</style>'. "\n";
    }
  }

  return $no_module_preprocess . $output . $no_theme_preprocess;
} 

Maybe you can change the ouput to add that html :

!--[if IE 6]>
<style type="text/css" media="all">@import "<?php print base_path() . path_to_theme() ?>/fix-ie-6.css";</style>
<![endif]-->
<!--[if IE 7]>
<style type="text/css" media="all">@import "<?php print base_path() . path_to_theme() ?>/fix-ie-7.css";</style>
<![endif]-->

In Drupal 5!

Chill35’s picture

Actually, it is more appropriate to override a themeing function here, rather than play with core.

The theming function to override in this case is :

theme_page($content)

Look at this function in theme.inc, copy and paste it in... oh wait, you'll have to override for all your themes... If you have 100 themes, you'll have to override a 100 times in a 100 different files.

Caroline

Anonymous’s picture

Thanks for the *great* response, Caroline.

That php wouldn't know about the browser type til the page is already rendered is a great point that I missed.

I went ahead and pasted the switcher code into on all the page templates. I use the base page.tpl and various switches to decide which exact page template to use... what I really need to do is simplify the head portion of those and consolidate some things together. We currently use different titles & meta tags on various templates head sections so they don't consolidate nicely.

Anyway, thank you for all of the ideas, great to have this how-to documented - I didn't see much to manage alt stylesheets efficiently in the forums, so this will be a nice addition. Worthy of a IE css handbook page.

-G

jenlampton’s picture

One thing I would like to see (in core?) is the option to add conditional comments in $styles and $scripts, maybe an arg in the drupal_add_css and drupal_add_js functions.

If you have lots of page-something.tpl.php it can get tedious to list the css or js files manually just because they need conditional comments.

If we could get some kind of $condition = array('Lte' => 'IE 7') passed into drupal_add_css it could gather all style sheets (or scripts) for a specific browser version, and print them together inside conditional comments, after all the other style sheets scripts have been printed.

Thoughts?

Jen

joshmiller’s picture

Check out the http://drupal.org/project/conditional_styles Module!

Josh

[edit] This only works for Drupal 6, though...