(upbeat music)
- Hey everyone, my name is Aditya
and I'm a developer advocate at Salesforce.
And this quick take, we are going to see
how you can use public properties
to style lighting web components.
In other words, we are going to see the best way
in which you can access the value of a JavaScript property
in your CSS files.
Let dive in.
Let's use this use case, you want to build a component
and you want certain elements of the component
like the text color or border color to be customizable
by an admin using AppsBuilder.
So here, when I changed the color from black to red,
notice how the text color of this element
and the border color of this element get updated.
So how would you achieve this result?
Let's look at the code.
Here is my HTML file with two divs.
One with the class called my class
and the other with my other class.
And I've used CSS to style them, one with the color
and the other one with the border color properties.
Now to update this styles from AppsBuilder,
first, I need to create a public property
which I do by using the API decorator.
And then I use the meta file to expose these properties
to the AppsBuilder.
Now, in order to style my competent based on this value,
one option is of course to use JavaScript,
to query for the individual elements
and then apply the style using dot style dot style name.
Here it can be color, border color, or anything else.
And I use this to assign the JavaScript property value
to that element, while this works,
it's not the most efficient way to do this.
First, manipulating styles using JavaScript is slower.
And second, in case you have more elements in the future
that you want to apply the same style tool,
you would have to query all those elements as well
using JavaScript, making your code unnecessarily bulky,
and of course slower.
The answer to this problem is to use CSS custom properties,
which are nothing but variables in your CSS files.
So you can create a custom property in your CSS file
just use double hyphen and then give
the name of your property.
So here in this example,
I have created my color custom property.
Now to use the value of my custom property,
I use the var keyword.
Here both my class and my other class
use the same custom property value.
One important thing to remember about CSS custom properties
is their values are inherited, meaning that whenever
an element is trying to get the of a custom property
using the var keyword, the value is available
to the element only if that element,
or one of its parent has defined its value.
Let's look at an example to understand this better.
So here I have defined the value of the custom property
using the lightning card selector.
Now, when my class is trying to access the properties value,
it is going to traverse it parents until it finds a value.
So the next parent for my class is container,
and container hasn't defined a property value.
So it goes further up to lightning card,
at which point it finds the value for the property,
which is red, so it uses red.
Same as the case with my other class.
Now, let me change this example a little bit.
Instead of lightning card defining the property value,
I'm going to define the property value
using the container selector.
So this time when my class is trying to access
the properties value, it goes to its parent,
which is container, and obviously container
has defined the value, so it takes the value of red.
But when it comes to my other class, you'll notice
that my other class doesn't have a property value.
So it tries to check the value from its parent,
which is lightning card, and lightning card
also hasn't defined a value to that property.
So in my other class, the properties value is undefined,
which is why the color is going to be black.
It's not going to get the value of the custom property.
And that is how inheritance works.
One other thing to remember about CSS custom properties
is that they can penetrate to shadow boundaries.
And we are going to discuss this a little bit later,
but for now with the knowledge that we have,
let's update our component to use these custom properties.
Here, like I've shown you in the example,
I declared one custom property to hold the color value
and I'm assigning the value at the lightning card level,
because of course I want all the elements in the card
to make use of this value.
And in the CSS classes I'm going to replace
the hard-coded values with the var keyword,
and I use the value of the custom property.
Now the next step is to assign
the JavaScript properties value to the CSS custom property.
You will do that using JavaScript itself,
but instead of selecting every element
when applying the style, you want to just select the element
at which level you want to declare the properties value.
Here, I'm going to select lightning card,
because like I mentioned before, I want my property value
to be applicable to all the elements inside it.
So I decided I have to apply the properties value
at lightning card, and then I use dot style.
This time I'm going to use a set property method,
and I'm going to use this to give the property name
and assign the property of value.
This way, you're assigning the JavaScript property value
to a CSS custom property.
And in case you need to style other elements in the future,
all you need to do is just create new CSS classes
and use a property value which means you don't have to worry
about creating all the elements using JavaScript.
And now remember, I was mentioning earlier
that CSS custom properties can penetrate
through shadow boundary.
Which means the value of the CSS custom properties
defined on the parent can also be accessed
from a child component.
You would use this concept to style your base components.
To style based components, we've created styling hooks,
which is just a fancy name for the CSS custom properties
that we have used inside the base components.
As mentioned earlier, CSS custom properties
can propagate through shadow boundary.
That means, based components can pick up and use the values
of the CSS custom properties from the parent.
In this example, I have a div with a class, my badge
and I need to change the background color
of the lightning badges that are present inside this div.
And lightning badge internally uses some custom properties,
and you'll find a list of all of those properties
under styling hooks for that property.
Here, the styling hook for background color
is SDSC badge color background.
Now, in my component, if I assign a value to this property
it would propagate through the shadow boundary
and lightening badge can use that value.
Because for all practical purposes, my component
is the parent component for any base component that I use.
So now that I Theoretically know that I'll have
to just assign a value to this custom property
in my component, next, I need to figure out
where and how do I assign this value.
For the where part, I can assign the property value
using the my badge selector, because I want only the badges
inside this div to use my custom color.
For the how part, one option of course,
like I mentioned before you can use JavaScript query
for the my badge class and use a set property method.
But why would I write additional JavaScript
to set the same color to another custom property?
I can do this using CSS itself.
So back in my CSS file, under the my badge selector,
I assigned the value of my custom property
to the styling hook.
Let me now deploy all of these changes,
and once the deployment is successful,
and I'm going to refresh the page
to check if my competent works as desired.
So let me change the color from red to green.
and there you go, the text color has changed to green,
the border color has changed to green
and the lightning badge back is also now green.
So it works, and I know this may be a little bit confusing
but feel free to re-watch this quick take
for a better understanding.
Also check out the GitHub Gists,
that I linked in the description,
for the code samples that you have seen today.
Thank you for watching.
If you've learned something, be sure to like this video,
if you want to get more content like this
pushed directly to you, click subscribe
and click that bell icon to get notifications.