Evolution and birth of CSSX – CSS in JavaScript

css-javascript

JavaScript is considered to be the universal web language in the times we live in now. After the introduction of JSX by Facebook, which is a mere mix of HTML with JavaScript , the idea to merge CSS in JavaScript producing CSSX may lead to ease of coding and access across the globe.

Just like JSX, CSSX proposes encasing. To be able to envision all functions of a single part is a leap forward. To understand the need of consumers and their approach to be able to do everything within the browser they use is the sole reason for Facebook utilizing JSX. Tying parts of HTML and JavaScript is most common, however bringing them together increases accuracy and certainty.

Idea & Approach

css-js

Krasimir Tsonev, having a decade of experience in programming, coding and web development and dedicating his work towards delivering cutting edge applications, thought about the concept way back in 2013. To be able to manage one file instead of various external style sheets. As the styles “prevail” with JavaScript they are packaged together. Foreseeing complication and resolving them was his key approach, however he faced two major issues:

  • Flash of Un-styled Text (FOUT) – The user visualizes the first few seconds of Un-styled text and then the actual image, leading to a poor user experience with improper layout shifts.
  • Modification of the Style property of the DOM Element leaves us with no style sheet with minimal classifications.

Krasimir wanted not only to shape a solution but also illustrate with example as to how effective would this combination be, so he remarkably created a CSS library within JavaScript.

cssjs

An image of the CSSX Library set up in JavaScript by Krasimir Tsonev

The developed library would stand as the mediator between JS and CSS. The responsibility of the library would extend to creating a virtual style sheet incorporating the <style> tag in it. This strategy would help keep the dynamic styles closely knit to the JavaScript that manages it. CSS rules would be generated on the fly at runtime.

Adding removing and altering styles within the JavaScript integrated CSS would be the same as the style sheet in a static file.

The way around the FOUT is to understand “what parts of CSS should be written in JavaScript” rather than use all parts at once.

The CSSX Library

In order to gain access to the CSSX Library either add cssx.min.js file on your page or install the module by npm install cssx. For a demonstration to see CSSX in action follow the link GITHUB.

With the JavaScript –only API, here is an example with one style sheet and a single rule registered:

var sheet = cssx();
sheet.add('p > a', {
'font-size': '20px'
});

If processed through a browser, we would see a new style tag injected in the head of the document:

<style id="_cssx1" type="text/css">p > a{font-size:20px;}</style>
The add method accepts a selector and CSS properties as an object literal, as explained by Krasimir. He further explains that there would be no benefit of doing this in JavaScript on account of it being a static declaration. To develop it further he showcases the following:

var sheet = cssx();
var rule = sheet.add('p > a');
var setFontSize = function (size) {

return { 'font-size': size + 'px' };
};

rule.update(setFontSize(20));

rule.update(setFontSize(24));

With the available code, another interesting fact displayed is the alteration of the font size dynamically. The resulting code is shown:

p > a {
font-size: 24px;
}

Further styling within the CSSX rule object with different scopes is as followed:

var sheet = cssx();

// `header` is a CSSX rule object
var header = sheet.add('.header');

header.descendant('nav', { margin: '10px' });
header.descendant('nav a', { float: 'left' });
header.descendant('.hero', { 'font-size': '3em' });

The observation of the short code above is below:

.header nav {
margin: 10px;
}
.header nav a {
float: left;
}
.header .hero {
font-size: 3em;
}

Krasimir further focuses on shortcuts utilized within the code for ease of coding. For example header.descendant will be used as header.d thus minimizing the need to type in the complete word ‘descendant’.
Another shortcut with similarities to .descendants would be .nested. The library intelligently adds and saves definitions as illustrated in the example below:


var smallScreen = sheet.add('@media all and (max-width: 320px)');
smallScreen.nested('body', { 'font-size': '10px' });

/* results in
@media all and (max-width: 320px) {
body {
font-size: 10px;
}
}
*/

For a programmer with immense experience in coding, Krasimir explains that the process enlisted above is not simple and lengthy and not as easy as integrating and writing Vanilla CSS.

The Turning Point – CSS coding in JavaScript

As displayed above, written CSS format is not very clear and Krasimir urges towards the same. He also understand the need for optimization and setting up of helpers, just like in regular CSS. On further clarification the mere fact that JSX was developed with its own syntax as a myth was busted by Krasimir, stating that it was the Trans-piling of JSX to valid JavaScript at the time of the buildup. The final bundle for JSX, executed in a browser contained the valid code shown as below:

