Write CSS in JS with glamorous

Kent C. Dodds
InstructorKent C. Dodds
Share this video with your friends

Social Share Links

Send Tweet

There are a few things you may be used to doing in CSS that you’ll need to learn how to accomplish using CSS in JS (in particular with glamor and glamorous). In this lesson we’ll go through a few examples.

Instructor: [00:00] Here, we're doing a basic styling of a class. We're using that class name in this div. That's rendering our raw CSS example there. To do this in glamorous, we'll add a glamorous example. For us, we're going to say glamorous.div. I'm going to copy this right into here. We'll change this to be a quoted string. We get the exact same result.

[00:27] To do pseudo-classes, you do something similar. We'll copy and paste this here. What we're going to do is I'll cut this out. We'll make a new object. We'll have a key in this object with hover. Then the property for that key is going to be the CSS we want applied when the hover state is active. If we hover over that, it works exactly the same.

[00:52] Ultimately, this is using actual, real CSS that is generating at run time rather that doing some sort of JavaScript hack to make this work. It's actual CSS. Cool. Let's go ahead and talk about applying multiple styles to an element. In this case, we have a class name that is taking two styles from this CSS. I'll paste this in here. We'll get rid of this styling here.

[01:18] With glamorous, you can pass as many arguments as you want here. Then they will be merged together. We can create two objects here, one for each group of styles. For our first, it's going to be color orange and fontSize is 10. For the second one, that's going to be color is blue and backgroundColor is going to be lightgray. With that, we get the exact same rendering here.

[01:48] There's going to be one slight difference here, and that is what we can do with glamorous is I can swap the order of these. With glamorous, the way that things are merging is the first one has less priority than the second one, and so on and so forth. It works similar to Object.assign, except it's doing a deep merge for us.

[02:09] What's cool about this is I can very explicitly say what order I want these to take precedence in, which I can't really do with className. If I swap those, I'm actually not going to get that same experience.

[02:25] You have to do a couple of extra things to worry about specificity, whereas with glamorous and glamor, you don't need to worry about specificity. It just works the way that you would expect it to. We'll move that back there, so they're the same.

[02:39] Now let's talk about child selectors. Sometimes you do need to have some sort of like, "When the parent is hovered, then I wanna apply these styles to this thing, and so how do we do this with glamorous?" Let's go ahead, and we'll copy this over. I'll make that a glamorous example.

[02:58] In this case, I need to apply some CSS to this div. That CSS is going to be this. I could create a glamorous div and then render that glamorous div, but, instead, what I'm going to do is swap out this div for a glamorous div. I'm importing that here from glamorous. With the glamorous div imported, we can render a capital div -- that's our glamorous div.

[03:26] With all glamorous components, you can use a CSS prop. This takes an object, or an array, or a function and allows us to do the same thing we would do as if we said glamorous.div. It accepts the same thing that we put inside of a glamorous component factory. With this CSS prop, now we can start styling things.

[03:49] I'll get rid of this. I'm going to say my display is block. Now we need to do something about styling these subcomponents. Let's say we don't want to change the class names. Maybe they're coming from a third party or something. We can take those styles, and actually use it inside of our div, and reference those child class names as child selectors.

[04:14] The way that we reference the class name that's going to be generated by this div is by using the ampersand sign. Now we can say .ex4-0From there, we can say the fontWeight is bold. Then we'll do the same thing with an ampersand and .ex4-1. That's going to have a color of blue.

[04:42] This is a little bit of a special case, so we'll say &:hover .ex4-2. In that case, we're going to have the color red, so we'll say color of red. Now we have exactly the same functionality that we had before.

[05:01] Normally, you want to avoid doing this kind of thing where we're referencing class names because it breaks out of the encapsulation that you get out of CSS and JS, but occasionally it's really useful, especially with the hover state that we have in this example.

[05:16] In this case, we want to style this item based off of a parent selector. If the parent has the class no-js, then we're going to give it the color of gray. If it doesn't have that class, then it's not going to get that color. Let's go ahead and copy this. I'm going to make this a glamorous example. I'm going to use the built-in glamorous component and the CSS prop that takes an object.

[05:42] As we learned in the previous one here where the ampersand references the class name that glamor is going to generate for us, that works exactly the same way. We're going to say .no-js &, and that says, "Insert the class name you generate here." Then I'll give it an object for a color of gray.

[06:05] With that, I'm getting the exact same experience. If I remove that no-js class name from the root div, then I don't have those styles applied. Again, this is all just regular CSS being generated for us by glamor.

[06:20] Next, let's talk about media queries. I'm going to go ahead, and we'll say gex.push(glamorous.div). In this case, we want to have the color be this red color. Then we're going to use the media query as the key for a property in our object and provide the CSS that we want to have applied in that scenario.

[06:45] I'm going to go ahead and copy this really quick. We'll change this to the camel case. We'll put that inside of a string, as well as this. We're going to get that same experience.

[06:59] One thing that I really like about this is that it actually allows us to extract our queries to objects, like we're doing here. We can use this object literal syntax here where we can reference the queries.phone. Then we can share those media queries throughout our application. All of that is really explicit.

[07:20] Let's go ahead and talk about fallbacks. Here we have this display block. If flex is available, we'll display this flex. In my case, I am using a browser that supports flexbox, and so that's working for me. Let's go ahead and do this using glamorous. We'll add this to our glamorous examples.

[07:37] Instead of a regular div, I'm going to use the glamorous div that I'm importing up at the top here. Instead of a class name, I'm going to reference the CSS prop. We're styling the display property, so we'll say display flex as our default situation here. I'm going to turn this into an array. We'll say, "Hey, we want it to display as block, but if flex is available, let's have it display as flex."

[08:05] We can see this working. If I switch this to fall back to block, then that's going to fall back to block for us, but we want the fall back to be flex, so we'll leave it at that.