DEV Community

Cover image for React VS Vue | How about some style ✨?
Atif Aiman
Atif Aiman

Posted on • Edited on

React VS Vue | How about some style ✨?

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.

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.

<div style="margin: 16px">...</div>
Enter fullscreen mode Exit fullscreen mode

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

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

<div style={{ backgroundColor }} />
Enter fullscreen mode Exit fullscreen mode

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 -->
<div :style="{ backgroundColor }" />

<script setup>
const backgroundColor = "#42b883";
</script>
Enter fullscreen mode Exit fullscreen mode

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.

<style>
div {
  background-color: ##35495e;
}
</style>
Enter fullscreen mode Exit fullscreen mode

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

Vue

<template>
  <div>...</div>
</template>

<style>
div {
  background-color: "#42b883";
}
</style>
Enter fullscreen mode Exit fullscreen mode

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.

<link rel="stylesheet" href="your-css-sheet.css">
Enter fullscreen mode Exit fullscreen mode

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

import "/path/to/your-css-sheet.css";
Enter fullscreen mode Exit fullscreen mode

...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.

.blog {
  background-color: #00000011;
}
Enter fullscreen mode Exit fullscreen mode

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.

<div class="blog">...</div>
Enter fullscreen mode Exit fullscreen mode

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.

<div class="blog-12ba89">...</div>
Enter fullscreen mode Exit fullscreen mode

React

To use in React, simply import you module css.

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

<div className="styles.blog">...</div>
Enter fullscreen mode Exit fullscreen mode

Vue

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

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

<script setup>
import styles from "your-style.module.css";
</script>
Enter fullscreen mode Exit fullscreen mode

OR you can just do it inside your .vue file!

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

<style module>
.blog {
  background-color: #00000011;
}
</style>
Enter fullscreen mode Exit fullscreen mode

Unfortunately, for Vue, you need to set up module loader to use CSS modules. You can refer to the documentation on Vue Loader.

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

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

<style scoped>
.blog {
  background-color: #00000011;
}
</style>
Enter fullscreen mode Exit fullscreen mode

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.

<div class="blog" data-v-f3f3eg9>...</div>
Enter fullscreen mode Exit fullscreen mode

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.

.blog {
  p {
    color: black;
  }
  .title {
    font-weight: 700;
  }
  &__wrapper {
    background-color: #00000011;
  }
}
Enter fullscreen mode Exit fullscreen mode

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

.blog p {
  color: black;
}

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

.blog__wrapper {
  background-color: #00000011;
}
Enter fullscreen mode Exit fullscreen mode

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.

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

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, 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!

Top comments (2)

Collapse
 
victorquanlam profile image
Victor Quan Lam

Vue for the W.

Collapse
 
alserembani profile image
Atif Aiman

I still want React 😭✊

🤣🤣🤣