Category
Software Engineering

Published
Feb 15, 2018

Read
6 min

Tweet
Share
Comment

Syntax Synergy - HTML, CSS, and JavaScript as One Language

Article Purpose

In working on my book Coding for Designers it became clear that there is a fundamental bottleneck that inhibits learning HTML, CSS, and JavaScript. Each language has rigid and conflicting syntactical opinions instead of unified and synergistic ones. What if HTML, CSS, and JavaScript were one language?

What If?

What if each language shared an identical approach for:

  • comments
  • value assignment
  • valid naming rules

What if there was an obvious way to distinguish between:

  • reserved language words
  • reserved environment words
  • custom identifiers

What if each language limited its amount of syntactical exceptions?

What if there was a unified approach to scoping/grouping?

What if certain HTML tags didn't vary between their use of href and src?

What if the target attribute of the HTML anchor tag didn't randomly start with an inconsistent preceding underscore?

What if JavaScript object property assignment matched identifier assignment (= not :)?

What if?

Reality

I am very aware that each of the three languages in question were designed independently and at different times. Additionally, I am very aware that it is difficult to implement non-breaking changes to any pre-existing creation—especially once society, business, and government are heavily reliant. This has prevented certain changes to the languages over time, but this will not keep me from dreaming.

Thought Experiment

The remainder of this article is a thought experiment inspired by the question: what if HTML, CSS, and JavaScript were one language? Other nerds will realize that the psuedo-code below—or a variation of it—could be transpiled in a best-of-both-worlds effort. I will leave such endeavors to others.

Recognition

Prior to revealing the code however, I want to acknowledge one thing. There is undeniable power in the file extension concept. A file's extension informs how its contents are to be interpreted by another program. The characters and the sequence of them could be identical between two files where only their extensions might differ. This is a very powerful idea.

This same idea is currently implemented in web browsers, but additionally through certain HTML tag types (.js : <script> :: .css : <style>). If HTML, CSS, and JavaScript were the same language how would you or a computer program distinguish between structure (HTML), style (CSS), and behavior (JavaScript)? For this reason, I will maintain this traditional idea moving forward.

It is worth noting that I am not the first person to consider this "one language" idea. Though Thomas Styles's approach is different, his alternative approach is explored here.

Code

In the What If? section above I outlined quite a few ideas so let's cut to the chase and view code examples. Let's call the language HCJ with the extension .hcj. Creative I know. Maybe uniscript, webscript, or web-script would be better...

The syntax highlighting below is not ideal as .hcj does not exist. Additionally, I imagine distinguishable colors for reserved language words, reserved environment words, and custom identifiers in any IDE supporting .hcj.

HTML becomes:

/* index.html */

document-type = { 'html' }
html = {
    head = {
        meta = { charset = {'utf-8'} }
        link = { rel={'stylesheet'} type={'text/css'} src={'assets/css/style.css'} }
        title = { 'Coding for Designers' }
    }
    body = {
        division = {
            class = {'dark-background'}
            heading-1 = {
                'This is the Primary Title of the Page'
            }
            paragraph = {
                'This is a paragraph. It is followed by an image and a button.'
            }
            image = { id={'image-to-toggle'} src={'assets/img/cover-coding-for-designers.jpg'} }
            button = {
                on-click={toggle-image-opacity()}
                'Toggle Image Opacity'
            }
        }
        division = {
            class = {'dark-background'}
            heading-2 = {
                'This is a Secondary Title'
            }
            paragraph = {
                'This is another paragraph. It has a ' anchor={ src={'/another-page'} 'hyperlink' }.
            }
        }
        script = { type={'text/javascript'} src={'assets/js/main.js'} }
    }
}

CSS becomes:

/* style.css */


vars = {
    colors = {
        black = {'#000000'}
        white = {'#FFFFFF'}
    }
}

id = {
    image-to-toggle = {
        border = {'2px solid ' colors.black}
    }
}

class = {

    dark-background = {
      background-color = {colors.black}
      color = {colors.white}
    }

    light-text = {
      color = {colors.white}
    }
}

JavaScript becomes:

/* script.js */

function toggle-image-opacity() {

  /* Reference work */
  var image-to-toggle = { document.get-element-by-id('image-to-toggle') }
  var current-opacity = { window.get-computed-style(image-to-toggle).opacity }

  /* Core work */
  if(current-opacity == 1) {
    image-to-toggle.style.opacity = { .5 }
  } else {
    image-to-toggle.style.opacity = { 1 }
  }

}

HCJ

The H

The first thing you will notice is that the HTML is a lot lighter. No more XML-based tags. Instead the {} curly braces are used to define the "scope" or boundary of a given set of code assigned to an identifier (just like CSS and JavaScript). This brings more consistency across all three. Additionally, consistency comes full circle through the use of this pattern sequence:

  1. identifier (lowercase-dash-delimited)
  2. =
  3. { ... } (where ... is the value for the identifier)

Now all three are uniform in assigning identifier values. In HTML we want an identifier to = some value where the { and } set the boundary for the value (again, just like CSS and JavaScript). What's unique to the HTML (first language exception) is that an order is expected within the curlys:

  1. space separated list of additional identifier-value pairs using same syntax
    • Equivalent to HTML element attributes
  2. the actual value of the identifier bound by its curlys
    • The nested element(s) or literal text

Lastly, you'll notice that element identifiers are spelled out completely. When newcomers see an <a> or <p> what are they supposed to think? Explicit and full identifier names remove the guessing (where editor shortcuts can mitigate any "more typing" complaints).

The C

The first thing you'll notice is that there are two namespaced identifiers, one for ids and one for classes. If multiple .css files get loaded these namespaces will be shared and duplicate identifiers will be overridden (nothing new). What is enforced however is that identifiers are now lowercase-dash-delimited (again to enforce consistency). Also, as you may have guessed, there is no more inconsistent : use where = takes its place. Lastly, the { and } scoping approach is identical to the previously introduced HTML.

The J

The first main difference you'll notice is that var and function identifiers take on the same lowercase-dash-delimited naming convention. Also, the { and } for scoping values is leveraged for consistency where . (dot) syntax remains for nested identifier access. Semi-colons are not needed as the scoping curlys determine the start and end. Due to the updated naming convention for identifiers, subtraction's - requires spaces around it (minification would leave the spaces in this instance). Neither an object or array literal is showcased above, but here are examples using many of the same ideas already discussed:

var my-object = {
    a-string = { 'a' } /* string of 'a' */
    an-object = { another-string = { 'aa' } } /* nested object literal */
    an-array = { 1 = 'a', 2 = 'b', 3 = 'c' } /* comma separated list */
}

In quick summary the ideas leveraged are:

  • lowercase-dash-delimited identifier naming
  • curlys for scoping
  • = instead of :
  • nested curlys for nested objects
  • arrays use numbers as identifiers and use {} vs []

Two main changes from traditional JavaScript arrays are:

  1. number identifiers are required when defining an array literal
  2. the first item is at index 1 not 0 (newcomers rejoice)

Conclusion

I will mention again that this experimental language idea is a what if that is informed with the fundamental goal of making HTML, CSS, and JavaScript much more consistent in terms of syntax. Unrealistic or problamatic as you may think this idea is, I firmly believe there are fundamental notions that would be valuable if we, as a web community, had the luxury of designing a more uniform language.