React VS Vue | How about some style ✨?
Tags: javascript, react, vue
Published: 2021-08-26 02:43:42

Previously, I talked about features offered by both frameworks, and shout out to @fyodorio for asking me to do comparison about both frameworks' approach on CSS. Well, it's gonna be long article, but I hope I can open to possibilities offered by frameworks and later can be used however you see fit.

{% link https://dev.to/alserembani/react-vs-vue-what-about-them-2o %}

I will talk about the beginning, on how people use CSS back then, and later will dive into specifics such as preprocessors and postprocessors, as well as available CSS frameworks. I know most of you love Tailwind, so hold on you cup of drink, and dwell in the history first, shall we?

---

## Inline Styles

In the beginning of times, after 4 years of the existence of HTML, comes the debut of CSS. Although that time, styling is not that great (as we evaluate the styling on current standard), but the debut of CSS brings great change to the web development. To style an element, you only need to add `style` attribute to the element.

```html
<div style="margin: 16px">...</div>
```

Style, in this matter, is the only style available at that time, and it's still available to this day. Element's `style` will always be treated at the top level, since we style it directly to a extremely specific element. Just imagine, there are hundreds, thousands of elements that uses the same style. Crazy right? But our predecessors used to do this, you know!

Well, for React and Vue, both of them are available! Though it differs on how you want to use it, especially when you need dynamic styling for a specific element, you might use `style` attributes.

### React JSX

```jsx
// React
const backgroundColor = "#00d8ff";

<div style={{ backgroundColor }} />
```

> Note that the first curly bracket is to trigger javascript code inside JSX, and the second curly bracket is for object notation.

> Since React is using JSX, anything inside curly bracket should always use camelCase.

### Vue

```vue
<!-- Vue -->
<div :style="{ backgroundColor }" />

<script setup>
const backgroundColor = "#42b883";
</script>
```

These are the respective example for the usage of `style` attribute for both React and Vue. However, we are too lazy to make ourselves repeat the code and read millions of line, so we are gonna escalate this a little bit!

---

## Selectors

We want to avoid repetitive works, so the existence of CSS helps us a lot on splitting the code between HTML and CSS, thus comes the selectors such as elements, classes, ids, siblings, and finally a cursed `!important` 💀

So, in standard HTML, you can use `<style>` tag to handle it for you. As usual, you either use a global one, from element selector, to the most specific selector, the id, and then increasing the specificity by using siblings, data-attributes, and `!important`.

```html
<style>
div {
  background-color: ##35495e;
}
</style>
```

In React, we don't have `<style>` tag, so we cannot do this way.

### Vue
```vue
<template>
  <div>...</div>
</template>

<style>
div {
  background-color: "#42b883";
}
</style>
```

---

## Stylesheet

Cascading StyleSheet (CSS), as the word describes, is a sheet of styles, where we can split the styling totally from the HTML. Quite neat right? So when we want to debug the CSS, we can just open the sheet, without going through HTML codes. Easier to read, easier for bug-hunting. To import the sheet, just use the code below.

```html
<link rel="stylesheet" href="your-css-sheet.css">
```

Since React and Vue both are using Javascript, we instead use Javascript way of importing the sheet. Both have the same implementation.

```javascript
import "/path/to/your-css-sheet.css";
```

...and later just use the class that is declared inside your CSS files. Neat!

However, heed this advice. Until this point, if you use general selectors, and import your CSS that the global level, that means all element, includes the children of the component will have the same styles. There are some case, you need the specificity, so you make a class e.g. `.Header__wrapper__link`. Imagine how specific you want to make it, but there are a better war for both React and Vue. Read more below!

---

## Modules and scopes

This is where some concerns arises. As I talked before, there are some use cases, where we need to specifically target a specific component, without affecting other components, including the children component. This is where modules and scopes comes in.

> Modules and scopes are only available for javascript, and not vanilla HTML.

Usually, we have a file called `your-style.css`. Do you know that you can actually modularise your CSS by just changing from `.css` to `.module.css`? Let me explain how it works.

Assume that this is your `your-style.css` sheet.

```css
.blog {
  background-color: #00000011;
}
```

> Note: In `.module.css`, it is not allowed to use element selector at the base of selector. As example, `div > .blog` is not allowed, but `.blog > div` is allowed.

After compile, when you inspect your element in your browser, you will see the element this way.

```html
<div class="blog">...</div>
```

However, if you convert it to `your-style.module.css`, javascript will help in hashing your class, so it will only target that specific element in specific component. In result, you will see this result during inspection.

```html
<div class="blog-12ba89">...</div>
```

### React

To use in React, simply import you module css.

```jsx
import styles from "your-style.module.css";

<div className="styles.blog">...</div>
```

### Vue

Since Vue also supports in-file stylesheet, so there are two ways of using `.module.css`.

```vue
<template>
  <div :class="styles.blog">...</div>
</template>

<script setup>
import styles from "your-style.module.css";
</script>
```
OR you can just do it inside your `.vue` file!

```vue
<template>
  <div class="blog">...</div>
</template>

<style module>
.blog {
  background-color: #00000011;
}
</style>
```

Unfortunately, for Vue, you need to set up module loader to use CSS modules. You can refer to [the documentation on Vue Loader](https://vue-loader.vuejs.org/guide/css-modules.html).

But, don't be sad, for there is a Vue way of doing things, that is scopes!

```vue
<template>
  <div class="blog">...</div>
</template>

<style scoped>
.blog {
  background-color: #00000011;
}
</style>
```

Different on how CSS modules handle things, instead of hashing the class itself, it create a data-attribute which handles the hashing. So the output should be like below when you inspect your website.

```html
<div class="blog" data-v-f3f3eg9>...</div>
```

---

## Preprocessors and Postprocessors

Sometimes, when we write our own CSS, there is a time where the class name initials are the same such as `blog__#`, or maybe you refer to the same initial selector such as `div > .wrapper` and `div > .title`. As your stylesheet grows, you find out that you need to copy the same sheet over and over (pun intended).

Of course, this is one of the example of the use case, but this is the time where you should consider using preprocessors or postprocessors to do the job.

Preprocessors such as LESS, SASS, SCSS, and postprocessors such as PostCSS are CSS-to-go for developers that well versed in CSS, since they support plugins and have some features such as nesting and variables (though I personally feel variables can be done using vanilla CSS). Let me show you some example on how they work.

```scss
.blog {
  p {
    color: black;
  }
  .title {
    font-weight: 700;
  }
  &__wrapper {
    background-color: #00000011;
  }
}
```

It will later processed and the result will be as below.

```css
.blog p {
  color: black;
}

.blog .title {
  font-weight: 700;
}

.blog__wrapper {
  background-color: #00000011;
}
```

Just imagine how easy your CSS can be debug later on!

These, of course can be used for both React and Vue, but you need to let your compiler know what you are using. You might need to find the loader of your desired preprocessor or postprocessor and install it as your dependency.

Since Vue also supports in-file styling, after you install the loader. you can do it this way.

```vue
<style lang="scss">
.blog {
  p {
    color: black;
  }
  .title {
    font-weight: 700;
  }
  &__wrapper {
    background-color: #00000011;
  }
}
</style>
```

You only need to add `lang` attribute to your `style`, and you are good to go!

---

## CSS-in-JS

Since we are using Javascript, why not having Javascript all the way? Of course, it is also available! It is one of the option, so you can use it if you want.

There are tons of libraries out there for CSS-in-JS, especially for React, so developer can do code sharing between React and React Native for development, since React Native didn't support CSS. @michelebertoli did a good job discovering [most of CSS-in-JS libraries](https://michelebertoli.github.io/css-in-js/), so you can explore there.

---

## CSS Frameworks

There are a ton of CSS frameworks that can be used as well, so you can use their CDN and just use all the utilities available for you. CSS frameworks such as Bootstrap, TailwindCSS, Materialize, Bulma etc. help developers to focus on component development, instead of composing your own CSS.

All you need to do, is to head to their respective framework documentation, and install it, or import it to your project to get going.

Personally, I really love TailwindCSS and Bulma for the features offered, but I won't explain further.

---

## Conclusion

There are a lot of ways you want to style your components. Of course, React and Vue has its own way of doing styling, so you can choose one of them that suits your style. Improving developer experience is one thing  that we need to keep in mind, especially when working in a team.

But of course, for you web artisans out there, you are cool 😎!

Anything lacking, you can comment down below!

Peace be upon ya!