@import "stuff.css" /* css import is escaped */ @import "colors.jxss" // will be processed as jxss @import "colors.js" // will be imported but not processed //font(family,file,weight,style) font("Droid Sans","DroidSans","normal"); font("Droid Sans","DroidSans-Bold","bold","normal"); font("VarelaRoundRegular"); font("My Font","myfont","bold","italic"); %> <%-- this block is a jxp comment and is not processed <%@ import "colors.jxss" %> <%@ import "colors.js" %> --%> /* this block is escaped as raw css but can still be programmably generated using JXP tags */ A.raw {color:<%=jaxcorePurple40%> } A.raw:hover {color:<%=jaxcorePurple%> } A.custom {color : <%=mycustomcolor%> } <% P { SPAN, DIV { color : black; } } A { +:hover, :active { text-decoration:underline; } } a, a:visited, a:hover, a:active {border:none} // function function add(a,b) { return a+b } // variable, globals are okay within a jxss because it is executed in sandbox in nodejs odd = 2 foo = 500 bar = 75 radiusObject = { topLeft : 1, topRight : 2, bottomLeft : 3, bottomRight : 4 }; borderObject = { '@' : '2px dashed red', radius : radiusObject } function getBorder(color, width, radius) { return { '@' : width+' solid '+color, radius : radius }; } // object literals to use as mixins or for macros leftrightzero = { left : 0, right: 0 } topbottomzero = { top : 0, bottom: 0 } TABLE { border : { // border is a built-in macro @:red; // @ in a macro will output border:red; in addition to the other rules in the macro left : 5; // border-left:5px radius : 3 // border-radius : 3px; -webkit-border-radius:3px; ... }; P.one { margin : { // margin macro @ : 0; left : 1 }; border-radius : 3; // border-radius macro will produce the appropriet -webkit -moz variations border : { left : 5; }; font-family: Lucida, Arial // spaces in css rules will be autowrapped as a string }; +.stuff { // + will append this selector to it's parent to produce TABLE.stuff instead of TABLE .stuff border : { @ : pink; // pink is a known color, single words that are unknown need to be wrapped in quotes radius : 5; } }; P.two { font : { // font macro will create the associate font-weight font-family... weight : bold; family : Arial; style : normal; size : 11pt; }; border-radius : { // border-radius macro top-left : 5; bottom-right : 4 }; margin : { // margin macro units also can be used left : 3; bottom : 1em; right : 2px; top : 5pt; } }; // several ways to specify border radius corner values DIV.radius { border : { @ : 1px solid black; radius : { // individual values top-left : 5; bottom-right : 4; }; } } DIV.radius2 { border : { @ : 1px solid black; // quick syntax radius : 1 2 3 4; // top-left, top-right, bottom-left, bottom-right } } DIV.radius3 { border : { @ : 1px solid black; // set from javascript object radius : radiusObject; } } DIV.radius4 { // radius object without nesting border-radius : radiusObject; } DIV.border1 { // set the whole border from an object border : borderObject; } DIV.border2 { // set using a custom function border : getBorder(grey, 2, 5); } font-family : "Digital"; // must use quotes here to produce string output margin : 1 2 1 2; // margin macro accepts this format to produce "1px 2px 1px 2px" output SPAN { border : 1; SPAN.two {height : 100}; // inline nested block }; DIV { color : (odd%2==1)? 'blue' : 'red'; // inline javascript processing margin : (function(){ // inline anonymous function execution var a = 1; var b = 2; return add( a, b ); // returns 3 which gets preprocessed to "3px" in output }()); P { glow2 : red; // red here is processed as a js variable glow3 : 'red'; // to not process as a variable use quotes B {border : 'orage'}; // inline nested TABLE DIV P B SPAN.one { height : 1002; // certain css rules like width/height/left/top get "px" added to them a : 1; // unkown css values will be outputted as-is SPAN.two { width : 55; SPAN.three { height : 5em // deep nesting outputs TABLE DIV P SPAN.one SPAN.two SPAN.three } } }; } height : 50; } SPAN.leftright { padding : leftrightzero; // macros accept objects margin : topbottomzero; border : leftrightzero; } // some notes about CSS/JS interpretation /* all css values that look like: something-something something something are outputted as strings if surrounded with brackets () it enforces javascript if surrounded with quotes "" '' it enforces strings */ P.math { width : foo-bar; // due to jxss processing rules this outputs literal string "foo-bar" height : (foo-bar); // use brackets to force evaluation left : foo bar; // this is also outputed as a string "foo bar" right : foo+bar; // but this does get processed because + isn't used in css bottom : "foo+bar"; // if surrounded by quotes it becomes a literal string "foo+bar" } // mixins accept an object or objects who's properties are copied to the current ruleset P.mixin { color : blue; @(leftrightzero); // that's a mixin border : 1; } // multiple mixins P.mixins1 { @( leftrightzero, topbottomzero, {width:50,height:80} ); } // alternate syntax for multiple mixins P.mixins2 { @(leftrightzero); @(topbottomzero); @({ width : 100, height : 200 }) } // mixins set by a function P.mixinfn { @(function() { var mixins = {}; var count = 1; ['left','right','top','bottom'].forEach(function(p) { mixins[p] = count++; }); return mixins; }()); } } // gradients DIV.gradient1 { background-image : linearGradient(top,[ [0.5, rgb(200,200,200)], [1.0, 240,240,240] // simplified ]); } DIV.gradient2 { background-image : linearGradient(left,[ [0, 59,36,77], [0.25, 102,74,157], [0.75, 102,74,157], [1, 59,36,77] ]); } .grey { y : 'x' + 'y' + 1; // remember closing brace must be by itself } // CSS3 macros A.boxshadow { box-shadow:[rgb(0,0,0,0.4),0,1,5] } A.boxshadows { box-shadow:[ [1,1,1,rgba(92,64,147,0.9)], [3,3,3,rgba(92,64,147,0.7)], [6,6,6,rgba(92,64,147,0.5)], [9,9,9,rgba(92,64,147,0.3)] ]; } DIV.transition { transition: all 3s ease-in; } DIV.hovertransition { +:hover { transition: all 3s ease-in; } } DIV.transitiontransform { transition: -webkit-transform 0.5s ease-in; } DIV.translaterotate { transform: translate(140px) rotate(20deg); // translate(100)+' '+rotate(20) also works transform-origin: 60% 100%; // 60+'% '+100+'%' also works } DIV.transformmatrix { transform: matrix(1, -0.2, 0, 1, 0, 0); } DIV.transform { transform: translate(540,-200); } DIV.rotate { transform: rotate(70); } DIV.transitionproperties { transform-origin: bottom left; transition-property: left, top, background, -webkit-transform; transition-duration: '2s, 2s, 1s, 1s'; // todo: need to stringify it this case to prevent compile error transition-timing-function: ease-out, ease-in, linear, ease-in-out; transition-delay: '0, 0, 0, 1s'; } A.textshadow { text-shadow:[0,2,2,rgba(92,64,147,0.4)] } A.textshadows { text-shadow:[ [1,1,1,rgba(92,64,147,0.9)], [3,3,3,rgba(92,64,147,0.7)], [6,6,6,rgba(92,64,147,0.5)], [9,9,9,rgba(92,64,147,0.3)] ]; } A { background-image:url(dataURI(__dirname+'/jaxcore.png')) } include('colors.jxss'); include('colorsinc.jxss'); include('colorsinc.jxss',{color:black}); %> /* url("/path/to/image.png") = <%=url("/path/to/image.png")%> dataURI('jaxcore.png') = <%=dataURI('jaxcore.png')%> RGB / HSL Functions rgb(0,0,0) = <%=rgb(0,0,0)%> rgb(102,74,157) = <%=rgb(102,74,157)%> rgb([102,74,157]) = <%=rgb([102,74,157])%> rgba(0,0,0, 0.5) = <%=rgba(0,0,0, 0.5)%> alpha("#000", 0.5) = <%=alpha("#000", 0.5)%> alpha("#000", null) = <%=alpha("#000", null)%> alpha(rgb(100,50,200),0.7) = <%=alpha(rgb(100,50,200),0.7)%> hex2rgb("#664A9D") = <%=hex2rgb("#664A9D")%> rgb2hex([102,74,157]) = <%=rgb2hex([102,74,157])%> color2hex("#664A9D") = <%=color2hex("#664A9D")%> color2hex(rgb(102,74,157)) = <%=color2hex(rgb(102,74,157))%> color2hex(rgba(0,0,0,0.5)) = <%=color2hex(rgba(0,0,0,0.5))%> color2hex([102,74,157]) = <%=color2hex([102,74,157])%> color2rgb("#000") = <%=color2rgb("#000")%> color2rgb("#664A9D") = <%=color2rgb("#664A9D")%> color2rgb(rgb(102,74,157)) = <%=color2rgb(rgb(102,74,157))%> color2rgb(rgba(0,0,0,0.5)) = <%=color2rgb(rgba(0,0,0,0.5))%> color2rgb([102,74,157]) = <%=color2rgb([102,74,157])%> saturation(rgb(180,0,0),0) = <%=rgb2hsl([180,0,0])%> saturation(rgb(180,0,0),0) = <%=saturation(rgb(180,0,0),0)%> saturation('#f00',0.5) = <%=saturation('#f00',0.5)%> saturation(rgba(100,50,200,0.5),1) = <%=saturation(rgba(100,50,200,0.5),1)%> lightness(rgb(180,20,50),0) = <%=lightness(rgb(180,20,50),0)%> lightness(rgba(180,20,50,0.4),0.5) = <%=lightness(rgba(180,20,50,0.4),0.5)%> lightness('#ff7a20',1) = <%=lightness('#ff7a20',1)%> getAlpha('#000') = <%=getAlpha('#000')%> getAlpha(rgb(100,0,50)) = <%=getAlpha(rgb(100,0,50))%> getAlpha(rgba(100,0,50,0.4)) = <%=getAlpha(rgba(100,0,50,0.4))%> getAlpha(alpha('#f00',0.8)) = <%=getAlpha(alpha('#f00',0.8))%> getHue(rgb(100,0,50)) = <%=getHue(rgb(100,0,50))%> getHue('#664A9D') = <%=getHue('#664A9D')%> getSaturation(rgb(100,0,50)) = <%=getSaturation(rgb(100,0,50))%> getSaturation('#664A9D') = <%=getSaturation('#664A9D')%> getLightness(rgb(100,0,50)) = <%=getLightness(rgb(100,0,50))%> getLightness('#664A9D') = <%=getLightness('#664A9D')%> rgb2hsl([100,0,50]) = <%=rgb2hsl([100,0,50])%> rgb2hsl(hex2rgb('#664A9D')) = <%=rgb2hsl(hex2rgb('#664A9D'))%> color2hsl(rgb(100,0,50)) = <%=color2hsl(rgb(100,0,50))%> color2hsl('#ffa0b5') = <%=color2hsl('#ffa0b5')%> hsl2rgb([0.916666,1,0.196078]) = <%=hsl2rgb([0.916666,1,0.196078])%> // to use degress and percentages and round the result hsl2rgb([20/360,50/100,20/100]).map(Math.round) = <%=hsl2rgb([20/360,50/100,20/100]).map(Math.round)%> // to use degress and percentages and convert to rgb() value rgb(hsl2rgb([20/360,50/100,20/100])) = <%=rgb(hsl2rgb([20/360,50/100,20/100]))%> HSLtoRGB(20,50,20) = <%=HSLtoRGB(20,50,20)%> rgb(HSLtoRGB(20,50,20)) = <%=rgb(HSLtoRGB(20,50,20))%> RGBtoHSL(77,43,25) = <%=RGBtoHSL(77,43,25)%> <%=rgb(160,70,90)%> lighten('#A0465A', 0) = <%=lighten(rgb(160,70,90), 0)%> lighten(rgb(160,70,90), 0.1) = <%=lighten(rgb(160,70,90), 0.1)%> lighten(rgb(160,70,90), 1) = <%=lighten(rgb(160,70,90), 1)%> lighten(rgb(160,70,90), 2) = <%=lighten(rgb(160,70,90), 2)%> darken('#A0465A', 0) = <%=darken(rgb(160,70,90), 0)%> darken(rgb(160,70,90), 0.1) = <%=darken(rgb(160,70,90), 0.1)%> darken(rgb(160,70,90), 1) = <%=darken(rgb(160,70,90), 1)%> darken(rgb(160,70,90), 2) = <%=darken(rgb(160,70,90), 2)%> saturate('#A0465A', 0) = <%=saturate(rgb(160,70,90), 0)%> saturate(rgb(160,70,90), 0.1) = <%=saturate(rgb(160,70,90), 0.1)%> saturate(rgb(160,70,90), 1) = <%=saturate(rgb(160,70,90), 1)%> saturate(rgb(160,70,90), 2) = <%=saturate(rgb(160,70,90), 2)%> desaturate('#A0465A', 0) = <%=desaturate(rgb(160,70,90), 0)%> desaturate(rgb(160,70,90), 0.1) = <%=desaturate(rgb(160,70,90), 0.1)%> desaturate(rgb(160,70,90), 1) = <%=desaturate(rgb(160,70,90), 1)%> desaturate(rgb(160,70,90), 2) = <%=desaturate(rgb(160,70,90), 2)%> blueshift('#A0465A', 0) = <%=blueshift(rgb(160,70,90), 0)%> blueshift(rgb(160,70,90), 0.1) = <%=blueshift(rgb(160,70,90), 0.1)%> blueshift(rgb(160,70,90), 1) = <%=blueshift(rgb(160,70,90), 1)%> redshift('#A0465A', 0) = <%=redshift(rgb(160,70,90), 0)%> redshift(rgb(160,70,90), 0.1) = <%=redshift(rgb(160,70,90), 0.1)%> redshift(rgb(160,70,90), 1) = <%=redshift(rgb(160,70,90), 1)%> hsl(100, 50, 50) = <%= hsl(100, 50, 50) %> hsl('100deg', '50%', '50%') = <%= hsl('100deg', '50%', '50%') %> hsla(100, 50, 50, 0.5) = <%= hsla(100, 50, 50, 0.5) %> hsla('100deg', '50%', '50%', 0.5) = <%= hsla('100deg', '50%', '50%', 0.5) %> hslx(0.3, 0.5, 0.3) = <%= hslx(0.3, 0.5, 0.3) %> hslx(0.3, 0.5, 0.3, 0.5) = <%= hslx(0.3, 0.5, 0.3, 0.5) %> <%=color2hsl(red)%> <%=getHue(red)%> <%=blueshift(red,0.5)%> */ <% DIV { +:first-child { TH:first-child { border : 1 }; border : 1; }; TR:first-child { TH { +:first-child { border:{ @ : 2px solid red; radius : { top-left : 5 }; }; }; +:last-child { border:{ radius:{ top-right:4; bottom-left:3 } }; }; } }; } DIV.three { border-radius : { top-left : 3; top-right : 4; bottom-left : 5; bottom-right : 6; }; } DIV.four { border : { @ : 1px solid black; radius : { top-left : 3; top-right : 4; bottom-left : 5; bottom-right : 6; } } } DIV.five { // short-hand syntax border-radius : 3 4 5 6; } // camel case must be used here because this is a javascript object, not JXSS var radiusMacro = { topLeft : 3, topRight : 4, bottomLeft : 5, bottomRight : 6, }; DIV.six { border-radius : radiusMacro; } DIV.seven { border : { @ : 1px solid black; radius : radiusMacro; } } @media print { DIV { border : red; } } @media screen and (orientation: landscape) { DIV { border : blue; } } @media print { body { font-size: 10pt } } @media screen { body { font-size: 13px } } @media screen, print { body { line-height: 1.2 } }