css margin transition doesnt animate in react

Im trying to create a simple react switch component that is moves smoothly

this is the react code

export function Switch({callBackOn, callBackOff}){
    const [switchState, setState] = useState("");

    function callback(){
        if(switchState == ""){
            setState("switch-on")
        }
        else{
            setState("")
        }
    }
    return(
      <div onClick={callback} className={"switch " + switchState}>
        <div></div>
      </div>
    )
  }

and this is my css

.switch {
  background-color: red;
  height: 5rem;
  width: 10rem;
  border-radius: 2.5rem;
  border: 5px solid;
  transition: 1s;
  position: relative;
}

.switch-on {
  background-color: green !important;
}

.switch div {
  height: 5rem;
  width: 5rem;
  border-radius: 2.5rem;
  background-color: white;
  transition: margin-left 1s;
}

.switch-on div {
  margin-left: auto;
}

The background color change transition works but the margin change isn’t animated at all. I have also tried using keyframes and the animation attribute but it also hasn’t worked

Answer

As Barthy mentioned, you cannot animate/transition margin: auto, also magrin is not best way to animate/transition. For that, better take a transform property. How to create high-performance CSS animations

Solution with margin

function Switch({ callBackOn, callBackOff }) {
  const [switchState, setState] = React.useState("");

  function callback() {
    if (switchState == "") {
      setState("switch-on");
    } else {
      setState("");
    }
  }
  return (
    <div onClick={callback} className={"switch " + switchState}>
      <div></div>
    </div>
  );
}

function App() {
  return (
    <div className="App">
      <Switch />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
    <App />,
  rootElement
);
.App {
  font-family: sans-serif;
  text-align: center;
}

.switch {
  background-color: red;
  height: 5rem;
  width: 10rem;
  border-radius: 2.5rem;
  border: 5px solid;
  transition: 1s;
  position: relative;
}

.switch-on {
  background-color: green;
}

.switch div {
  height: 5rem;
  width: 5rem;
  border-radius: 2.5rem;
  background-color: white;
  transition: margin-left 1s;
}

.switch-on div {
  margin-left: 5em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Solution with transform

function Switch({ callBackOn, callBackOff }) {
  const [switchState, setState] = React.useState("");

  function callback() {
    if (switchState == "") {
      setState("switch-on");
    } else {
      setState("");
    }
  }
  return (
    <div onClick={callback} className={"switch " + switchState}>
      <div></div>
    </div>
  );
}

function App() {
  return (
    <div className="App">
      <Switch />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
    <App />,
  rootElement
);
.App {
  font-family: sans-serif;
  text-align: center;
}

.switch {
  background-color: red;
  height: 5rem;
  width: 10rem;
  border-radius: 2.5rem;
  border: 5px solid;
  transition: 1s;
  position: relative;
}

.switch-on {
  background-color: green;
}

.switch div {
  height: 5rem;
  width: 5rem;
  border-radius: 2.5rem;
  background-color: white;
  transition: transform 1s;
}

.switch-on div {
  transform: translateX(5em);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>