Search code examples
htmlcsssvg

How to <svg> in <table> with CSS?


I have a <table> with 2 <svg> inside:

<table>
    <tbody>
        <tr>
            <td>
                <svg/>
            </td>
            <td>
                <svg/>
            </td>
        </tr>
    </tbody>
</table>

These svgs are used to draw shapes on top of <image> that have certain width and height. Like this:

<svg viewbox="0 0 100 100">
    <image href="/my_image.png"/>
    <rect x="10" y="10" width="80" height="80"/>
</svg>

The table itself has a limit on max-width. Typically, this is 100% in order to not grow larger than the screen (horizontally). But in general it might be deliberate value like 800px or width might be limited by container size, which itself might be limited to 100% of the screen.

In case when svgs have total width less than the screen I want the table to have width equal to sum of that of svgs. For instance, if width of left svg is 100px, right is 200px and screen width is 500px then I want a table with 100px+200px width.

In case when svgs have total width greater than the screen I want the table to be fit into the screen and to "shrink" size of the svgs in the way that preserves the ratio between them. For instance, if width of left svg is 2000px, right is 1000px and the screen width is 1500px then I want a table with 1500px, left svg with 1000px width and right svg with 500px width. As you can see, the width is proportional: 1000px for left = original 2000px / total width (2000px + 1000px) times screen width 1500px.

Now, what I tried...

I understand that svg means "scalable" and normally doesn't have a certain size. So in order to make this work I filled viewbox with width and height of the images. This didn't help.

Then I tried to set width and height for svgs. Both as attributes and style properties:

<svg
  viewbox="0 0 1000 500"
  width="1000px"
  style="width:1000px"
>
</svg>

This didn't work either.

Then I experimented with things like max-width for svgs but to no avail.

Is this even possible with pure CSS? It is also important to keep in mind that the table might have other elements in cells besides svgs. How to make this work in general?


Solution

  • This is what i think will work on that i

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Resizable SVGs in Table</title>
      <style>
        table {
          width: 100%;
          table-layout: fixed;
          border-collapse: collapse;
        }
        
        svg {
          display: block;
          /* Ensures inline-block spacing is not applied */
          max-width: 100%;
          /* Make the SVG responsive */
          height: auto;
          /* Maintain aspect ratio */
        }
      </style>
    </head>
    
    <body>
    
      <table>
        <tbody>
          <tr>
            <td>
              <svg viewbox="0 0 1000 500">
              <image href="/my_image1.png"/>
              <rect x="10" y="10" width="80" height="80"/>
            </svg>
            </td>
            <td>
              <svg viewbox="0 0 1000 500">
              <image href="/my_image2.png"/>
              <rect x="10" y="10" width="80" height="80"/>
            </svg>
            </td>
          </tr>
        </tbody>
      </table>
    
      <script>
        // Calculate and adjust the width of SVGs
        function adjustSVGWidths() {
          const tableWidth =
            document.querySelector('table').getBoundingClientRect().width;
          const svgs = document.querySelectorAll('svg');
    
          let totalSvgWidth = 0;
    
          // Calculate the total width of SVGs
          svgs.forEach(svg => {
            totalSvgWidth += svg.getBoundingClientRect().width;
          });
    
          // Adjust the width of each SVG proportionally
          svgs.forEach(svg => {
            const originalWidth = parseFloat(svg.getAttribute('viewBox').split(' ')[2]);
            const newWidth = (originalWidth / totalSvgWidth) * tableWidth;
            svg.setAttribute('width', newWidth);
          });
        }
    
        // Adjust SVG widths initially and on window resize
        window.addEventListener('resize', adjustSVGWidths);
        adjustSVGWidths();
      </script>
    
    </body>
    
    </html>