Using styled-components with Vue.js

Using styled-components with Vue.js

  • 264

‘styled-components’ is a component-first approach to styling your web apps. That means your JS components can be complete UI units (not only structure and logic that are styled from a separate stylesheet). ‘styled-components’ uses JavaScript to create and modify CSS at run-time.

How does it Work?

styled-components are particularly popular with React. So let’s first use a React example to understand how they work.

import styled from 'styled-components';
const Title = styled.h1`

index.js

import React from "react";
import ReactDOM from "react-dom";
import styled from 'styled-components';
 // Create a <Title> react component
const Title = styled.h1`
  font-size: 1.7em;
  text-align: center;
  color: palevioletred;
`;
const container = styled.section`
  padding: 4em;
  background: papayawhip;
`;
const rootElement = document.getElementById("root");
ReactDOM.render(
  <React.StrictMode>
	<container>
  	<Title>Title using style component</Title>
	</container>
  </React.StrictMode>,
  rootElement
);

index.js

In the above example, we see a styled title, loaded with its CSS styling in the JS file, and rendered as a normal React button. Traditionally to style a component, you add a className prop or introduce SASS files, but now you can directly write the CSS properties for the instance of styled-components.

This is image title

When you use CSS within JS files, style properties are added at the top of the DOM. Many examples of using styled-components can be found on the styled-components website, and the awesome-styled-components and ecosystem pages.

Why use Styled-components

Before we go on to implement a Vue example with styled-components, let’s see how styled-components can help Vue developers.

Allows building custom components with CSS

Styled-components allow developers to build custom components that are more than just HTML elements. Developers who use these components don’t have to put in extra effort to add styles through className.

These components contain their own styles and can be reused across entire projects easily. Traditional elements like subheadings which require a className and associated styles can now be declared as follows:

import styled from "styled-components";
 
// Create a <Title> react component
const heading = styled.h2`
  font-size: 1.3em;
  text-align: center;
  color: navy;
`;
 
<heading>Heading Using Style Components</heading>

index.js

Output:

This is image title

Styled-components remove the dependency on CSS and make styles also a part of the component itself. There will be almost no learning curve involved because the syntax used for styles are almost identical to traditional CSS.

A better option than Inline Styling

Inline-styles are usually discouraged due to the many inherent flaws they bring along, such as limited browser compatibility, camel-casing, auto appended scalar quantities, and the inability to use pseudos and media queries.

The good thing about styled-component is they don’t compile their code into inline CSS. They add their relevant styles at the top of the DOM as follows: Here is an example to understand it better.

import styled from 'styled-components';
const Para= styled.div`
color: green,
background: blue
`
<Para>Testing Styled Components </Para>

index.js

Below is the output once we compiled.

<style>
.hash12345tf {
background-color: blue;
color: green;
}
</style>
<p class="hash12345tf">Testing Styled Components </p>

index.html

Support for Native Mobile app development

Another advantage of using styled-components is that they can be bundled with React Native. Thus styled-components become a unified solution for both web and native mobile. Vue also has a native mobile app framework called Vue Native which is designed to connect React Native with Vue. Thus styled-components can be used to build native mobile apps even with Vue.

You can use styled-components to make JSX code very legible by assigning alias names to comments. You can also easily convert components to styled-components using styled().

Enforces Scoped Styles

Controlling how styles affect various elements within the DOM is somewhat complicated, especially for inexperienced developers. This is due to the difficulty of controlling the scope of CSS styles. Vue provides very good support for scoped styles. Without proper control, changing a CSS rule of one element can affect a seemingly unrelated element somewhere else in the DOM.

Styled-components create styles for each instance of a component and, thus, ensure that changes don’t affect the styles of other components. This behavior is quite similar to the scoped styling behavior provided by Vue.

Props over Classes

Styled-components use props instead of classes, and this has enabled developers to adopt best practices for controlling the behavior of components. When styled-components are used, HTML and CSS manipulations are outside of components.

const Subtitle = styled.h2`
  font-size: 2em;
  color: ${props => props.primary ? 'red' : 'green'};
`;
<Subtitle primary>Hello World</Subtitle>

index.js
However, you will still be able to use classes where required without affecting its performance. Here is an example of using classNames with styled-components.

const Title = styled.h2`
  font-size: 2em;
  color: blue;
 
  &.primary {
	color: black;
  }
