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.