A few basics about Hacss

All professional web developers are familiar with inline styles. Most developers restrict their use to trivial prototyping exercises due to functional limitations or belief in a separation of concerns between markup and presentation styles. On the other hand, newer architectures such as atomic CSS and CSS-in-JS demonstrate that some developers prefer colocation of markup and related style information.

Like these approaches, Hacss facilitates the colocation of markup and styles. It combines the strongest features of atomic CSS and CSS-in-JS while minimizing the downsides of each approach.


Hacss works by embedding CSS syntax within ordinary HTML classes. While these self-describing class names are meaningless to the browser, Hacss analyzes them at build time and generates a style sheet that contains the corresponding "actual" CSS. For example, the class name color:red; results in the style sheet .color\:red\;{color:red;}

Hacss can find your style rule classes within HTML templates, JavaScript modules, or other code files that render HTML: It is essentially language-agnostic. You'll just need to provide Hacss with the location of these source files.


Versus inline styles

CSS-in-HTML enhances the development experience of inline styles with additional capabilities that normally require external style sheets:

  • selectors
  • variables (named constants)
  • media queries

Furthermore, CSS-in-HTML may be faster than native inline styles.

Versus CSS-in-JS

CSS-in-HTML works without JavaScript (except at build time) and imposes fewer constraints upon your architecture by supporting a wide array of HTML templating languages, compile-to-JS languages, and application frameworks.

Because all the work is done at build time, CSS-in-HTML also offers better performance.

Versus atomic CSS

With a familiar syntax that translates directly to CSS, the CSS-in-HTML approach provides significant advantages over atomic CSS.

First, the learning curve is greatly reduced because, unlike atomic CSS frameworks, there is no system of utility class names to learn. Instead, the class names mostly consist of the underlying CSS that one would write anyway.

Perhaps more importantly, CSS-in-HTML is flexible in a way that no set of predefined classes can match. Hacss makes it possible to use advanced selectors where atomic CSS frameworks are typically limited to basic pseudo-classes like :hover and :focus. It also allows variables to be interpolated into style rules, which can address "edge-case" scenarios, e.g. left:calc(50%+#{$spacing4});


While CSS-in-HTML introduces fewer constraints than other approaches, some basic rules apply.


Whitespace cannot be used within a style rule because it is used to delimit HTML classes. The browser would simply not apply the intended style rule if it were allowed to contain spaces.

When spaces are strictly required (which is actually not often), double underscores may be used in declaration values, e.g. box-shadow:0__0__0__1px__black;

Dynamic class names

Style rules cannot be constructed dynamically using string concatenation, template literals, or otherwise. They must appear in the code as string literals in order to be detected and processed correctly.

Hacss provides its own syntax for variables and basic interpolation, and selectors can be used to apply styles conditionally. When these options are insufficient (such as when styling the width of an element as calculated in JavaScript), a native inline style is a reasonable solution and usually does not introduce any unintended side effects despite its high specificity.