Search code examples
htmlsvgperspectivez-order

How to clip an inline SVG *after* it has been transformed with perspective?


In the code below the buttons are not viewable and so not clickable but they are without the transform. The transformed SVG elements spills over where the buttons are. I've tried changing the z-index but I have read that the z axis no longer matters once a perspective transform has taken place.

All I want to do is clip the SVG after the transform to stop it spilling over to other controls etc.

enter image description here

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body style="background-color: #999;">

    <label style="z-index: 0;" for="dd">Choose :</label>

    <select style="z-index: 0;" name="dd" id="dd">
        <option value="Foo">Foo</option>
        <option value="Bar">Bar</option>
    </select>
    <input style="z-index: 0;" type="number" value="0"></input>
    <button style="z-index: 0;" onclick="console.log('start clicked')">Start</button>
    <button style="z-index: 0;transform: translateZ(0px);" onclick="console.log('stop clicked')">Stop</button>

    <svg viewBox="0 0 600 800" style="z-index: -1;transform:  perspective(300px) rotateY(10deg); background-color:cyan "
        width="1280" height="800">
    </svg>
</body>

</html>

Solution

  • You can wrap all your form controls in a div, give it relative position and a z-index of 1 and it will show up above your SVG despite your transform. Then you can give that div a background that matches the page background and it will look like the SVG element is clipped.

    body {
      margin: 0;
    }
    
    div {
      position: relative;
      z-index: 1;
      background-color: #fff;
      padding: 1rem;
    }
    
    svg {
      z-index: -1;
      transform: perspective(300px) rotateY(10deg);
      background-color: cyan;
      height: 800px;
      width: 1280px
    }
    <div>
      <label for="dd">Choose :</label>
    
      <select name="dd" id="dd">
        <option value="Foo">Foo</option>
        <option value="Bar">Bar</option>
      </select>
      <input type="number" value="0" />nii
      <button>Start</button>
      <button>Stop</button>
    </div>
    
    <svg width="1280" height="800">
    </svg>