SVG Animation does not fill container in Safari

I’m having issues with SVG animation not filling whole container on Safari browser. For some reason on Safari width of my SVG seems to bo random, but it works fine on Chrome and other browsers.

Expected behavior:

  • After clicking menu icon, SVG background animation should fill container with red borders.

Actual behavior

  • Animation does not fill whole container on Safari Mac / iOS

Codepen

Simplified code below:

import React, { useEffect, useState } from "react";
import styled from "styled-components";

function MenuOverlay({ isOpen, firstLoad }) {
  const controls = useAnimation();

  const variants = {
    open: {
      d: [
        "M 0 24 L 0 0 L 1 0 C 1 8 1 16 1 24 L 0 24 Z",
        "M 0 24 L 0 0 L 9.143 0 C 18.286 0 18.286 24 9.143 24 L 0 24 Z",
        "M 0 24 L 0 0 L 24 0 C 24 8 24 16 24 24 L 0 24 Z",
      ],
      scaleX: [0, 1, 1],
      transition: {
        ease: ["easeIn", "easeOut"],
      },
    },
    close: {
      d: [
        "M 0 24 L 0 0 L 24 0 C 24 8 24 16 24 24 L 0 24 Z",
        "M 0 24 L 0 0 L 16.5 0 C 9 5.5 8.5 17.5 16.5 24 L 0 24 Z",
        "M 0 24 L 0 0 L 1 0 C 1 8 1 16 1 24 L 0 24 Z",
      ],
      scaleX: [1, 1, 0],
      transition: {
        ease: ["easeIn", "easeOut"],
      },
    },
  };

  // Sequence animation
  async function open() {
    await controls.start("open");
  }
  async function close() {
    await controls.start("close");
  }

  if (!firstLoad) {
    isOpen ? open() : close();
  }

  return (
    <LazyMotion features={domAnimation}>
      <Container>
        <Svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" preserveAspectRatio="none">
          <Path animate={controls} variants={variants} />
        </Svg>
      </Container>
    </LazyMotion>
  );
}

export default MenuOverlay;

// Styled Components
const Container = styled(m.div)`
  position: fixed;
  top: 0;
  left: 0;
  height: 100vh;
  width: 100vw;
  pointer-events: none;
  z-index: 0;
`;

const Svg = styled.svg`
  border: 1px solid red;
  height: 100vh;
  /* Mobile */
  width: 100vw;
  transform: scaleX(-1);
  /* Tablet */
  @media screen and (min-width: ${({ theme }) => theme.breakpoints[0]}) {
    width: 75vw;
    transform: unset;
  }
  /* Desktop */
  @media screen and (min-width: ${({ theme }) => theme.breakpoints[1]}) {
    width: 50vw;
  }
`;
const Path = styled(m.path)`
  fill: ${({ theme }) => theme.black[1]};
`;

Answer

Try adding the WebKit version of transform before where you have transform: scaleX(-1);

-webkit-transform: scaleX(-1);

Can you also provide us with a codepen or a link to where you have it so we can better see the behavior?

Ok after looking at your code try modifying you SVG view box from

<Svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" preserveAspectRatio="none">

to

<Svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" preserveAspectRatio="none">