Download From GitHub

C<js>SS.js

Use Javascript In Your CSS
Bind Javascript Variables & Functions In CSS

Overview

CjsSS (Cascading Javascript Style Sheet) is LESS SASSy and more Stylush than the competition ;)

Our (twisted) sister project: ngCss Check out the Angular Directive+Filter+Factory (twisted) sister project ngCss for a CSS Preprocessor | Reprocessor with Angular binding.

Options

Option values can be passed into CjsSS.js in a number of locations:
  1. <div style="color: color;" cjsss="{ scope: '#myCss', async: false }">...</div>

    overrides:
  2. <style type="text/css" id="myCss" cjsss="{ async: true }" />...</style>

    or
    <link rel="stylesheet" type="text/css" id="myCss" href="css/site.css" cjsss="{ async: true }" />

    overrides:
  3. When placed on the first line within the CSS,
    /*cjsss({ async: false })*/

    overrides:
  4. The default values described below (which can be programmatically overridden).
In the example above,
options.async
will be set to
false
within the context of the
DIV
as the
DIV
tag's option values override the
STYLE
/
LINK
tags' option values.
options.async
will be set to
true
within the context of the
STYLE
/
LINK
tags' which overrides the CSS's inline option values.
options.async
was set to
false
within the CSS's inline option values which would have overriden the default value (
true
), but it never takes effect due to the
STYLE
/
LINK
tags' option values.
The use of the CSS's inline option values (#3) allows you to fully configure all aspects of CjsSS.js within the CSS itself.

scope

VARIANT (see valid values below) "isolated" The Javascript scope that the CSS embedded
SCRIPT
tags will be
eval
uated within:

selector

STRING (CSS Selector) [cjsss],[data-cjsss] The
selector
option defines the CSS selector to use by default. This
selector
is used when CjsSS.js autoruns and when
cjsss.process()
is called without any
vElements
defined. If you wish to disable autorun you must override the default value, resetting it to "" (a
null-string
).
In-line
selector
values set on
LINK
or
STYLE
tags are ignored
because the tags have already been selected by this point in the lifecycle.

expose

BOOLEAN inverse
truthy
value of
selector
Specifies if CjsSS.js functionality is to be made publicially accessable via
window.cjsss
. Any values set within
window.cjsss
prior to exposure will be retained. When exposed, the following
object
is made available via
window.cjsss
:
  • cjsss.options
    exposes the
    object
    containing the default option values described in this section, allowing the developer to override any default value.
  • cjsss.process(vElements, oOptions)
    processes the passed DOM
    vElements
    reference(s) utilizing the provided
    oOptions
    object
    in preference to the default values set within
    cjsss.options
    .
  • cjsss.services
    exposes an
    object
    containing the services utilized internally by CjsSS.js, allowing for the overriding of default behavior as well as plugin development.
If
expose
is set to
true
anywhere, CjsSS.js will be exposed despite any subsequent
expose = false
declarations. If you wish to remove
window.cjsss
after it has been exposed, you can use the
delete
operator
(e.g.
delete window.cjsss;
).

optionScope

VARIANT (see valid values below) "json" The Javascript scope that the CSS embedded
SCRIPT
tags will be
eval
uated within:
In-line
optionScope
values set on
LINK
or
STYLE
tags are ignored
because the options have already been parsed by this point in the lifecycle.

callback

FUNCTION undefined Defines the function** that will be called each time the CSS is updated. You can disable the callback by returning
false
from the function.

async

BOOLEAN true Specifies if
LINK
tags are to be processed asynchronously. If ordering matters in the execution of the embedded
SCRIPT
s, then this should be set to
false
.

d1

STRING Starting delimiter denoting embedded Javascript variables, e.g.
color: /*mainColor]]/*
.
Adjacent leading CSS comment syntax (e.g.
/*[[
) is implicitly removed.

d2

STRING Ending delimiter denoting embedded Javascript variables, e.g.
color: /*[[mainColor]]/*
.
Adjacent trailing CSS comment syntax (e.g.
]]*/
) is implicitly removed.
d1
and
d2
must contain non null-string values and be different; e.g.
$mainColor
nor
%mainColor%
are valid.
† - There is no reason to use
sandbox
over
isolated
if your CSS embedded
SCRIPT
tags are from a trusted source, especially considering the limitations of postMessage.
‡ - Allows for the sharing of functionality and variables across invocations.
* -
object
.script
must create a new Javascript scope; it cannot link to an existing scope.
** -
function
s are passed 2 arguments:
  1. domElement
    - the directive's DOM element.
  2. metadata
    - an object representing the internal metadata pertaining to the element.
