CSS templates for JavaScript

TeaCSS extends CSS with dynamic behaviour of JavaScript.

It offers features similar to LESS.js or SASS such as variables, mixins and functions.

But it is

  • Easier to debug (because TeaCSS compiles to line-to-line Javascript),
  • Faster to compile (very simple single pass parser that is less than 300 lines of code), supports any current and future CSS-rules,
  • Bundles with own framework - donut
  • Has a number of extensions to simplify development process - ui, canvas
  • Can be used as build system also (some kind of Makefile but for browser)
  • If used as build system can produce JS and CSS files for your web application

Download TeaCSS

Write some tea-style:

.box_shadow(x,y,blur,alpha) {
  @ color = 'rgba(0,0,0,'+alpha+')'
  box-shadow: @color @x @y @blur;
  -webkit-box-shadow: @color @x @y @blur;
  -moz-box-shadow: @color @x @y @blur;
}
.box {
  @ base = '#f938ab';
  @ border_color = lighten(base, 30);
  color: @{saturate(base, 5)};
  div {
    .box_shadow(0, 0, '5px', 0.4);
    border: 1px @border_color solid;
  }
}

Include teacss.js with your styles:

<link tea="style.tea">
<script src="teacss.js"></script>

Overview

Tea is not a new language. It is a CSS preprocessor, it just adds Javascript embedding (with some syntaxic sugar) and rule nesting. So all the power of Tea is the power of Javascript.

Javascript embedding

You have four choices of embedding JS.

  1. Simple inline. Used to evaluate single Javascript variable.
    body { 
      color: @color; 
    }
    
  2. Complex inline. For complex expressions.
    body {
      color: @{lighten(color,5+x*3)};
    }
    
  3. Single line block
    body {
      @ var color = lighten(other_color,25); 
      @ var border_big = add_border(border_small,'5px');
    }
    
  4. Multiline block. Allows you to run lots of JS inside template.
    body {
      @{
        var color = lighten(other_color,25);
        if (lightness(color)>25)
          border_big = add_border(border_small,'5px');
      }
    }
    

Every css rule is getting transformed to JS function call. So contexts and variable visibility as similar to JS. Here is an example TeaCode and its JS variant:

body {
  @ var color = 'red';
  background: @color;
  h2 {
    font-weight: bold;
  }
}
tea.rule("body",function(){
  var color = 'red';
  tea.rule("background: "+color+";")
  tea.rule("h2",function(){
    tea.rule("font-weight: bold;")
  })
})

Variables

You can use variables like in LESS or SASS but in Tea they are just JS variables, with no hidden caveats and additionary types for colors or dimensions.

So you can type:

/* TeaCSS */
@ var color = '#4D926F';
#header {
  color: @color;
}
h2 {
  color: @color;
}                    
/* Compiled CSS */
#header {
  color: #4D926F;
}
h2 {
  color: #4D926F;
}

Mixins in Tea are just JS functions.

Plain CSS rules are functions that are executed right in place.

body {
  color: red;
}
tea.rule('body',function(){
  tea.rule('color:red')
}

adds 'color:red' to rule stack.

And mixin is function for later use.

.my_mixin(color) {
  color: @color;
}
my_mixin = function(color){
  tea.print('color: '+color);
}

adds nothing to rule stack, but declares JS functions that can be used in plain rule. p You can call mixins as functions or using alternative syntax. So: table

body {
  .my_mixin('red');
}
body {
  @ my_mixin('red')
}

are equivalent and produce Highlight csscolor: red

As javascript does not support default parameters Tea CSS does neither. You can implement them in JS as usual.

.my_mixin(color) {
  @ color = color || 'blue'
  color: @color;
}

Of course, you can define functions as object members.

@ my_namespace = {}
.my_namespace.my_mixin(color) {}

Nested rules

Rather than constructing long selector names to specify inheritance, in TeaCSS you can simply nest selectors inside other selectors. This makes inheritance clear and style sheets shorter. table

/* TeaCSS */
#header {
  h1 {
    font-size: 26px;
    font-weight: bold;
  }
  p { font-size: 12px;
    a { text-decoration: none;
      &:hover { border-width: 1px }
    }
  }
}
/* Compiled CSS */
#header h1 {
  font-size: 26px;
  font-weight: bold;
}
#header p {
  font-size: 12px;
}
#header p a {
  text-decoration: none;
}
#header p a:hover {
  border-width: 1px;
}

Usage

Client-side

Link your .tea stylesheets with the rel set to “stylesheet/tea”:

<link tea="style.tea">

Then download teacss.js from the top of the page, and include it in the element of your page, like so:

<script src="teacss.js"></script>

Make sure you include your stylesheets before the script.

Server side

TeaCSS does not handle saving css to server but simplifies process a lot.

You can add code like this to you development version of page:

<script>
  teacss.buildCallback(function(files){
    $.ajax({ type:'POST', url: location.href, data: {css:files['\default.css']}  });
  });
</script>
<? if (isset($_POST['css']) file_put_contents('path/style.css', $_POST['css']) ?>

Then for every tea link in page you will see an overlay ui that helps you to build all your styles.