# Making JavaScript more CSS friendly.

**URL:** <https://es.discourse.group/t/making-javascript-more-css-friendly/470>\
**Category:** 💡 Ideas\
**Tags:** proposal\
**Created:** [September 16, 2020, 6:08pm UTC](https://es.discourse.group/t/making-javascript-more-css-friendly/470 "2020-09-16T18:08:19Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![c-smile](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/c-smile/32/226_2.png) [@c-smile](https://es.discourse.group/u/c-smile)\
**Post date:** [September 16, 2020, 6:08pm UTC](https://es.discourse.group/t/making-javascript-more-css-friendly/470/1 "2020-09-16T18:08:19Z")

</div>

Let's assume that JS is used mostly in context of Web (in browser or node/deno) so it would be nice for JS to allow to write CSS "directly" - so for JS syntax to include CSS syntax (at least partially) .

All below is based on [Sciter](https://sciter.com)'s script that was designed to better (than JS) serve "language-behind- UI" role. Yet below ideas are 100% backward compatible - existing code will work as it is.

## Proposal #1, syntax-only, object literals

In object literals allow `;` to be used as `,` name/value pairs separators. So

```javascript
{
   font: "system";
   opacity:0.5;
}

```

will be a valid object literal. As far as I know it will not break existing code.

## Proposal #2, syntax-only, object literals

To use CSS's nmtoken production in field names. CSS's name token matches JS name token but also allows `-` inside names. So this

```javascript
{
   font-family: "system";
   opacity:0.5;
}

```

will be a direct equivalent of

```javascript
{
   "font-family": "system";
   opacity:0.5;
}

```

## Proposal #3, syntax & runtime

To introduce Tuple type.

Tuple is a) tagged and b) immutable vector/array. Tuple literals look close to array literals :

```javascript
[nmtoken ':' element1, element2, ...]

```

Motivation: CSS uses "functions" in notation that are actually tuples - not functions.

So this CSS declaration:

```javascript
{
   background-color: rgb(255,0,0) ;
}

```

Can be expressed in JS++ as

```javascript
{
   background-color: [rgb:255,0,0];
}

```

or with some helper CSS namespace object as:

```javascript
{
   background-color: CSS.rgb(255,0,0);
}

```

Tuple class is essentially Array class a) without mutating methods and b) with .tag:string property.

## Proposal #4, syntax-only, numbers with units

For parser to support units, so this JS++ construct

```javascript
{
   border-width: 0.5em;
}

```

will be translated to tuple as:

```javascript
{
   border-width: [em:0.5];
}

```