Each
cjsss
attributed
LINK
tag is replaced with a
STYLE
tag with only the
cjsss
attribute copied across. If you require additional attributes or processing to apply to these created
STYLE
tags, you can make any necessary modifications to the DOM element within a
function
.

style
Attributes

Variable
s can be used within any tag's
style
attribute (but
SCRIPT
tags are not permitted). When applying ngCss to a
style
attribute, you have two options when setting the value of
cjsss
's in-line options: Only the
style
attribute is effected by CjsSS.js in this context using a non-isolate
$scope
(even when the referenced element is!). This is accomplished by a bit of pre- and post-
$compile
slight-of-hand between the directive's
template
and
link
functions and custom linking code via a
$watch
(
live: true
) or
$on
(
live: false
).
Due to IE's behavior of removing invalid CSS settings from
STYLE
attributes at parse (which in turn, removes them from the DOM) it is necessary to specify CjsSS.js styles in a
cjsss-style
(or HTML5-compliant
data-cjsss-style
) attribute. The
cjsss-style
(or HTML5-compliant
data-cjsss-style
) attribute is concatnated with the additionally-defined
STYLE
attribute if it is present.

How To Override The Default Option Values

If you wish to override any of the default option values, you must include a Javascript code block like the one below before CjsSS.js's
SCRIPT
tag:
                window.cjsss = {
                    options: {
                        key: value
                    }
                };
                
Where
key
equals the option value you wish to reset and
value
equals the new default value.

Getting Started

Assuming the default option values are in effect as described above:
  1. Download CjsSS.js From GitHub
  2. Include the CjsSS.js
    SCRIPT
    tag(s) in the
    HEAD
    of your HTML document below any
    LINK
    /
    STYLE
    tags you want to process:
                            <script type="text/javascript" src="cjsss-polyfill.js"></script> <!-- IE6-7 support -->
                            <script type="text/javascript" src="cjsss.min.js"></script>
                            
  3. Add the
    cjsss
    attribute to the
    LINK
    and/or
    STYLE
    tags you want to process:
                            <link rel="stylesheet" type="text/css" href="css/site.css" cjsss>
                            <style type="text/css" cjsss>...</style>
                            
  4. Define the
    options
    used by CjsSS.js (if any) using JSON-style object definitions (both keys and values are "double quoted"):
                            <style type="text/css" cjsss='{ "crlf": "\n" }'>...</style>
                            <link rel="stylesheet" type="text/css" href="css/site.css" cjsss='{ "crlf": "\n" }'>
                            
  5. Edit the CSS within the
    LINK
    and/or
    STYLE
    tags to use CjsSS.js like this:
                            /*<script>
                                var mainColor = 'blue';
                            </script>*/
                            DIV {
                                color: /*mainColor*/;
                            }
                            
NOTE: You are also permitted to use the attribute name
data-cjsss
in place of
cjsss
if you want to be HTML5 compliant.

Advanced Configuration

If you want to change any of CjsSS.js's default functionality, you will first need to disable
autorun
and
expose
the
window.cjsss
object (NOTE:
expose
happens auto-magicially when you disable
autorun
) like so:
                <script>
                    window.cjsss = {
                        options: {
                            selector: '', //# disables autorun
                            expose: true  //# exposes `window.cjsss`
                        }
                    };
                </script>
                <script type="text/javascript" src="cjsss.min.js"></script> <!-- include CjsSS.js -->
                
When CjsSS.js is
expose
d, the following properties are made available under
window.cjsss
: * - Any values set within these properties prior to
expose
being run are preserved in addition to any other properties not described above (e.g.
window.cjsss.custom
would be preserved).

How To
inject
Custom Functionality

