Scoping CSS in Angular

I’m refreshing my SmallBizDevOps brochure site with a static site written in Angular. I currently have a need to generate an interactive component that looks like an old computer. I found a CSS framework that looks like it will fit the bill called TuiCSS, but I’m currently using Material design for Angular as my main framework of choice. I want to be able to use TuiCSS for my interactive component, but not apply all the base styles over top of what Angular’s Material framework is doing for me. To do this we’ll have to use Angular’s view encapsulation features to write TuiCSS to one component only.

I started to solve this problem by just getting TuiCSS components and classes to load. This involved loading the distribution stylesheets globally from the tuicss node module. I did this by pulling it into the styles array in my angular.json file. Adding in the javascript distribution file to the scripts array in my angular.json file got the tabs working as I expected from this demo. Everything was going great until I scrolled down past my interactive component and saw that my flexbox layout had been reverted back to a single-column layout instead of a two-column layout. Back to the drawing board.

Next, I looked into just importing the style into the component directly. I started by breaking out my styles array into a separate scss file and importing it via a styleUrls array. Then, I added the distribution file to the styleUrls array of my component and removed the import from the angular.json file. Finally, I looked at Angular’s documentation for scoping css and other methods to single components and found the ViewEncapsulation API. I looked first at the ShadowDOM type of encapsulation and tried that. However, I received an unexpected error when the tabs in my interactive component stopped working. Back, yet again, to the drawing board.

I knew I just wanted the styles from TuiCSS applied solely to my interactive component. So, I took another look at the ViewEncapsulation documentation and found that the default Emulated type of encapsulation would achieve what I wanted by rewriting the CSS imported to the component with greater specificity than the original files. The missing element was the JavaScript, but I didn’t have to scope it just to one component and could leave the script as an import in the angular.json file. I tried it, and voila it worked! I had a fully styled interactive component that looked like an old computer!

The cool thing about ViewEncapsulation is that it enables multiple CSS frameworks to live in harmony along-side each other. I can envision a CSS framework showcase site that automatically encapsulates each showcase element inside it’s own component. That way you could show bootstrap alongside TuiCSS, Material, Foundation, Nes.css, or any other CSS framework without conflicts of base styles!