`;
<Title>Title using </Title>

index.js

Output:

This is image title

We can also use className like below:

<Title className= "primary">Style using class name</Title>

index.js

Output:

This is image title

Unit Testing of CSS is available

Styled-components, like any other component, can have unit tests. This is an important benefit of styled-components that introduce an important feature for styling that has not been available up to now.

Jest can be used to perform snapshot testing on styled-components. It provides a matcher that can be used to control style rules. Installing Jest Styled Components is quite straightforward:

npm install --dev jest-styled-components

command.txt

This is a simple test showing the versatility Jest with Styled-components:

import React from 'react'
import styled from 'styled-components'
import renderer from 'react-test-renderer'
import 'jest-styled-components'
const Button = styled.button`
  color: red;
`
test('it works', () => {
  const tree = renderer.create(<Button />).toJSON()
  expect(tree).toMatchSnapshot()
})

index.js
The resulting snapshot will be as follows:

exports[`it works 1`] = `
.c0 {
  color: green;
}
<button
  className="c0"
/>
`

output.txt

Support for Sass and Polished

If you are familiar with Sass, you may have noticed that both Sass and Polished have been used in the examples of this article. Polished enhances the possibilities of Sass, and styled-components supports both of them.

const Weblink = styled.a`
  cursor: pointer;
  text-decoration: none;
  &:hover {
	color: blue;
    text-decoration: underline;
  }
`;

index.js

The link gets activated while the mouse hover.

This is image title

The support offered for Sass and Polished, and their optimizations features stand to show the commitment of styled-components to ensure that everything that is already available through CSS is not lost. It also serves the purpose of reducing or eliminating a learning curve.

Things to consider before switching to styled-components

Styled-components have a lot of benefits over CSS. However, there are still a few things that users should consider before switching to styled-components. Users are concerned with the considerable learning curve of depending solely on JS for styling. There is also the concern of continuity and extended support, as reverting to traditional CSS can be a daunting task.

There is also the concern of being locked-in. Now, in addition to being locked-in to JS, you will have the additional concern of being locked-in to styling in JS. Personal preferences are difficult to change. Those used to maintaining separate styling will have many reservations against styled-components. This will also affect the growth of the community, and even the few early adopters will not have much support.

Sample example of styled-components in Vue

Let’s create a ‘dynamic button” using Vue App and style-components. Styled-components can be installed using npm or yarn:

yarn add vue-styled-components
npm install vue-styled-components

We start by creating Button.js as per the Vue app hierarchy in “…/component/elements/StyledButton.js”.

import styled from "vue-styled-components";
const buttonProps = {
 color: String
};
 
const CButton = styled("button", buttonProps)`
 color: ${props => props.color};
`;
 
export default CButton;

StyledButton.js

This file defines the button and its text string. The button is defined using vue-styled-components. The button will then be added to App.vue as follows:

<template>
 <div id="app">
   <span>Select Color</span>
   <br>
   <input type="color" v-model="textColor" width="50px" margin-top="70px">
   <br>
   <br>
   <Sbutton :color="textColor">check out the text color</Sbutton>
   <br>
 </div>
</template>

App.vue

Next, let’s add the script to change the color of the button text in App.vue:

<script>
import CButton from "@/component/element/StyledButton.js";
export default {
 components: {
   Sbutton: CButton
 },
 data() {
   return {
     textColor: "#000000"
   };
 }
};
</script>

App.vue
Below is the complete App.vue file:

<template>
 <div id="app">
   <span>Select Color</span>
   <br>
   <input type="color" v-model="textColor" width="50px" margin-top="70px">
   <br>
   <br>
   <Sbutton :color="textColor">check out the text color</Sbutton>
   <br>
 </div>
</template>
 
<script>
import CButton from "@/component/element/StyledButton.js";
export default {
 components: {
   Sbutton: CButton
 },
 data() {
   return {
     textColor: "#000000"
   };
 }
};
</script>

App.vue

The application will give the below output initially:

This is image title

Select a color in the color-picker to change the text-color of the button. The output will be as follows:

This is image title

Conclusion

With 28.7k GitHub stars, styled-components are a favorite in both the React and Vue communities. It uses styles with the best bits of ES6 and CSS. Despite being quite new, styled-components have been adopted in many projects.

Styled-components enables styling for custom components using props and eliminates the use of className. We looked at many code snippets demonstrating the use of styled-components in React and also a complete example of using them in Vue. We hope that this article has encouraged you to adopt styled-components.