If you have some experience with React, you probably came across styled-components. In the last few years, the concept of css-in-js became more popular, and there are multiple libraries that are available for us to use. styled-components is one of them, but you can also find Emotion, Radium, JSS, and more. In this post I'm not going to cover the pros and cons of traditional stylesheet files vs. styled-components, and instead - I'm going to focus on tagged template literals - the "magic" that let us use the
Let's take the following simple syntax for example:
StyledDivin the example above is actually a React component that returns a
divblock with the css of
color: red; font-weight: bold;.
Well... kind of. Actually - it's a bit more complicated than that. The output of the above is a div with specific css class-names having the above css definitions inside:
Some of you are probably using this without giving it too much of a thought. If we take a closer look we can see the usage of the backtick (
`) right after the
Let's start with
Template Literals, and then move on to the more interesting concept.
As you can see from the example above - expressions can be variables, but are not limited to them:
We can use either variable or function inside a template literal, and the value that will be used is basically the string representation of the expression:
Now that we understand the power of template literals - it's time to move on to tagged template literals - or just tagged templates.
With tagged templates, we have the power to parse the template literal ourselves using our own "home-made" function.
Note that in the example above - the variable
strBcontains the string
String A(and not
String Bas you might expect).
- The function
funcAreturns the string
- By using the function
funcAas a tagged template - we completely ignored the string that was sent, and we just return something else.
- We can use it with an empty string, and the output will be the same.
Check it out:
The function we use in a tagged template can return everything that we want - we are not limited to only return strings:
Building tagged templates have an option to also accept variables that can be used:
The first argument is a special object, which behave as an array and provides access to all the "native strings" in the original string that was passed to the tag-template function (
strings), alongside a
raw property, which allows you to access the original raw strings.
The rest of the arguments are the expressions that we used inside the template literal.
Now that we know a bit more about template literals it's time to move on to some more complex examples.
We already know that template literals don't have to return strings, so how about creating a simple example of a tagged template that returns a react component with the relevant style?
We will start by creating a simple div example to just wrap our text with some styling on it:
The tagged template is the following code:
The full example is available here:
Check out the helper functions (the
cssObjFromStr). we are going to focus on it in the next example.
The basic example gave us a nice intro, but what about the component's props? We use them all the time in React, and losing them is not an option. Moving to the next example, we will add the option to also use props as part of our component that we would like to style:
We will use the
onClick prop on the div element.
The full example is here:
Props are not only relevant to the components, but also to the template itself. We want to use the props of the component inside the template itself - colors, elements behavior, and more.
To do this we will need to pass the props from the
<Div...> to the
But this is not enough.
Let's assume that we use the
<Div> element with the property
The issue we face here is that the
<div> component (inside the
cmp) will get the
textColor property, which is not a valid property of a
A specific solution can be to extract the
textColor from the
props, and pass the rest of the properties down to the
Working example can be found here:
The styled-components solution is a bit more elegant (and much more generic) - all props that start with
$ are considered "private props" and will not pass down to the actual jsx component.
We will use the same concept, but in our example, we will use the _ (underscore) to create private props.
Full working example can be found here:
Cover photo by Gerd Altmann @ pixabay