When it comes to styling components, it helps to know your options. Read on to learn what will—and what won't—work for you.
Recently, I wanted to apply a border style to the rating component that we built in Kendo UI Builder in an earlier blog post. I added the border CSS instructions in "View Styles" (available in properties panel) but it didn't work.
For example, simply adding the style below had no effect:
.kbc-rating-container {
border
:
1px
solid
black
;
}
In this blog post, we will learn why it did not work and what your options are when it comes to styling your components.
Why Didn't Adding this Style Work?
To understand this, we need to study how view styles work. For this, we will create a blank view with an HTML component containing the following:
<
div
class
=
"test-class"
>Custom HTML Component</
div
>
And in View Styles, we enter:
.test-class {
color
: chartreuse; }
When this view renders, we get something like this:
Now, let’s inspect the HTML component in Chrome's developer tools. We see:
<
div
_ngcontent-c5
=
""
class
=
"test-class"
>Custom HTML Component</
div
>
And in the styles window we see our test-class CSS was generated as:
.test-class[_ngcontent-c
5
] {
color
: chartreuse;
}
This CSS syntax simply means “apply color chartreuse to any element that has both test-class and _ngcontent-c5 attribute.” Using a unique generated attribute enables scoping styles to a specific view and thus avoids collisions with other views. You can read more on this here.
Now back to our problem: when we inspect the DOM of a blank view containing the rating component, we have:
<
div
_ngcontent-c6
=
""
class
=
"kbc-rating-container"
>
and
.kbc-rating-container[_ngcontent-c5] {
border: 1px solid black;
}
We see that the div container for the rating component has a different attribute (_ngcontent-c6). As a consequence, our border style does not apply.
In summary, the reason why a CSS rule in View Style does not work is that the CSS rule is scoped to the view elements and not its descendants. A custom component is a descendant.
How Will We Fix This?
We have several options:
Option 1: Adding the CSS definitions in the CSS file of the Angular component. For example, rating.component.css (this is the file you can find here)
The style will be applied to all component instances on all views. This can be a pro or con depending on your use case.
Option 2: If you need a style that is view specific, you can use the “View Styles” but you will have to use some special syntax to indicate that you want to target the view components as well as all descendants.
This is achieved with the keywords “:host ::ng-deep”. For more details, please read this explanation.
So, to apply a border to our component, we would use:
:host ::ng-deep .kbc-rating-container {
border
:
1px
solid
black
;
}
Note that if you use ng-deep without host:
::ng-deep .kbc-rating-container {
border
:
1px
solid
black
;
}
We get the following generated style:
<
style
>
border: 1px solid black;
}
</
style
>
Option 3: In our custom component, we can implement the most commonly used styles as separate properties. And for all other CSS styles we can define "Additional CSS" as a string property.
The advantages with this option are that:
- It makes your component easier to configure (I call that a no-code feature)
- It makes the component more framework agnostic as the user does not have to use framework specific techniques
- You can have unique styles in different views
- You can have unique styles for separate component instances within the same view
It's about Picking the Right Options
When it comes to styling you have many options. Hopefully this blog will make it easier for you to understand your options, and help you select the one that's most appropriate to your use case.
Thierry Ciot
Thierry Ciot is a Software Architect on the Corticon Business Rule Management System. Ciot has gained broad experience in the development of products ranging from development tools to production monitoring systems. He is now focusing on bringing Business Rule Management to Javascript and in particular to the serverless world where Corticon will shine. He holds two patents in the memory management space.