Style your frontend with an engineering flavour by using JSS
Tags: engineeringmonday, javascript, css, react
Published: 2021-05-10 09:19:20

Choosing between numerous options for styling your app could be a project in and of itself. 🤯

I've tried several styling solutions and approaches on frontend like:
* Vanilla CSS
* CSS extensions like [Sass](https://sass-lang.com/) or [Less](https://lesscss.org/)
* [CSS modules](https://github.com/css-modules/css-modules) (and Sass)

Projects which used them were written either with Vanilla JS or with some modern JavaScript frameworks like AngularJS, Angular 4, React ⚛️ or even React Native.

After all I have a huge favourite regarding styling options world which is not mentioned above. I would vote for it on new project anytime (sorry, there are local elections 🗳️ soon here in Croatia).

To finally get closer to the point, I like to write my styles just as rest of the app. In JavaScript. Which means I use the same programming language and the same syntax both for logic and for styles. This is really cool, but it's not the main motive behind it. It's because I find JavaScript much more powerful 💪 and capable than CSS. 

JavaScript brings more of the engineering flavour into the app styling process. And it's possible with [CSS-in-JS](https://cssinjs.org/) solutions, or shorter JSS.

I used JSS for the first time while I was working on projects built with Material UI. In their [docs](https://material-ui.com/styles/basics/#why-use-material-uis-styling-solution), you can find out why they use such approach after abandoning Less and custom solution inline-styles. Actually they did some [pretty interesting comparison 📊 when choosing styling solution](https://github.com/oliviertassinari/a-journey-toward-better-style).

I've mentioned engineering flavour so let's show some examples of what I thought.

##Variables
You can simply keep any style in a variable.
```js
const COLOR_PRIMARY = "black";
const COLOR_SECONDARY = "#f0f0f0";
```

Also group them into a JS object.
```js
baseTitle: {
    fontSize: 24,
    fontWeight: 600,
    color: COLOR_PRIMARY
}
```

You could think now: nothing special, I can do that with extended CSS too. Be patient... 😃 

##Spreading, default properties and overriding
Let's say we want to extend this basic title for some other use.
```js
sectionTitle:  {
  ...baseTitle,
  //override font weight from base title
  fontWeight: 800, 
  //extend base title
  fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
  fontStyle: 'italic',
}
```

> Notice that you don't need to learn any new syntax, you actually write CSS but you just use `camelCase` instead of the `kebab-case`: `font-size` ➡️ `fontSize`. And have JS power on top of it.

##Themes
Then, you could also keep all your **reusable** styles in one place and build your whole theme - which is simply JS object. 

```js
const theme = {
  backgroundColor: COLOR_PRIMARY,
  color: COLOR_SECONDARY,
  ...
};
```

That theme could be considered a config file but for styles 💅. Use [Material UI theme](https://material-ui.com/customization/default-theme/#explore) for inspiration. From breakpoints, typography to colour palette and spacings.

##Integrate JSS with React
There is a [JSS Core](https://cssinjs.org/jss-api) library which can be used in any Javascript app, but React developers will be more interested in [React-JSS](https://cssinjs.org/react-jss). 

###Dynamic Values
Give attention to [Dynamic values](https://cssinjs.org/react-jss#dynamic-values) . 

JSS uses Hooks API where you can use hooks like `createUseStyles`. 

There is a cool example I will borrow from JSS docs about how to start with it. I will just separate a style from components, because it is always a good practice not to make a big clutter in one file. Also, it reminds of the CSS modules approach which have a separate isolated style for each component.

`useButtonStyles.js`
```js
import { createUseStyles } from 'react-jss'

export const useButtonStyles = createUseStyles({
  myButton: {
    padding: props => props.spacing
  },
  myLabel: props => ({
    display: 'block',
    color: props.labelColor,
    fontWeight: props.fontWeight,
    fontStyle: props.fontStyle
  })
})
```

Notice how elegantly you can change the style depending on props values passed from the component.

`index.js`
```js
import React from 'react'
import { useButtonStyles } from "./useButtonStyles";

const Button = ({children, ...props}) => {
  const classes = useButtonStyles(props)
  return (
    <button className={classes.myButton}>
      <span className={classes.myLabel}>{children}</span>
    </button>
  )
}

Button.defaultProps = {
  spacing: 10,
  fontWeight: 'bold',
  labelColor: 'red'
}

const App = () => <Button fontStyle="italic">Submit</Button>
```

Feel free to play with [example on CodeSandbox](https://codesandbox.io/s/react-jss-dynamic-values-example-devto-7cisu?file=/index.js).

###Theming
Besides hook for creating style there is the `useTheme` combined with a `ThemeProvider` wrapper. It also provides a [theming solution](https://cssinjs.org/react-jss/#theming) which makes it a lot easier to start writing themed apps with reusable styles, and to quick start your new project.

##Would you give it a try?
❓ What are you thoughts? 
❓ Which styling solution do you prefer?
❓ How do you deal with theming and reusable styles?