DEV Community

Cover image for How to add dark mode in Gatsby + React Project using CSS/SCSS #2

Posted on

How to add dark mode in Gatsby + React Project using CSS/SCSS #2


This is the part of the previous post where we learned how we can add the dark theme using styled-components, in this post we're gonna learn to add dark theme using CSS/SCSS.


clone the repo if you don't have, and don't know to use Gatsby, there nothing unique we'll write our react code in Gatsby or you can just use React instead:

gatsby new
Enter fullscreen mode Exit fullscreen mode

the project will be cloned and install all the dependencies locally, now install SCSS and Img plugin for Gatsby:

yarn add node-sass gatsby-plugin-sass
Enter fullscreen mode Exit fullscreen mode

add configuration to gatsby-config.js file:

plugins: [`gatsby-plugin-sass`],
Enter fullscreen mode Exit fullscreen mode

now open up the server:

gatsby develop
Enter fullscreen mode Exit fullscreen mode

if you don't have installed Gatsby:

npm install -g gatsby-cli

# or
yarn global add gatsby-cli
Enter fullscreen mode Exit fullscreen mode

Adding Theme

to learn the basic the dark theme in CSS/SCSS we need to add some dummy need, so follow up create a file /src/pages/darkincss.js and use the below code:

import React, { useState } from "react"
import { DarkModeToggler } from "react-darkmode-toggler"
import { GlobalStyle } from "../components/Theme/globalStyle"
import { graphql } from "gatsby"
import Img from "gatsby-image"
import "./style.scss"

export default ({ data }) => {
  const [isDark, setIsDark] = useState("light")

  // Dark mode button toggler
  const darkModeHandler = () => {
    setIsDark(isDark === "light" ? "dark" : "light")

  return (
      {/**  This is for the background color **/}
      <GlobalStyle theme={isDark} />

      {/**  This is Button for theme switching */}
      <div className="toggler">

      {/** Our autcual Code is here for profile */}
      <div className={`profile__container ${isDark === "dark" && `dark`}`}>
        <div className="profile__card">
          <div className="profile__img">
            <Img fixed={data.file.childImageSharp.fixed} alt="Image of mine" />
          <div className="profile__body">
            <h1 className="profile__body--title">
              Has One
              <span className="profile__body--secondary">Code addicted</span>
            <div className="profile__actions">
              <button className="profile__actions--btn">Chat</button>
              <button className="profile__actions--btn">follow</button>

/** GraphQL query for getting Image */
export const query = graphql`
  query {
    file(relativePath: { eq: "profile.jpg" }) {
      childImageSharp {
        # Specify the image processing specifications right in the query.
        # Makes it trivial to update as your page's design changes.
        fixed(width: 200, height: 230) {

Enter fullscreen mode Exit fullscreen mode

In the above code, first we add the <GlobalStyle theme={isDark} /> which changes the global style like body background-color,

next adding the DarkModeToggler button,

profile__container our actual codes starts from profile__ for the profile as a dummy, I don't think this is best example...., then we add dark class if the isDark === 'dark'.

The last is GraphQL query for fetching image (if you're using ReactJs you can just use img instead).

To add the layout code here is the code /src/pages/style.scss:

$background-color: #e8eaee;
$card-color: #fff;
$font: #36373b;
$font-sec: #718796;
$button: #121212;

:root {
  --color-bg: #{$background-color};
  --color-card: #{$card-color};
  --color-text: #{$font};
  --color-sec: #{$font-sec};
  --color-button: #5679fb;

.dark {
  --color-bg: #121212;
  --color-card: #1e1e1e;
  --color-text: #e3e3e3;
  --color-sec: #989898;
  --color-button: #bb86fc;

.toggler {
  display: flex;
  justify-content: center;

.profile {
  /** container */
  &__container {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    width: 100%;

  /** card */
  &__card {
    width: 350px;
    height: 170px;
    border: 1px solid #ccc;
    overflow: hidden;
    border-radius: 7px;
    background: var(--color-card);
    display: flex;
    flex-direction: row;

    /** Box Shadow */
    box-shadow: 0 2.8px 2.2px rgba(0, 0, 0, 0.034),
      0 6.7px 5.3px rgba(0, 0, 0, 0.048), 0 12.5px 10px rgba(0, 0, 0, 0.06),
      0 22.3px 17.9px rgba(0, 0, 0, 0.072), 0 41.8px 33.4px rgba(0, 0, 0, 0.086),
      0 100px 80px rgba(0, 0, 0, 0.12);

  /** img */
  &__img {
    width: 200px;
    overflow: hidden;
    flex: 1 1 40%;

    & img {
      object-fit: cover;

  /** Body */

  &__body {
    margin: 4px 20px;
    font-family: Arial, Helvetica, sans-serif;

    &--title {
      font-size: 23px;
      color: var(--color-text);

    &--secondary {
      display: block;
      padding: 4px 0;
      color: var(--color-sec);
      font-size: 13px;

  /** Button */

  &__actions {
    margin-top: 15px;
    &--btn {
      width: 100%;
      margin: 4px 0;
      background: var(--color-button);
      padding: 8px 16px;
      border: transparent;
      color: #fff;
      text-transform: uppercase;
      cursor: pointer;

Enter fullscreen mode Exit fullscreen mode

To achieve this in CSS we need to use :root selector to define all colors for the light theme, for the dark color we define all colors inside .dark{}, once the dark class name added to HTML it will use all the colors from .dark{}, that's pretty much it!

:root {
  --color-background: #fff;

.dark {
   --color-background: #121212;

.container {
   background: var(--color-background);

Enter fullscreen mode Exit fullscreen mode

Alt Text

Final word

for the complex project you can create seprate file for color then include it to your SCSS file. Git Repo for this on gihtub.

Thanks for those who already followed me on Github, if you didn't please follow Github, I share a lot of stuff there about React, Gatsby, Linux,....

Feel free to fix any issue/mistake/weakness of mine, I would adore it!

Top comments (0)