htmlcsssvgoverlay

Overlaying a div with an svg using CSS grid layout when div size is unknown ahead of time


I have a div:

I want to overlay that div with an SVG:

I know this could be done using position: relative/absolute. I am trying to use CSS grid layout to achieve this, though.

Here's the code I have:

#wrapper {
  display: grid;
  width: fit-content;
  height: fit-content;
}

#d1 {
  grid-area: 1 / 1;
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  border: 5px solid black;
}

#overlay {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
}
<div id="wrapper">
  <div id="d1" style="width: 20em;">
    <p>Some content here.</p>
    <p>Some content here.</p>
  </div>
  <svg id="overlay" viewBox="0 0 3 3" preserveAspectRatio="none">
        <rect width="100%" height="100%" fill="purple" opacity="0.5" />
    </svg>
</div>

https://jsfiddle.net/w2mucxvL/

enter image description here

The problem is: browsers seem to be ignoring preserveAspectRatio="none", which causes SVG to be square (instead of the size of #d1, which is not square). What am I missing?


Solution

  • You have to disable the size contribution of the SVG so that it doesn't affect the size of the grid but rather consider the grid size to be sized:

    #wrapper {
      display: grid;
      width: fit-content;
    }
    
    #d1 {
      grid-area: 1 / 1;
      border: 5px solid black;
    }
    
    #overlay {
      grid-area: 1 / 1;
      width: 100%;
      height: 100%;
      contain: size; /* disable size contribution */
    }
    <div id="wrapper">
      <div id="d1" style="width: 20em;">
        <p>Some content here.</p>
        <p>Some content here.</p>
      </div>
      <svg id="overlay" viewBox="0 0 3 3" preserveAspectRatio="none">
            <rect width="100%" height="100%" fill="purple" opacity="0.5" />
        </svg>
    </div>

    Written differently:

    #wrapper {
      display: grid;
      width: fit-content;
    }
    
    #d1 {
      grid-area: 1 / 1;
      border: 5px solid black;
    }
    
    #overlay {
      grid-area: 1 / 1;
      width: 0;
      height: 0;
      min-width: 100%;
      min-height: 100%;
    }
    <div id="wrapper">
      <div id="d1" style="width: 20em;">
        <p>Some content here.</p>
        <p>Some content here.</p>
      </div>
      <svg id="overlay" viewBox="0 0 3 3" preserveAspectRatio="none">
            <rect width="100%" height="100%" fill="purple" opacity="0.5" />
        </svg>
    </div>