views:

238

answers:

8

I am trying to write the HTML and CSS for an internal webapp properly. As much as technically possible, I want the HTML markup to define the content of the page and be completely independent of what the layout will need to be.

Obviously it is not possible to do this perfectly. I die a little inside every time I have to add an extra nested div for the sole purpose of making the layout work.

The most recent problem I have been trying to tackle is how to reduce the amount of duplicated text in my .css file. The main thing is colors. All throughout my app I use colors to represent "clean", "errors", "warnings", and "pardoned" and so far pretty much every place that uses the colors needs to have them explicitly defined. Sometimes they are used for text colors, sometimes background colors, sometimes border colors.

Is there a way to assign a value such as a color to a name, and then reference that name in the CSS properties?

I am aware of how inheritance works in CSS and I am aware that one method of accomplishing this goal would be to use multiple class names on a lot of my elements and then I could just have backgroundClean be a style that all sorts of objects use. But that requires making the HTML aware of more data that is only relevant to the stylistic layout of the page and not the data, which as I mentioned I would like to avoid.

Bonus Question: What is the best practice for doing this kind of stuff? Am I stupid in trying to make HTML+CSS act like an MVC when it is not ready to do so? I know that is the direction CSS has always been headed but perhaps it's just not there yet.

+9  A: 

Why yes, there are newly introduced css variables to do this!

Unfortunetly... it's not made its way into browsers yet, so you can't use them, just yet.

To get the same behavior, you'll need to use some sort of Server-Side language to output the color dynamically into your CSS files. (You could also use a ton of javascript, but that'd be horrible)

So in PHP you could do this:

styles.php---------------------
<?php
$warningColor = "#f00";
?>

.warning {
     color: <?=$warningColor?>;
}
.error {
     color: <?=$warningColor?>;
}

index.html----------------------

<link rel="stylesheet" src="styles.php" />
Tom Ritter
"... can't use them just yet" ... or ever, really, since it will be AGES before you count on all the old, nonsupporting browsers to go away. Why oh why didn't they add this 10 years ago? :(
Joel Coehoorn
I actually use this solution on my own website. It lets me control the entire color scheme of the site by only changing a couple of hex values.
Christopher W. Allen-Poole
CSS variables are NOT a solution for an application written today--and it doesn't take a "ton" of JavaScript to manipulate the class names and other CSS-related attributes.
rp
Doing like this, browser can cause problems when caching stylesheets. So better use JavaScript :-)
Pawka
+1  A: 

I'm not sure that I totally understand your problem, but you may want to consider simply assigning a particular class for a color. For example, if all the text/divs/etc for a "warning" are bright red, you could do this in your css:

.warning { color: #f00; }

And then whenever you have a div, even if it already has extra classes, you simply add this one, space-separating the classes:

<div class="message warning">Invalid username.</div>

One thing to note is that it's not considered good practice to use color names for the classes, for example you shouldn't define a class named "blue". You should try to use the name for what that color is representing, in case you wish to change it in the future.

Edit: you did mention this in the question, but as far as I know it's going to be the best currently-possible way to do it, so I just wanted to expand on it a little.

Chad Birch
+5  A: 

Not with any current browser support no. Although if you preprocess your CSS with something like SASS then you do this and much more. SASS improves CSS is just about every single way. It makes it easier and much more fun to write stylesheets. I will never go back to writing vanilla CSS.

Squeegy
This SASS looks very interesting! I'm way too far in to this current project to switch to it but I am going to try it out for some of my personal projects.
OverloadUT
+1 to Sass. If you'd like to give it a try, you could use the included css2sass tool to transform your existing CSS into Sass. Since it's ultimately just an intermediate language, it doesn't really change the requirements of the project.
Chuck
A: 

I think the best way for you to accomplish this would be from the server side. Have your CSS be processed by the server so you can output what ever you'd like.

For example, if you were using C#, you would reference the variables using the script block

width: <%= Width %>
Bob
Doing this dynamically seems a waste of resources. It makes more sense IMHO to preprocess the template into a static file and put that on the server.
Chuck
A: 

Yes--it's called jQuery. Use JavaScript and a good JavaScript library (jQuery is excellent) and manipulate what you need that way.

rp
A: 

It is not possible to do this with plain HTML and CSS.

You could go for generating the CSS on the fly when requested to achieve similar effet; however, you will have to control the caching of such CSS very carefully to find the balance point between total control of the output and minimizing the bandwidth usage for the user.

You can also implement it with jQuery or any other JavaScript framework, but that puts more work on the browser and if used with no restriction can make your page unresponsive to the user.

Franci Penov
A: 

If you don't want to or don't have access to server side scripting, one workaround would be to use Javascript on the client. Just something with document.write() would do the trick. Only problem is the line breaks...

<script type="text/javascript">
<!--
var sColor = "#f0000";
var myCSS = ".red {" +
             "    color: " + sColor+
              "}" +
             ".error { " +
                  color: " + sColor +
             "}";

document.write(myCSS);
-->
</script>

Not too fiddly to write or read (IMHO) and rather simple to maintain... Personally, I would prefer a server side language. That way you are in control of what is happening completely. Or at least a bit more. ;-)

Tooony
It would be nice with a comment to the down vote ...
Tooony
A: 

Another possible solution is to include multiple definitions for each style...

.error{ text-decoration: underline; font-weight: bolder}

.cancelled{ text-decoration: line-through; font-style: italic;}

.warning{font-weight: bold}

.comment{font-size: smaller; font-style: italic}
.
.
.

.error, .cancelled { color: red };

.warning, .comment {color: green};

The key thing here is that you've decided that error and cancelled should be the same colour as each other and the warning and comment should be the same colour as each other. The actual colours to use are defined separately to the other style attributes and allow a single value to be changed, should a colour update be required.

The warning that I'd give with this, is that your style definitions are split into two places, so somebody may update the main one to use a different colour, then spend a long time scratching their head before they realise why it has no effect - i.e. because the second definition overrides it.

The server side approach mentioned by @Bob and Tom Ritter, is also worth considering but, as with the approach I suggest, is susceptible to caching issues.

belugabob