How to define CSS API

Make css customisation fun again with style-hooks.

We build building–blocks to build the web. When you build a collection of distributable components you should (must) probably define the component API and write the documentation to share with the components consumer. We have a lot of ways to do that in 2018, but what about CSS? While Javascript is the most growing language, CSS is still the best — and only — way to handle and define component style, even if you write it inside the js, you will get CSS and no one can save you from learn it!

With the latest CSS specifications, we can use a lot of awesome features to handle our styles, behaviors and responsive things. Say Hello! to CSS Custom Properties and CSS API.

Define the element

Let’s start defining our html component with a simple attribute binding.

<progress my-progress value="50" max="100"></progress>

You can also use classes to bind the element to the CSS

Now let’s add some style to our element following the native css nesting syntax:

Now we have a fancy progress bar using the native html element, but how can we allow customisations and handle the style without make consumers entering in a mess of classes and specificity issues?

Custom properties and API

We can define at this point a bunch of Custom Properties and let consumers know how they can customise our component without facing issues and integrate it with their custom classes.

Let’s pick our previous CSS example and then add some custom properties. We have to define properties that you want to be customisable/accessible from the ”outside” and convert them into custom properties.

Now we have a beautiful way to customise our element without worrying about classes and conflicting css scopes, but we forgot something…

What about decoupling internal custom properties from the public ones?

Right now we have coupled css properties on which consumers can directly work. This is not a good move if you want to extend/refactor your component without making breaking changes everytime, or, if you don’t want consumers know about what you are using inside. Another issue with this example is the lack of custom properties fallbacks.

So, we can do better and improve our code…continue reading: