The Complete Guide to JSS Syntax and Selector Rules

JSS is a JavaScript library that allows you to create objects that follow a CSS-like syntax for styling components. More technically, from the JSS docs, JSS lets you “use JavaScript to describe styles in a declarative, conflict-free and reusable way”.

Many JavaScript libraries make use of JSS (also known as CSS-In-JS). As a React developer, I use it daily in place of regular CSS. Attempting to properly style and customize Material-UI components has also encouraged my use of JSS.

In fact, working with disabled or hovered Material-UI components is what pushed me to write this article: even armed with knowledge of CSS syntax, it can be hard to get the selectors correct with JSS.

In this article, I will give a few examples of selecting pseudo-classes and child elements with JSS. In my blog, I use JSS in almost every Material-UI article. See how to override TextField border when disabled and custom style MUI Chips as examples. Here is the CodeSandbox for the below examples.

JSS Syntax vs CSS Syntax

The following points are four significant differences between JSS and CSS.

  • JSS uses camel-case instead of dashes (i.e. fontWeight instead of font-weight)
  • There is no ‘.’ in front of class names (i.e. buyButton instead of .buyButton)
  • Imports and other variables are fine. Remember, this is JavaScript
  • Other JavaScript syntax is fine (i.e. object destructuring)

Remember that when writing JSS, you are creating a JavaScript object. Therefore, all normal JavaScript Syntax applies.

JSS Selector for :hover Pseudo-Class

Let’s add a :hover selector to a button. The elements are below (using JSX).

<form>
<button className={classes.buyButton}>
Click Me!
</button>
</form>

And here is the JSS:

buyButton: {
backgroundColor: 'blue',
width: 200,
height: 80,
borderRadius: 4,
fontSize: 24,
'&:hover': {
border: '4px solid red',
cursor: 'pointer'
}
}

Notice the & has no space after it. This makes sense because we are not selecting a hovered child of buyButton.

JSS Selector for Two Pseudo-Classes

This time let’s resize a checked and disabled checkbox. The JSX:

<div>
<input
className={classes.personChecker}
type='checkbox'
id='person1'
name='person1'
value='Person'
checked={true}
disabled={true}
/>
<label for='person1'> I am a person</label>
</div>

And the JSS:

personChecker: {
'&:checked:disabled': {
width: 20,
height: 20
}
}

Notice once again that there are no spaces. There is also only one ‘&’.

Nested Pseudo-Class JSX

Here is an example of what the code would look like for a nested pseudo-class selector. This one is not in the CodeSandbox.

buyButton: {
  '&:hover': {
    backgroundColor: 'blue',
    '&:before: {
      textDecoration: 'bold',
    }
  }
}

This nested pseudo-selector allows some styles to be applied on hover (backgroundColor in this case) with separate styling applied on both :hover and :before.

Interestingly, the pseudo-element selector syntax can be either &:before or &::before – either one or two colons. The result is the same either way. This only applies to pseudo-elements. It does not work for the hover pseudo-class.

Child Selector JSX

Let’s select all span elements that are children of form elements. JSX:

<form className={classes.form}>
<span>Child span</span>
<span>Another child span</span>
</form>

JSS:

form: {
"& span": {
backgroundColor: "red",
margin: 4
}
}

As a reminder, notice the space between the & and the span selector. JSS follows the CSS rule of a space indicating a parent-child relationship.

Resources

Are you a JavaScript expert? Test yourself against these 50 challenging JavaScript questions.

If you are using Material-UI, there are quite a few JSS plugins that can be enabled so that your code looks exactly how you want it to.

Here are three ways to create media queries in JSS.

Share this post:

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.