It is possible to achieve what you want because after all, templating engines generate text, the context determines if it should be interpreted as HTML, SVG or CSS.
The technique I'm using is a bit counter-intuitive because it uses the style tag and we've been taught to stay away from embedding our CSS inside HTML pages, but the purpose of this recommendation is to separate HTML and CSS, which is still the case in the example I'm about to explain.
Suppose you have a collection of items with 4 properties relative to how you want to render them on screen.
- text : String of content.
- color1 and color2 : Strings representing HTML colors.
- gradient : Boolean; if true, use a background gradient with color1 and color2 then reverse the gradient on hover; if false, use color1 as background color then color2 on hover.
Let's fill a collection using this schema.
Items=new Collection("items");
for(var i=0;i<10;i++){
Items.insert({
text:"Item "+i,
color1:"#"+Random.hexString(6),
color2:"#"+Random.hexString(6),
gradient:Random.choice([false,true])
});
}
Now we define a template to iterate over our collection.
<template name="itemsList">
<ul class="items-list">
{{#each items}}
{{> item}}
{{/each}}
</ul>
</template>
Here comes the most interesting part : we use a style tag to define our inline CSS which is produced by a dedicated subtemplate.
The itemClass template gets passed the current context which is the item being iterated over.
<template name="item">
<li class="item item-{{_id}}">
<style scoped>
{{> itemClass}}
</style>
{{text}}
</li>
</template>
Our template generates CSS based on the properties of the current item : conditional formatting at last !
Since we're using Meteor, your formatting will be also reactive, how cool is that ?
<template name="itemClass">
height:64px;
.item-{{_id}}{
{{#if gradient}}
background:linear-gradient(to bottom, {{color1}} 5%, {{color2}} 100%);
{{else}}
background-color:{{color1}};
{{/if}}
}
.item-{{_id}}:hover,.item-{{_id}}:focus{
{{#if gradient}}
background:linear-gradient(to bottom, {{color2}} 5%, {{color1}} 100%);
{{else}}
background-color:{{color2}};
{{/if}}
}
</template>
Note : I'm using the scoped attribute of the style tag, which tells the browser that formatting defined in this section is local to the parent element (the li.item in this example), which makes totally sense.
http://www.w3schools.com/tags/att_style_scoped.asp
However this is supported only in Firefox at the moment so in other browsers the style tag produces plain old global CSS and we need a fallback : that's why I decorate the class name with the _id of the item.
If all browsers supported the scoped attribute, we could remove the item-{{_id}} class and style directly the item class instead, and it would work as expected !