Styled components in ReactJS

Building a professional website does include UI and UX both. There are several ways to make a website’s eye pleasant and make it more user-friendly. In this article, we will talk about some of them. Below is the topic that we will discuss today,

  • Styled components
  • Styled components and dynamic props
  • Styled component and media query
  • CSS module
  • Dynamic style with CSS module

Styled components

  • Create a react project

Note: please read this article to learn about creating a react project.

  • Install the styled component package by running the below command in the project folder,
npm install --save styled-components
  • After installing, open the App.js file
function App() {
  return (
    <div>

    </div>
  );
}

export default App;
  • Create a button component with the help of styled component
import styled from "styled-components";
// styled component for button
  const Button = styled.button`
  font-size: 1.2em;
  padding: 8px 16px;
  outline: none;
  border:none;
  border-radius: 4px;
  display: block;
  margin: 20px auto;
background: black;
color: white;
  `;

Here we have imported the styled component first. Then we have declared a variable; but in the styled object, button is a method. Basically, we can get every HTML tag from this styled method. And after the method, inside the template literal, we have added some CSS styles that will and only applicable for the button only.

  • Use this Button variable like a regular component inside the JSX
<div>
     <Button>Styled Button</Button>
   </div>
import styled from "styled-components";

function App() {
  // styled component for button
  const Button = styled.button`
  font-size: 1.2em;
  padding: 8px 16px;
  outline: none;
  border:none;
  border-radius: 4px;
  display: block;
  margin: 20px auto;
background: black;
color: white;
  `;
  return (
    <div>
      <Button>Styled Button</Button>
    </div>
  );
}

export default App;

After running the server, this will look like this,

Dynamic props

We can set style dynamically with the props while using styled-components as well.

  • Create a state hook with the default value of true and change its state of it by using onClick() event handler in the button
  const [isValid, setIsValid] = useState(true);
<div>
      <Button onClick={() => setIsValid(!isValid)}>Styled Button</Button>
    </div>
  • Now, pass an isValid props in this button,
 <Button isValid={isValid} onClick={() => setIsValid(!isValid)}>Styled Button</Button>

This isValid props can now be accessible from the template literal

  • Add a border style dynamically based on this isValid props and its boolean value,
border:5px solid ${props => props.isValid ? 'red' : 'none'};

Here, we will pass a callback function with props. And this props will receive the data attribute that we have passed to this button component. And based on this, we can change or add some styles. In our case, if the isValid value is true, we will see a red border around the button here.

import { useState } from "react";
import styled from "styled-components";
// styled component for button
const Button = styled.button`
font-size: 1.2em;
padding: 8px 16px;
outline: none;
border:5px solid ${props => props.isValid ? 'red' : 'none'};
border-radius: 4px;
display: block;
margin: 20px auto;
background: black;
color: white;
&:active
{
background: gray;
}
&:hover
{
cursor: pointer
}
`;
function App() {
  const [isValid, setIsValid] = useState(true);
  console.log(isValid);

  return (
    <div>
      <Button isValid={isValid} onClick={() => setIsValid(!isValid)}>Styled Button</Button>
    </div>
  );
}

export default App;

While false,

While true,

Styled component and media query

We use CSS media query to make a page responsive. And we can also add media query to styled component as well.

  • Declare media query screen ratio inside the template literal of the button method,
// styled component for button
const Button = styled.button`
font-size: 1.2em;
padding: 8px 16px;
outline: none;
border:5px solid ${props => props.isValid ? 'red' : 'none'};
border-radius: 4px;
display: block;
margin: 20px auto;
background: black;
color: white;
&:active
{
background: gray;
}

@media (max-width:768px){
  background: salmon;
  color: white
}

&:hover
{
cursor: pointer
}
`;

Here we have added media query for maximum screen size 768px. So, till 768px resolution, background of the button will be salmon color and the text color will be white. And larger than 768px will take regular colors that we have already applied.

