Search code examples
htmlcssreactjstoggle

How to create a toggle slider switch with only background changes using CSS


Here, I want to create a toggle switch slider button. I have created it, but when I click on it," its background will be blue, and when I click off," its background will be blue, but here text is getting hidden on and off and is shown. I want that like in this picture:

Every time I only toggle the background colour to blue, I want to show the on and off buttons in a row, like in this image:

So when I click to toggle the background colour, from one to another colour with some transition, so how to achieve this using code is given below.

import React, { useState } from 'react';
import './styles.css'; 

const App = () => {
  const [isOn, setIsOn] = useState(false);

  const toggleSwitch = () => {
    setIsOn(!isOn);
  };

  return (<>
    <div className="toggle-container">
      <button
        className={`toggle-button ${isOn ? 'on' : 'off'}`}
        onClick={toggleSwitch}
        style={{color:isOn?'blue':'white',textAlign:isOn?'left':'right'}}
      >
        {isOn ? 'On' : 'Off'}
      </button>
    </div>
    
    </>
  );
};

export default App;

and css is below

.toggle-button {
  border:2px solid blue;
  outline: none;
  cursor: pointer;
  width: 100px;
  padding: 10px 20px;
  border-radius: 25px;
  font-weight: bold;
  font-size: 16px;
  transition: background-color 0.3s;
  position: relative;
  overflow: hidden;
}

.toggle-button:before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 50%;
  height: 100%;
  background-color: blue;
  transition: left 0.3s, background-color 0.3s;
}

.toggle-button.on:before {
  left: 50%;
  background-color: white;
}

.toggle-button.off {
  background-color: blue;
}

.toggle-button.on {
  background-color: white;
}

.toggle-button.on.off:before {
  background-color: blue;
}

.toggle-button.off.on:before {
  background-color: white;
}

Solution

  • I guess I get what are you trying to do, but I think this shoud be done with a different aproach, what about somehing like this, is a div at the bottom which indicates the selected option.

    This is only a example, you will have to apply external logic and events.

    Good luck!

    https://codesandbox.io/s/weathered-brook-yzkv2n?file=/src/App.js React Code:

    CSS:

    .btn__container {
      display: inline-flex;
      justify-content: center;
      align-items: center;
      border: 2px solid gray;
      border-radius: 3px;
      position: relative;
    }
    
    .btn__option {
      border-radius: 3px;
      padding: 8px;
      position: relative;
      z-index: 2;
      transition: all 0.3s linear;
      cursor: pointer;
    }
    
    .btn__option:hover {
      background-color: rgba(0, 0, 0, 0.2);
    }
    
    .btn__container.btn__container--left .btn__option--left {
      color: white;
    }
    
    .btn__container.btn__container--right .btn__option--right {
      color: white;
    }
    
    .btn__option--selection {
      padding: 8px;
      border-radius: 3px;
      position: absolute;
      top: 0;
      bottom: 0;
      background-color: purple;
      color: purple;
      z-index: 1;
    }
    

    JSX:

    import "./styles.css";
    import { useState, useRef } from "react";
    
    export default function App() {
      const [selected, setSelected] = useState("Text");
    
      const leftDiv = useRef(null);
    
      const rightDiv = useRef(null);
    
      const left = "Text";
    
      const right = "File";
    
      const getContainerClass = () => {
        if (selected === left) {
          return "btn__container btn__container--left";
        }
        return "btn__container btn__container--right";
      };
    
      const getSelectionStyle = () => {
        if (leftDiv && leftDiv.current && rightDiv && rightDiv.current) {
          if (selected === left) {
            return {
              left: "0",
              width: `${leftDiv.current.clientWidth}px`,
              padding: "0"
            };
          } else {
            return {
              left: `${leftDiv.current.clientWidth}px`,
              width: `${rightDiv.current.clientWidth}px`,
              padding: "0"
            };
          }
        }
        return { left: "0" };
      };
    
      return (
        <div className={getContainerClass()}>
          <div
            className="btn__option btn__option--selection"
            style={getSelectionStyle()}
          >
            {left}
          </div>
          <div
            ref={leftDiv}
            className="btn__option btn__option--left"
            onClick={() => setSelected(left)}
          >
            {left}
          </div>
          <div
            ref={rightDiv}
            className="btn__option btn__option--right"
            onClick={() => setSelected(right)}
          >
            {right}
          </div>
        </div>
      );
    }