There is a more elegant solution to this problem via computed property names (for FF>34, Chrome, Safari>7.1):
<div data-bind="css: { [color]: true,'translucent': number() < 10 }">
static dynamic css classes
</div>
Whereas color is a property with a string value.
If the value of color is an observable then we need to clear the classname before that observable updates. If we do not do this then each change will add another class and not remove the previous one. This can easily be accomplished manually but I wrote an extender for those who are interested.
ko.extenders.css = function(target, value) {
var beforeChange;
var onChange;
//add sub-observables to our observable
target.show = ko.observable(true);
beforeChange = function(oldValue){
target.show(false);
}
onChange = function(newValue){
target.show(true);
}
target.subscribe(beforeChange, null, "beforeChange");
target.subscribe(onChange);
return target;
};
With this extender, your JavaScript code would look like this:
function MyViewModel() {
this.color = ko.observable("red").extend({ css: true });
this.number = ko.observable(9)
};
And your markup would be this simple:
<div data-bind="css: { [color()]: color.show(),'translucent': number() < 10 }">
static dynamic css classes
</div>
I have a code pen demonstrating this technique:
http://codepen.io/USIUX/pen/WryGZQ
I have also submitted an issue with knockout in hopes that one day the custom extender will not be necessary: https://github.com/knockout/knockout/issues/1990