transpiler

Krasimir looks forward to a better code and stability knowing that a code language like JSX manages to conceal its actual complexity of utilizing HTML Templates.

babylon

His keen understanding of the code in order to successfully use parts of CSS within the JavaScript would launch directly from his comprehension of how Babylon understands JSX.

JSX utilizes the Babylon module to parse the source code and transform it in to an Abstract Syntax Tree (AST). Later upon compilation the babel generator parses and converts it to a valid JavaScript Code and so Babel understands JSX.

As any inventor, Krasimir started the CSSX plugin unaccountable number of times. He was determined to setting up a plugin just like JSX. As time heals almost everything, he understood that JSX is quite different and his needs were only to integrate and implement within CSS. Babylon has more than 2100 tests, obviously reasonable knowing that it comprehends a complex language like JavaScript.

Design Decisions:

1. var styles = {
margin: 0,
padding: 0
}

He was successful throughout until trying to run his plugin against all the tests within Babylon. A node was produced constantly ObjectExpression.

In order to ascertain what was invented, he needed to parse the whole block, so instead he used a different syntax:

var styles = cssx({
margin: 0;
padding: 0;
});

The above can be stated as written in CSSX Expression successfully.

A quote & method directly from Krasimir would explain the above:

“I was using CSSX with the cssx( … ) notation for a while, but then I realized that I could replace it with <style> … </style>>. It was a cheap switch. Every time the code lands in the parser, just before processing it, we run a simple regex replacement:

code = code.replace(/<style>/g, 'cssx(').replace(/<\/style>/g, ')');

This helps us write the following:

var styles = <style>{
margin: 0;
padding: 0;
}</style>;

And we have the same result in the end”.

A Few CSSX Expressions

Let’s see a couple of simple transformations.

var styles = <style>{
font-size: 20px;
padding: 0;
}</style>>;

This is transformed to the following:

var styles = (function () {
var _2 = {};
_2['padding'] = '0';
_2['font-size'] = '20px';
return _2;
}.apply(this));

That’s the first type, where we produce a simple object literal. The equivalent of the code above is this:

var styles = {
'font-size': '20px',
'padding': '0'
};

Here is the transpiled JavaScript:

var sheet = (function () {
var _2 = {};
_2['padding'] = '0';
_2['font-size'] = '20px';

var _1 = cssx('_1');

_1.add('.header > nav', _2);

return _1;
}.apply(this));

With the above illustrated, he clarifies that a new style sheet has been defined with cssx (‘_ 1 ’)
Furthermore if this codes is run twice then it wouldn’t be creating an additional style tag instead would be using the same one as cssx () would be using the same ID (_1) and thus has the same style sheet object.

The Code

To show what was invented by Krasimir in practice he set up a React Navigation Menu as followed:

(The final source code of this example is available on GitHub. Simply download the files, and install the dependencies with npm install. Then, runnpm run dev to compile the JavaScript, and open example/index.html in a browser. A live demo of the result is also available.)

The Grounds

Having established that CSSX is limited to serve most of the CSS properties, it is significant to understand that it is to contain only those bits that are dynamic. A basic example of normal CSS would be as followed:

body {
font-family: Helvetica, Tahoma;
font-size: 18px;
}
ul {
list-style: none;
max-width: 200px;
}
ul, li {
margin: 0;
padding: 0;
}
li {
margin-bottom: 4px;
}

The navigation will be consisting of “out of order” list of items. Every bit will contain an <a> tag, which depicts the clickable (hand- hyper) area.

Summation

To understand an experiment and to know the end results, is itself a revelation of a new beginning. However Krasimir confirms that he is still adding various components and styles to the CSSX version. Being his brainchild for ease of coding and running alongside JSX, he dedicated this workflow to relate the same feeling programmers may have while using HTML and CSS in JavaScript. But honestly most programmers have been doing the same for years, the need for optimization however wasn’t brought up necessarily.

To find out more and contribute on similarities on JSX and the new CSSX see how it works- Check out the Demo

Links:

Languages:
CSSX Language, Github

Sources:
Github- Krasimir

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

Leave a Reply

Your email address will not be published. Required fields are marked *