FYI : I am running [campaign to Open Source Sciter](https://www.kickstarter.com/projects/c-smile/open-source-sciter-engine) now.

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [September 17, 2020, 6:28am UTC](https://es.discourse.group/t/making-javascript-more-css-friendly/470/2 "2020-09-17T06:28:31Z")

</div>

Proposal one is a block with two labeled statements, is it not?

---

<div class="post-metadata">

**Author:** ![c-smile](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/c-smile/32/226_2.png) [@c-smile](https://es.discourse.group/u/c-smile)\
**Post date:** [September 17, 2020, 1:43pm UTC](https://es.discourse.group/t/making-javascript-more-css-friendly/470/3 "2020-09-17T13:43:36Z")

</div>

No.

1. Labels cannot appear in object literals;
2. When JS parser gets opening `{` it knows exactly is it block or object literal.

---

<div class="post-metadata">

**Author:** ![vrugtehagel](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/vrugtehagel/32/653_2.png) [@vrugtehagel](https://es.discourse.group/u/vrugtehagel)\
**Post date:** [March 7, 2021, 5:00pm UTC](https://es.discourse.group/t/making-javascript-more-css-friendly/470/4 "2021-03-07T17:00:17Z")

</div>

As much as I love CSS, I don't think it's a good idea to do this for several reasons.

One is, you probably don't want to tie one language to another. What if CSS gets new features? Would that require JS engines to update as well?

As far as syntax goes, I'm not convinced any of the proposed syntaxes are better than just a template literal. Especially for more complex values, like the following:

```javascript
border-top: 23px solid rgb(0 40 123 / 40%);
background: no-repeat center / 80% url("../img/image.png");
content:
    "hello there, "
    attr(name)
    ", I see you've gotten to page "
    counter(page)
    ".";

```

Not to mention media queries, keyframe animations, or selectors, which would all be features that would be the next step after this.

My main line of thought is that either we're writing CSS in a string (which I'd say is preferable) or we inevitably have differences in the way we write CSS and CSS inside JS.

As a solution currently, you can implement a CSS tag and simply use

```javascript
CSS `
    background-color: rgb(255 0 0);
    border-width: 0.5em;
`;

```

allowing you to parse the CSS however you'd like.

---

<div class="post-metadata">

**Author:** ![c-smile](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/c-smile/32/226_2.png) [@c-smile](https://es.discourse.group/u/c-smile)\
**Post date:** [March 7, 2021, 6:14pm UTC](https://es.discourse.group/t/making-javascript-more-css-friendly/470/5 "2021-03-07T18:14:19Z")

</div>

I am not saying that whole CSS syntax should be in CSS but reasonable parts can be there.

And speaking about CSS grammar/syntax, as a person who implemented CSS and script parsers from scratch, here are some revelations if you wish:

CSS grammar has three list joiners (or groupings) (JS just one), all of them in order of precedence :

- a / b - '/' is a pair joiner, in JS++ it will be tuple `["/": a, b]`
- a b c - ' ' is a "space list" joiner, in JS++ it will be tuple `[" ": a, b, c]`
- a, b, c - ',' is a "comma list" joiner, in JS++ it will be tuple `[",": a, b, c]`

So this  
`border-top: 23px solid rgb(0 40 123 / 40%);`  
could be parsed to JS++ as:

`[" ": 23px, "solid", ["rgb": 0,40, ["/": 123,0.4] ] ]`

---

<div class="post-metadata">

**Author:** ![vrugtehagel](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/vrugtehagel/32/653_2.png) [@vrugtehagel](https://es.discourse.group/u/vrugtehagel)\
**Post date:** [March 7, 2021, 6:40pm UTC](https://es.discourse.group/t/making-javascript-more-css-friendly/470/6 "2021-03-07T18:40:38Z")

</div>

Right, but how does that improve the experience for me as a web developer? Why would I write

```javascript
{
    border-top: [" ": 23px, "solid", ["rgb": 0,40, ["/": 123,0.4] ] ]
}

```

rather than

```javascript
element.style.borderTop = '23px solid rgb(0 40 123 40%)';

```

I'm not conviced the new syntax improves the CSS-in-JS experience, let alone this syntax being useful enough to warrant a new JS syntax.

Let's look at a subset of your idea though; the dashes in property names. I've thought about that this would be nice, but this could be problematic when parsing JS. If we extend plain JS objects so that keys with dashes don't need dashes, then how would you read

```javascript
const top = -23;
const css = {
    border: 0;
    border-top: 'solid';
};
console.log(css.border-top); // 'solid' or 23?

```

this would mean you can define keys with dashes without quotes, but not access them (and no destructure them). I'm not a fan of this inconsistency, and I'm not convinced it improves drastic enough upon the existing way (simply using quotes around a property name).

The semicolons also could be problematic - introducing them as separators (instead of commas) in normal objects could lead to confusion, not only for developers, but also JS parsers:

```javascript
{
    foo: 'bar';
}

```

is already a valid statement - it's a block with one labeled statement, `'bar'`, but with your proposal it could also be interpreted as an object with one key-value pair `foo: 'bar'`.

All in all, I have the feeling this is a bit too broad of an idea and would lead to a lot of confusion for developers (it would for me, at least).

---

<div class="post-metadata">

**Author:** ![c-smile](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/c-smile/32/226_2.png) [@c-smile](https://es.discourse.group/u/c-smile)\
**Post date:** [March 7, 2021, 7:22pm UTC](https://es.discourse.group/t/making-javascript-more-css-friendly/470/7 "2021-03-07T19:22:57Z")

</div>

> [@vrugtehagel](#):
>
> but how does that improve the experience for me as a web developer?

I am saying that this:

```javascript
element.style.set { 
   border-top : 23px solid rgb(0 40 123 0.4);
}

```

could be a valid JS construct if following is met:

1. to allow "white space joiners" at least in object literals;
2. helper constants and functions like `const rgb => (r,g,b) ["rgb": r,g,b] `;
3. NNuuu support;

If you, as a web developer, think that embedded JSX is valuable then you may find embedded CSS valuable too. It is just that tuples + list joiners is the way to express as VNode (JSX) as CSSNode (CCSX) literals.

---

<div class="post-metadata">

**Author:** ![vrugtehagel](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/vrugtehagel/32/653_2.png) [@vrugtehagel](https://es.discourse.group/u/vrugtehagel)\
**Post date:** [March 8, 2021, 6:52am UTC](https://es.discourse.group/t/making-javascript-more-css-friendly/470/8 "2021-03-08T06:52:21Z")

</div>

Perhaps I misunderstood then. Is the idea to invent a new language that allows this, or integrate it into Javascript? JSX is nice, sure, but it's a different language altogether, so that doesn't help your point too much.

Regardless of whether or not this is a new language, writing this

```javascript
element.style.set { 
   border-top : 23px solid rgb(0 40 123 0.4);
}

```

would indeed be nice, but having to write

```javascript
element.style.set { 
   border-top: [" ": 23px, "solid", ["rgb": 0,40, ["/": 123,0.4] ] ];
}

```

defeats the whole purpose of making CSS integrate into JS better. If this type of expression only happens under the hood, then I never have to know about it (just like I can use JSX without knowing what they are internally represented as).

I think overall it's best to either make this in a new language (so not make it native JS) or to use template literals for this purpose, like so

```javascript
element.style.set `
   border-top : 23px solid rgb(0 40 123 0.4);
`

```

(and the fact that that's not being syntax highlighted is a different problem, but that has nothing to do with whether or not it's part of the language).

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [March 8, 2021, 2:50pm UTC](https://es.discourse.group/t/making-javascript-more-css-friendly/470/9 "2021-03-08T14:50:04Z")

</div>

There does seem to be a lot of generic language changes required if we tried to make the CSS language valid syntax inside javascript. And a number of new global functions, like `rgb()`, and I would prefer not to pollute the global namespace with even more stuff.

Maybe, such specialized syntax is better suited as a sub-language to javascript. i.e. something like this:

```javascript
element.style.set = css {
  border-top: 23px solid rgb(0 40 123 40%);
}

```

i.e. I'm tagging this object literal with "css" before it, to allow special CSS syntax inside of it.

...but, I would be perfectly happy if we just came out with a standard tagged template to parse CSS. If it was standardized, then editors could provide syntax support because they know what the "css" tag means, different css-in-js libraries could use it in different ways, and the language could provide some standard support for it too.

It would make it easier to inject variables into this syntax too. There's a lot of edge cases you have to think about with this new CSS Syntax idea, like variable interpolation, that's already solved with tagged template literals.

I almost wonder if JSX would have never existed if tagged template literals existed when they were designing React.

---

<div class="post-metadata">

**Author:** ![c-smile](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/c-smile/32/226_2.png) [@c-smile](https://es.discourse.group/u/c-smile)\
**Post date:** [March 8, 2021, 4:00pm UTC](https://es.discourse.group/t/making-javascript-more-css-friendly/470/10 "2021-03-08T16:00:06Z")

</div>

> [@vrugtehagel](#):
>
> JSX is nice, sure, but it's a different language altogether,

JSX is not a different language strictly speaking. It is just another format of literals that enables description of hierarchical structures disregarding of what it is - HTML, XML or whatever, so this:

```javascript
let a = <a href="foo">bar</a>;  

```

is just this:

```javascript
let a = JSX("a", {href:"foo"}, ["bar"]);  

```

where JSX is an arbitrary function that can be defined in user code.

In the same way JS object literals `var a = {foo:1, bar:2}` are actually translated (roughly) into calls like this

```javascript
   var s = OBJ("foo",1,"bar",2);

```

We all use object literals in JS even they have distinct grammar from the rest of JS.

Example from my Sciter.JS where [JSX is built into JS](https://github.com/c-smile/quickjspp/blob/35f5a29d9a2bc3dca26ff5c2df6beda6e0e98567/quickjs-jsx.h) compiler natively. Here [JSX function is defined for Mithril](https://github.com/c-smile/sciter-js-sdk/blob/de1ebd34fe20a268c6df0a93a56a400eaf8a9c5f/samples/mithril/JSX/mithril%2Bjsx.htm) and [here for PReact](https://github.com/c-smile/sciter-js-sdk/blob/de1ebd34fe20a268c6df0a93a56a400eaf8a9c5f/samples/preact/hello-world-jsx.html#L9)

Nothing in JS syntax and grammar prevents adding space as a list joiner operator at least in object and array literals so this:

```javascript
var b = {
   foo: 12 rgb(0,0,0) solid
} 

```

to be compiled into:

```javascript
var b = {
   foo: [12, rgb(0,0,0), solid]
} 

```

Same thing with `;` as separators in object/array literals - they can be used as `,` there so this can be valid object literal declaration:

```javascript
var b = {
   foo: 12;
   bar: rgb(0,0,0);
} 

```

---

<div class="post-metadata">

**Author:** ![jithujoshyjy](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jithujoshyjy/32/399_2.png) [@jithujoshyjy](https://es.discourse.group/u/jithujoshyjy)\
**Post date:** [March 8, 2021, 5:02pm UTC](https://es.discourse.group/t/making-javascript-more-css-friendly/470/11 "2021-03-08T17:02:45Z")

</div>

In some browsers there's already a CSS object attached to the window object. I don't actually recommend using it mainly because the browser support is really poor.  
I'm not sure about it's capabilities. It's definitely part of CSS Houdini. I couldn't find much about it in the web. Might be worth checking out.  
[Houdini Draft](https://drafts.css-houdini.org/)  
These discussions should be done there!