import { useState } from "react";
import styled from "styled-components";
// styled component for button
const Button = styled.button`
font-size: 1.2em;
padding: 8px 16px;
outline: none;
border:5px solid ${props => props.isValid ? 'red' : 'none'};
border-radius: 4px;
display: block;
margin: 20px auto;
background: black;
color: white;
&:active
{
background: gray;
}

@media (max-width:768px){
  background: salmon;
  color: white
}

&:hover
{
cursor: pointer
}
`;
function App() {
  const [isValid, setIsValid] = useState(true);
  console.log(isValid);

  return (
    <div>
      <Button isValid={isValid} onClick={() => setIsValid(!isValid)}>Styled Button</Button>
    </div>
  );
}

export default App;

Larger than 768px,

3

Less than 768px,

4

CSS module

While working on a big project, sometime it happens that, different components but with the same class. Even though the styles should be different as well. And the class names should not be the same for different components. This might cause some conflicts while adding styles to the component.

To solve this, we can use CSS module.

  • Create a CSS file named, custom.module.css in the src folder,

5

  • Import this newly created CSS file in the app.js component,
import styles from './custom.module.css';

We are importing this CSS file as styles. This is like an object. And every style with the respective class name is like an object property here.

  • Add some styles for the button in this CSS file,
.button {
    font-size: 1.2em;
    padding: 8px 16px;
    outline: none;
    border: 5px solid none;
    border-radius: 4px;
    display: block;
    margin: 20px auto;
    background: black;
    color: white;
}
  • Access this class from the button as a property of the styles object
<div>
     {/* <Button isValid={isValid} onClick={() => setIsValid(!isValid)}>Styled Button</Button> */}
     <button className={styles.button} isValid={isValid} onClick={() => setIsValid(!isValid)}>Styled Button</button>
   </div>
import { useState } from "react";
import styled from "styled-components";

import styles from './custom.module.css';
function App() {
  const [isValid, setIsValid] = useState(true);
  console.log(isValid);

  return (
    <div>
      <button className={styles.button} isValid={isValid} onClick={() => setIsValid(!isValid)}>Styled Button</button>
    </div>
  );
}

export default App;

6

Dynamic styles with CSS module

  • Add a new class and styles to show dynamically into the button
.button_redBorder{
    border: 3px solid red;
}

We will set this styled class dynamically base on certain condition on that button,

  • Use the same isValid state and the onClick() handler to change state dynamically,
<button className={styles.button} onClick={() => setIsValid(!isValid)}>Styled Button</button>
  • Write the class names inside the template literal to add some dynamic conditions
<button className={`${styles.button} ${isValid && styles.button_redBorder}`} onClick={() => setIsValid(!isValid)}>Styled Button</button>

Here we are checking the condition of isValid . If it is true we will render the button_redBorder ‘s styles here which will add a red border around the button.

import { useState } from "react";
import styled from "styled-components";

import styles from './custom.module.css';
// styled component for button
/* const Button = styled.button`
font-size: 1.2em;
padding: 8px 16px;
outline: none;
border:5px solid ${props => props.isValid ? 'red' : 'none'};
border-radius: 4px;
display: block;
margin: 20px auto;
background: black;
color: white;
&:active
{
background: gray;
}

@media (max-width:768px){
  background: salmon;
  color: white
}

&:hover
{
cursor: pointer
}
`; */
function App() {
  const [isValid, setIsValid] = useState(true);
  console.log(isValid);

  return (
    <div>
      {/* <Button isValid={isValid} onClick={() => setIsValid(!isValid)}>Styled Button</Button> */}
      <button className={`${styles.button} ${isValid && styles.button_redBorder}`} onClick={() => setIsValid(!isValid)}>Styled Button</button>
    </div>
  );
}

export default App;

custom.module.css,

.button {
    font-size: 1.2em;
    padding: 8px 16px;
    outline: none;
    border: 5px solid none;
    border-radius: 4px;
    display: block;
    margin: 20px auto;
    background: black;
    color: white;
}

.button_redBorder {
    border: 3px solid red;
}

7

8

This is how we can add dynamic styles with CSS module as well.