• Quick note - the problem with Youtube videos not embedding on the forum appears to have been fixed, thanks to ZiprHead. If you do still see problems let me know.

CSS Variables?

RSLancastr

www.StopSylvia.com
Joined
Sep 7, 2001
Messages
17,135
Location
Salem, Oregon
Is there any way to use variables within CSS?

For example: I am creating a style sheet which includes various colors (background colors, font colors, etc).

Every time I experiment with different colors, I have to do a scan/replace to change all the references to a given color. This becomes even more of a pain in the ass if I have used the same color for more than one element, but want to change only one of them.

It would be nice if I could just define variables (like MainBackgroundColor, etc) up front and use those variables throughout the sheet, so I only have to change the statement where the variable's value is set.

Is there any such capability within CSS?
 
How are you building your objects?

You shouldn't have a whole lot of objects to change. You aren't using one of those cursied WYSIWYG editors, are you?

(Also, have you tried find/replace? :D )
 
How are you building your objects?
If by "objects" you mean the .css and .htm files, I am using a text editor.

(Also, have you tried find/replace? :D )
Yes, but again, if you are using the same color for more than one purpose, using find/replace to change its use for ONE of those purposes without changing it for the others becomes problematic.

I've found a workaround which helps with my particular situation. The majority of colors I am dealing with are background colors, so I am using little one-color .jpg files for the background colors. Although this can make for some delays while the image is loaded, all I have to do to change the color throughout the site is to change the .jpg.

I may go back to #xxxxxx literals later, but for now, while I am experimenting with various combinations, it is helpful.
 
If by "objects" you mean the .css and .htm files, I am using a text editor.


No. The purpose of .css is to describe objects in the HTML.

You should have to change ONE color in the .css to change all background color on all pages.

Do you have an example of the HTML/CSS online to look at?
 
No. The purpose of .css is to describe objects in the HTML.
Ah. I didn't think of the divs and such as objects.

How am I building them? With a text editor.

You should have to change ONE color in the .css to change all background color on all pages.
Yes. But if you have multiple objects (within a given css) which refer to this same color, you have to change it on ALL objects. It would be nicer if it could be done in one spot in the css rather than several.

It still beats hell out of changing it in every html on the site, though.

I don't currently have any of it up on a server, but will by the end of the month.
 
only if the style information is generated dynamically.

A good text editor (or even a css specific editor) can help you at least find and replace them much more quickly. PSPad is free and pretty good:
http://www.pspad.com/en/

Using CSS inheritance properly can sometimes reduce the need for specifying things over and over, although without seeing the CSS directly I can't say that for sure.

I've seen a lot of problems with people just specifying TOO many classes, not ever block of text needs to be classified differently from everything else.
 
Last edited:
Hey RSL...

Are you a C programmer?

If so, this will (potentially) make sense. Use the C preprocessor.
 
Sorry, although I did write a program or two in C long ago and far away, I am by no stretch of the imagination a C programmer.

That's OK, my solution for you doesn't require you to know C, but it uses the macro facility of the C preprocessor.

This is easy, btw... Here's how:

I'll use a simple example css file (test.css) with only four lines in it:

