//

INTEROPERABLE CSS

Interoperable CSS or ICSS is a low-level file format that enables CSS Modules, designed for loader implementers (not for end users).

Why Interoperable CSS?

Even though JavaScript has evolved into building workflows to produce reusable components with scoped modules, CSS has remained conventional.

ICSS is for compilers, not for human authoring

ICSS is compiled fom CSS Modules. Each file is compiled separately then linked in the loader.

JavaScipt used to be global before the introduction of CommonJS. With require and module.exports, a proper system of dependenices and proper local scoping was introduced. ICSS is designed to achive the same goal.

:export

Exporting symbols from a file to another CSS or JS file is done by using the :export pseudoselector block.

:export {
  Page: _page_page_afd97dfs867;
  Header: _page_header_85fd867fsfg;
  Footer: _page_footer_97fd867fsfg;
}
._page_page_afd85dfs867 { /* page styles */ }
._page_header_85fd867fsfg { /* header styles */ }
._page_footer_97fd867fsfg { /* footer styles */ }

The symbols are imported as a simple JS object

import styles from './page.css';
/*
 styles: {
   Page: "_page_page_afd85dfs867",
   Header: "_page_header_85fd867fsfg",
   Footer: "_page_footer_97fd867fsfg"
 }
 */

CSS Modules generate globally unique class names using :export and provide them to JS.

:import

The :import pseudoselector just like CommonJS import, defines which symbols it needs to import.

:import("./page.css") {
  i__page_class_1: Header;
  i__page_class_2: Footer;
  I__page_var_1: SharedPageVar;
}

The loader will determine the path looking at the argument given to it, fetches the file and links it to the current.

In the body of the import statement, is the local temporary aliases and the exported symbols from the dependency, which matches up to the :export block of page.css.

:export {
  Header: _page_header_85fd867fsfg;
  Footer: _page_footer_97fd867fsfg;
  SharedPageVar: #FFFFFF;
}

In the above example, we are exporting class name as Header, and Footer.

When an ICSS file is loaded and linked, the symbols gets passed with the :import block is deleted.

:import("./page.css") {
  i__page_class_1: Header;
  i__page_class_2: Footer;
  i__page_var_1: SharedPageVar;
}

:export {
  Page: _page_page_afd85dfs867;
}

_page_page_afd85dfs867 {
  color: i__page_var_1;
}

After the :import is processed against the :export block:

:export {
  Page: _page_page_afd85dfs867;
}

_page_page_afd85dfs867 {
  color: i__page_var_1;
}

When this processed file is imported, it becomes a JavaScript object, and the loader will inject it inot the DOM.

Conclusion

The difference between CSS Modules and ICSS is that the latter is not opiniated. There is an Interoperable CSS Standard which is designed towards making CSS a multi-file language, just like what CommonJS did with JavaScript.