Until now, we mostly talked about how to create simple components in Angular, like a zippy or a tabs component, and we also covered some isolated parts of the framework like the new dependency injection. In this article we are going to discuss another essential part when it comes to building components: Styling.
A component in Angular is basically a controller class with a template. But as all of us know, a component also needs it’s own styles, especially when it comes to sharing reusable components across applications, which is what we want to achieve in the modern web anyways, right?
We can always write our CSS code in a way, that it is modular and easily extensible at the same time. However, if we don’t rely on technologies like Web Components, our styles all end up concatenated and minified in the head of our HTML document, without our components actually knowing that they exist. This is actually good when we think in separation of concerns, on the other hand, if we build a component and want to share it, it should come packaged with all the needed styles, scoped to that component.
Component inline styles
The easiest way to add styles to a component is taking advantage of the
@Component decorators that allow us to define component inline styles. All we need to do is to add a
styles property to the decorator and define the styles. To see what that looks like, here’s a snippet of our zippy component that we’ve built a while ago.
This is pretty straight forward. You might wonder though, why the value of that property is a list and not just a (multi-line) string. Well, I wonder too. That’s why I asked the question right away.
Okay, so defining styles on the component is pretty clear, but where did those end up in the DOM? If we run this code in our browser, we see that there’s something very interesting happening. It turns out that Angular takes the defined styles, and writes them into the head of the HTML document. Here’s what that looks like:
What’s going on there? The reason why Angular takes our styles and puts them up there, is because of the View Encapsulation that we are using. Since Angular 2.x, it comes with three different view encapsulation types in order to support both, browsers that don’t support Shadow DOM, and also the ones that do support it. The view encapsulations
will be explored in another article are covered in this article, but we have to touch on this though in order to understand why this is happening.
Angular currently uses the
Emulated View Encapsulation by default. Which basically means, there’s no usage of any Shadow DOM at all. One of the nice features of Shadow DOM is style encapsulation. It allows us to scope styles to a specific component without affecting the outer world.
To take advantage of style encapsulation, styles have to be put into the
shadowRoot of a component. Due to the Shadow DOM strategy that is used, there is no
shadowRoot to put our styles into. That’s why Angular writes them into the head. But as mentioned, there’s another article that explains all three view encapsulations.
Let’s take a look at another way of adding styles to our component.
In an ideal world, we don’t have to mix our styles with our application code. That’s why we have the
<link> tag, that allows us to fetch and embed a stylesheet from a server. Angular components allow us to define
styleUrls, so that styles don’t have to be written into the component. Pretty straight forward, here’s an example:
Where do those end up in the DOM? Well, for the same reason as explained earlier, they are written into the head of the document. But not only that, when Angular fetches the style resources, it takes the text response, inlines and appends them after all component inline styles. So if we would have a configuration like this:
my-zippy.component.css content would look like this:
We will end up with a document head that looks something like this:
This also brings us to the next conclusion that styles defined in style urls will always be appended and therefore override styles defined in the component, unless the inline styles don’t have a higher specificity.
Last but not least, we have template inline styles.
Template inline styles
We can for sure always write our styles directly into the DOM, nobody can prevent us from doing that. In fact, when thinking in Web Components it’s quite common to put styles directly into the template of a component, since they will be encapsulated when Shadow DOM is used.
Translating the styles used above to template inline styles would look something like this (in case of our zippy component):
Guess what, also those will be appended in the head of our document, after the ones defined in the component or as style urls. Template inline styles always have the highest priority, which sounds pretty straight forward to me.
Angular Master Class at Shopware
Join our upcoming public training!Get a ticket →
Get updates on new articles and trainings.
Join over 1400 other developers who get our content first.
RxJS Master Class and courseware updates
If you've been following us for a while, you're quite aware that we're always striving to provide up-to-date and high-quality...
Advanced caching with RxJS
When building web applications, performance should always be a top priority. One very efficient way to optimize the performance of...
Custom Overlays with Angular's CDK - Part 2
In this follow-up post we demonstrate how to use Angular's CDK to build a custom overlay that looks and feels...
Custom Overlays with Angular's CDK
The Angular Material CDK provides us with tools to build awesome and high-quality Angular components without adopting the Material Design...
Easy Dialogs with Angular Material
Building modals and dialogs isn't easy - if we do it ourselves. Angular Material comes with a powerful dialog service...
A web animations deep dive with Angular
Angular comes with a built-in animation system that lets us create powerful animations based on the Web Animations API. In...