Code:
a:link {color:#2f78c0;}
a:visited {color:#2f78c0;}
a:hover {color:#2fc0c0;}
a:active {color:#2fc0c0;}

Notice how in this contrived example, we want to use the same colour a couple of times. In fact, we want to do this for a couple of colours.

OK, rename the file to test.cssp (or something).

Modify it as so:

Code:
#define LINK_COLOUR	2f78c0
#define HOVER_COLOUR	2fc0c0

a:link {color:#LINK_COLOUR;} 
a:visited {color:#LINK_COLOUR;} 
a:hover {color:#HOVER_COLOUR;} 
a:active {color:#HOVER_COLOUR;}

See what we've done? We've defined macros that the C preprocessor will expand.

Use this command line:

gcc -E -x c -P test.cssp > test.css

This will expand the macros and create a file called test.css for you, with your colour values inserted in the right place.

Let me know if you need more info.
 
Last edited:
I've looked into this further, and it might be more useful to use the m4, or gm4, macro processor program instead of the C preprocessor.

Google 'css preprocessor' or 'html preprocessor' and you'll find lots of information.
 
m4

I'd like to give an example of how to do this using the m4 macro processor, rather than the C preprocessor. The example is for a CSS fixed-width three-column layout, and demonstrates the flexibility of the macro processor approach.

Say you want a layout that's 768 pixels wide, divided into three columns, 164, 448, and 156 pixels wide respectively. There's padding applied to each column, and you have a hack in there to make sure it works in (nearly) all browsers. To get some of the values you need, you have to apply a little arithmetic to the column and padding widths.

If you ever wanted to change the widths, you'd have to recalculate everything. We'll use m4 to do all the hard work for us, and make it very easy to make new layouts with different widths.

Please note that this approach can be used for any layout type, not just the one presented here.

OK, time to look at some code. The CSS we want to end up with is this:

* { margin: 0; padding : 0; }
#wrapper { width: 768px; }
#col_container { width: 448px; padding-left: 164px; padding-right: 156px; }
#col_container .column { position: relative; float: left; }
* html #col_left { width: 164px; w\idth: 148px; }
#col_left { width: 148px; margin-left: -612px; padding: 0px 8px 0px 8px; }
* html #col_middle { width: 448px; w\idth: 416px; }
#col_middle { width: 416px; padding: 0px 16px 0px 16px; }
* html #col_right { width: 156px; w\idth: 140px; }
#col_right { width: 140px; margin-right: -156px; padding: 0px 8px 0px 8px; }
#footer { clear: both; }

I won't go into details about how all the values were arrived at. You'll see the calculations in the next bit of code.

Normally, you'd create a .css file and put all that code in there. What we're going to do, though, is create a .m4 file (actually, the extension is irrelevant) and use the m4 program to generate our .css file.

Here's the .m4 file:

changecom(`~')

define(`LINK_COLOUR', 2f78c0)
define(`HOVER_COLOUR', 2fc0c0)

define(`COL_LEFT_FULL_WIDTH', 164)
define(`COL_LEFT_LEFT_PAD', 8)
define(`COL_LEFT_RIGHT_PAD', 8)
define(`COL_LEFT_WIDTH', eval(COL_LEFT_FULL_WIDTH - COL_LEFT_LEFT_PAD - COL_LEFT_RIGHT_PAD))

define(`COL_MIDDLE_FULL_WIDTH', 448)
define(`COL_MIDDLE_LEFT_PAD', 16)
define(`COL_MIDDLE_RIGHT_PAD', 16)
define(`COL_MIDDLE_WIDTH', eval(COL_MIDDLE_FULL_WIDTH - COL_MIDDLE_LEFT_PAD - COL_MIDDLE_RIGHT_PAD))

define(`COL_RIGHT_FULL_WIDTH', 156)
define(`COL_RIGHT_LEFT_PAD', 8)
define(`COL_RIGHT_RIGHT_PAD', 8)
define(`COL_RIGHT_WIDTH', eval(COL_RIGHT_FULL_WIDTH - COL_RIGHT_LEFT_PAD - COL_RIGHT_RIGHT_PAD))

define(`FULL_WIDTH', eval(COL_LEFT_FULL_WIDTH + COL_MIDDLE_FULL_WIDTH + COL_RIGHT_FULL_WIDTH))

a:link {color:#LINK_COLOUR;}
a:visited {color:#LINK_COLOUR;}
a:hover {color:#HOVER_COLOUR;}
a:active {color:#HOVER_COLOUR;}

* { margin: 0; padding : 0; }
#wrapper { width: FULL_WIDTH()px; }
#col_container { width: COL_MIDDLE_FULL_WIDTH()px; padding-left: COL_LEFT_FULL_WIDTH()px; padding-right: COL_RIGHT_FULL_WIDTH()px; }
#col_container .column { position: relative; float: left; }
* html #col_left { width: COL_LEFT_FULL_WIDTH()px; w\idth: COL_LEFT_WIDTH()px; }
#col_left { width: COL_LEFT_WIDTH()px; margin-left: -eval(COL_MIDDLE_FULL_WIDTH + COL_LEFT_FULL_WIDTH)px; padding: 0px COL_LEFT_RIGHT_PAD()px 0px COL_LEFT_LEFT_PAD()px; }
* html #col_middle { width: COL_MIDDLE_FULL_WIDTH()px; w\idth: COL_MIDDLE_WIDTH()px; }
#col_middle { width: COL_MIDDLE_WIDTH()px; padding: 0px COL_MIDDLE_RIGHT_PAD()px 0px COL_MIDDLE_LEFT_PAD()px; }
* html #col_right { width: COL_RIGHT_FULL_WIDTH()px; w\idth: COL_RIGHT_WIDTH()px; }
#col_right { width: COL_RIGHT_WIDTH()px; margin-right: -COL_RIGHT_FULL_WIDTH()px; padding: 0px COL_RIGHT_RIGHT_PAD()px 0px COL_RIGHT_LEFT_PAD()px; }
#footer { clear: both; }

It contains a couple of other things in there as well as the layout.

If we run this command line:

m4 test.m4 > test.css

(assuming that the file was called test.m4) then the m4 program will generate a file called test.css with the following content:

a:link {color:#2f78c0;}
a:visited {color:#2f78c0;}
a:hover {color:#2fc0c0;}
a:active {color:#2fc0c0;}

* { margin: 0; padding : 0; }
#wrapper { width: 768px; }
#col_container { width: 448px; padding-left: 164px; padding-right: 156px; }
#col_container .column { position: relative; float: left; }
* html #col_left { width: 164px; w\idth: 148px; }
#col_left { width: 148px; margin-left: -612px; padding: 0px 8px 0px 8px; }
* html #col_middle { width: 448px; w\idth: 416px; }
#col_middle { width: 416px; padding: 0px 16px 0px 16px; }
* html #col_right { width: 156px; w\idth: 140px; }
#col_right { width: 140px; margin-right: -156px; padding: 0px 8px 0px 8px; }
#footer { clear: both; }

How's that? Exactly what we were after.

If you study our .m4 file, you'll see definitions for column widths and paddings. You can simply change any of them and all the dependent values will be calculated automatically, saving you a lot of work and error-proofing your code.

I prefer this to the php approach for a number of reasons:

  1. It doesn't rely on a web server, meaning I can experiment with my css on my, or any, local machine.
  2. The generated CSS file is just like any other CSS file, and will be cached by browsers, saving a hit on every page on your site. The PHP version won't be cached in browsers.
  3. It doesn't require the PHP interpreter to run on each hit, saving time and resources.
  4. PHP is really for dynamic content. Preprocessing is for static content.

Now, let's take a look at our .m4 file in detail.

The first line:
changecom(`~')
changes m4's comment delimiter from the default '#' to '~'. Otherwise, text coming after '#' would be seen as comments.

define(`COL_LEFT_FULL_WIDTH', 164)
defines a macro called COL_LEFT_FULL_WIDTH and sets its expansion to 164. Simple stuff, really.

define(`COL_LEFT_WIDTH', eval(COL_LEFT_FULL_WIDTH - COL_LEFT_LEFT_PAD - COL_LEFT_RIGHT_PAD))
defines a macro called COL_LEFT_WIDTH and sets it to the result of the operation evaluated by the eval builtin macro.

a:link {color:#LINK_COLOUR;}
calls the macro LINK_COLOUR, replacing the text LINK_COLOUR with the text 2f78c0.

#wrapper { width: FULL_WIDTH()px; }
The macro call here has braces after it, otherwise we'd have FULL_WIDTHpx as our token and the macro processor would not recognise the macro.

#col_left { width: COL_LEFT_WIDTH()px; margin-left: -eval(COL_MIDDLE_FULL_WIDTH + COL_LEFT_FULL_WIDTH)px; padding: 0px COL_LEFT_RIGHT_PAD()px 0px COL_LEFT_LEFT_PAD()px; }
This line has a number of macro expansions, including an eval macro call for some arithmetic.

You can compare the .m4 file to the generated .css file to see how the macros are expanded.

The m4 program is available as standard on Unix computers, including Linux and Mac. It's also available for Windows.
 
Thanks LM for the wonderful examples. I'm not sure if this is the route I'll be taking, but I definitely appreciate your help.
 
Instead of using variables, you could simply specify common properties (such as colours) for multiple elements in one statement:

Code:
.menu, .footer, .content .list {
color: #FF00FF;
font-family: "Comic Sans";
}
You can then add specific properties (that aren't the same in a of the specified elements) in separate CSS statements.
 

Back
Top Bottom