Continuing on from the code above to disable
autorun
,
cjsss.inject
can be used to expose any Javascript variable or value to your CjsSS.js evaluated Javascript code:
                <script>
                    //# .inject a function named "invertColor"
                    cjsss.inject("invertColor", function(sHex) {
                        var r, g, b, sReturnVal;

                        if (sHex.length === 7 && sHex.indexOf('#') === 0) {
                            r = "0" + (255 - parseInt(sHex.substr(1, 2), 16)).toString(16);
                            g = "0" + (255 - parseInt(sHex.substr(3, 2), 16)).toString(16);
                            b = "0" + (255 - parseInt(sHex.substr(5, 2), 16)).toString(16);
                            sReturnVal = "#" + r.substr(-2) + g.substr(-2) + b.substr(-2);
                        }

                        return sReturnVal;
                    });

                    //# .inject an object named "userConfig"
                    var defaultColor = {
                        color: "green"
                    };
                    cjsss.inject("userConfig", defaultColor);

                    //# .inject an object named "span"
                    var spanCss = {
                        backgroundColor: "red"
                        subObject: defaultColor
                    };
                    cjsss.inject("span", spanCss);

                    //# .inject a string named "textTransform"
                    cjsss.inject("textTransform", "capitalize");

                    //# Process the LINK / STYLE tags with a "cjsss" attribute and no oOptions
                    cjsss.process("[cjsss]", {});
                </script>
                
The code above exposes a function called "invertColor" to all CjsSS.js evaluated Javascript code like this:
                /*<script>
                    var sMainColor = "#cccccc";
                </script>*/
                DIV {
                    color: /*invertColor(sMainColor)*/;   //# invertColor returns '#333333'
                    text-transform: /*textTransform*/;    //# outputs 'capitalize'
                }                                             
                P {                                           
                    /*mixin(userConfig)*/                 //# outputs 'color: "green";'
                }                                             
                /*mixin(span, true)*/                     //# outputs 'span { background-color: "red"; color: "green"; }'
                

Plug-in Development and Overriding Internal Functionality

If you want to develop a plug-in or you need to override the default functionality of any aspect of CjsSS.js, you can do so via
cjsss.servicesFactory
or
cjsss.services
.

cjsss.services
exposes all of the internal functionality of CjsSS.js, allowing every piece of functionality within CjsSS.js to be overridden. Implementing a
cjsss.servicesFactory
under
window.cjsss
prior to including the CjsSS.js
SCRIPT
tag(s) allows you to override any
cjsss.services
functionality prior to CjsSS.js loading, or you can replace any of the functions under
cjsss.services
after CjsSS.js has been exposed via
window.cjsss
.

For example, if you wanted to override the
expose
functionality to make CjsSS.js available in a variable other than
window.cjsss
, you could do the following:
                <script>
                    var newVar = null;

                    window.cjsss = {
                        options: {
                            expose: true  //# exposes CjsSS.js under `newVar`
                        },
                        servicesFactory: function ($cjsss) {
                            return {
                                expose: function() {
                                    newVar = $cjsss;
                                }
                            };
                        }
                    };
                </script>
                <script type="text/javascript" src="cjsss.min.js"></script> 
                

Examples

To be added...

Jasmine Test Results

To be added...

Gotchas

Side Effects

What is up with the snake?

Oh, you mean Cee & Jay? They are the mascots for CjsSS.js!

CjsSS (cee-JAY-hiss or Cascading Javascript Style Sheet) is the union of two related web technologies joined seemlessly (unnaturally?) into one solution. Thanks to the akwardness of the acronym (ending in three S's) it seemed reminisent of a snake's hiss... "CSS and Javascript sss-ing"... "CJ hiss"... Hey! I need a two-headed snake!

CjsSS.js is a Vanilla-Javascript toolkit made by Nick Campbell, © 2014.

CjsSS.js is released under the MIT License. See the license.txt file in the source code for copy permission.

Nick is a web nerd who likes to tinker in his spare time; CjsSS.js is a product of that tinkering. Development is not supported by advertising nor the marketing of your email addresses. If you find this code useful, please consider tossing a few dollars into my tip jar. If you are a company that finds this code useful, please feel free to toss more than a few dollars into my tip jar ;)