While using <img> tags to present icons is pretty straight forward, using CSS files is much more troublesome. I know Plone 2.5 used CSS classes for icons, but they switched over to <img> tags for version 3. I asked in #plone on IRC why they did this, and got these answers:

  • we used css before. it was painful to work with and didnt really help anyone
  • the images are defined in the fti. So you'd have to create a dynamic css from the fti. Images can use the icons directly from the fti.
  • css generation is slow
  • Images are good enough (tm)

I was also given an email address to limi, the co-founder of Plone, if I'd like to hear a better explanation as to why they ditched CSS classes. I don't think that will be necessary though..

Using CSS classes is difficult because the available icons (and thus image URLs) are defined based on user selection, overrides and default fallbacks. A CSS file must therefore be dynamically created whenever new icons are installed or when user selects preferred icons. It was mentioned that CSS generation is slow, but this isn't something that's done on every request, and the generated CSS file may later be optimized and cached anyway...

Some advantages to CSS classes are; they are accessible standards compliant (icons aren't images that need to be part of the document), and icons may be added to any existing DOM element. But creating a dynamical CSS file of classes isn't dynamical enough - one would still need to apply to classes to elements, so the second advantage wouldn't apply anymore.

I really like what Alpritt just proposed on IRC. To use variables in the theme's CSS file, and have the module replace those placeholder variables with actual values (in this case image urls, but this may even be hex codes, font sizes - basically anything). The resulting CSS file would then be saved as a new .css file in the files/css directory (if that's the right place). The icon module would the add that CSS file using drupal_add_css(), allowing it to be optimized and cached by Drupal. This way, icons could be attached to virtually anything on the document, as long as it's possible to do with CSS.

Example of original variable-infested CSS file:

#edit-preprocess-css-0-wrapper input {
  background: url([icon:disabled,16]) no-repeat;
  padding-left: 21px;
}
#edit-preprocess-css-1-wrapper input {
  background: url([icon:enabled,16]) no-repeat;
  padding-left: 21px;
}

And the resulting variable-replaced CSS file:

#edit-preprocess-css-0-wrapper input {
  background: url(/sites/default/themes/mytheme/icons/16x16/disabled.png) no-repeat;
  padding-left: 21px;
}
#edit-preprocess-css-1-wrapper input {
  background: url(/sites/default/themes/mytheme/icons/16x16/enabled.png) no-repeat;
  padding-left: 21px;
}

Comments

quicksketch’s picture

The concept of this from the designers aspect is very appealing. Just pop in some brackets and you're done. However, I'm not sure the processing of CSS files is going to be palatable by the Drupal community. We already do something sort of similar for JS files, check out drupal_add_js() and the way that the new Drupal.t() function works in Drupal 6. The JS files are parsed for calls to Drupal.t(), then the strings are translated and added to the page as JavaScript variables. It's pretty flippin' slick.

The one thing I don't particularly like is that we're now writing invalid CSS files. Perhaps we could do something really tricky and just have a convention for icons? Something like

background-image: url(/icons/16/enabled.png);

The path "/icons" would be a tip off to the Drupal theme system that some icons need to be put in place. Then we could generate just a *single* dynamic CSS file that just contains background-images that need to be put in place. Because browsers are smart enough to read all the CSS files before pulling in images, we don't have to worry about the fact that those icons at /icons don't actually exist.

Continuing this train of thought, there's no reason why we need to even have /icons in the path to identify if it's an icon that can be overridden. If modules provide a filepath => icon mapping in their "icon.info" file, we'd could actually determine which background-images are icons based off of this mapping.

In the end, we're going to need to generate a dynamic CSS file of some sort, that much seems to be certain. However, I'm opposed to the actual rebuilding of all CSS files. A single CSS file containing all the necessary background-images paths is much more appealing because it'll take much less work to Drupal core, and will be an easier sell.

ximo’s picture

I absolutely agree. I wasn't happy with non-standard template holders either. I used RCSS (templatable CSS files in Ruby) as inspiration and tried some other formats, but never thought of something as simple and functional as that. I like it a lot!

Taking the idea of a producing a single icons-specific .css file further, there could be an icons.css file to begin with, as an alternative to having the icons placed in style.css. The icons.css file would be automatically picked up by icon.module (as style.css is picked up by Drupal), it would be somewhat faster to regex (much smaller file), and the icon specific CSS would only be loaded once (not first in style.css, then overridden by the generated .css file). What do you think?

quicksketch’s picture

A separate CSS file for icons would make our job a lot easier, but I feel like it'd be a pain for everyone else. Note that we may need more than one icons.css file to be generated, since the combination of CSS files will change as you browse around the site. Similar to the CSS aggregator, we could generate icons.css files named with the MD5 hash of the combination of files that are currently added to the page.

i.e. /files/css/icons/90c32d384733ce4b0437e8c7ceb14cbe.css

markhalliwell’s picture

Version: » 6.x-1.x-dev
Status: Postponed (maintainer needs more info) » Closed (won't fix)

Closing per re-purposing of module. See: #1948240: [icon] Request re-purpose/ownership change