Home > Mobile >  Resizing window with SVGs
Resizing window with SVGs

Time:06-08

I've got the current HTML being rendered:

<div style="width: 912px; height: 673px;">
    <div id="img-container" style="height: 58.82%; width: 47.07%; top: 20.59%; left: 26.46%; position: absolute;">
        <img  src="grid.jpg" alt="grid" style="width: 100%; height: 100%;"/>
        <div style="top: 40.55%; left: 50.13%; width: 11.7%; height: 19.33%; z-index: 13; position: absolute; transform: rotate(0deg); display: block;">
            <svg viewBox="0 0 100 100" height="100%" width="100%" id="square-0" preserveAspectRatio="none"  name="square">
                <rect x=".5%" y=".5%" height="98.5%" width="99%" stroke="white" fill="#cc0000" stroke-width="4"/>
            </svg>
        </div>
        <div style="top: 40.34%; left: 26.72%; width: 11.96%; height: 19.75%; z-index: 14; position: absolute; transform: rotate(0deg); display: block;">
            <svg viewBox="0 0 100 100" height="100%" width="100%" id="roundedSquare-1"  name="roundedSquare" preserveAspectRatio="none">
                <rect x=".5%" y=".5%" height="98.5%" width="99%" stroke="white" fill="#990099" stroke-width="4" rx="6"/>
            </svg>
        </div>
        <div style="top: 21.43%; left: 27.1%; width: 11.58%; height: 19.12%; z-index: 15; position: absolute; transform: rotate(0deg); display: block;">
            <svg viewBox="0 0 100 100" height="100%" width="100%" id="squareLetter-2"  name="squareLetter" preserveAspectRatio="none">
                <rect x="1.5" y="1.5" height="97" width="97" stroke="#00ffff" stroke-width="4" fill="#ff9900"/>
                <text  x="50" y="50" dy="26.5" dx="0.0em" text-anchor="middle" fill="white" font-size="74.96px">A</text>
            </svg>
        </div>
    </div>
</div>

This renders out like this: enter image description here

The goal is that on resizing the browser window, I'd like to keep the aspect ratio of the image, as well as have the SVG's resize to maintain position and shape inside the grid image. I've tried setting the height on the img-container div to auto, which does maintain the ratio for the image. But the SVGs still resize in a manner that doesn't make sense to me:

enter image description here

I've tried changing the height on the divs surrounding the SVGs to auto, and they look the right size, but the locations are off:

enter image description here

My question is how can I achieve the goal of resizing the window, and keeping the aspect ratio of the image and SVGs, as well as keeping the SVGs in the location on the grid image?

CodePudding user response:

I'd rather recommend a css grid or svg layout to keep aspect ratios.

Absolute positioning is rather complicating responsive layouts.

Svg grid layout: including tiles/columns in one parent svg

.resize {
  overflow: auto;
  padding: 1em;
  border: 1px solid #ccc;
  resize: both;
  width: 75vmin;
}

.svg-grid {
  width: 100%;
}

:root {
  --transX: translateX(0);
  --transY: translateY(0);
}

.col {
  transform: var(--transX) var(--transY);
}

.row-2 {
  --transY: translateY(100px);
}

.row-3 {
  --transY: translateY(200px);
}

.col-2 {
  --transX: translateX(100px);
}

.col-3 {
  --transX: translateX(200px);
}

.col-4 {
  --transX: translateX(300px);
}
<p>Resize me</p>
<div >
  <svg  viewBox="0 0 400 300" overflow="visible">
    <defs>
      <pattern x="-2" y="-2" id="grid" width="100" height="100" patternUnits="userSpaceOnUse">
        <rect width="100%" height="100%" fill="#000" />
        <rect x="0" y="0" width="100%" height="100%" fill="none" stroke="#fff" stroke-width="8" />
      </pattern>
    </defs>
    <rect  x="0" y="0" width="100%" height="100%" fill="url(#grid)" />
    <g >
      <rect x="0" y="0" height="100" width="100" stroke="white" fill="red" stroke-width="2" />
    </g>
    <g >
      <rect  name="roundedSquare" x="0" y="0" height="100" width="100" stroke="white" fill="#990099" stroke-width="4" rx="6" />
    </g>
    <g  name="squareLetter">
      <rect x="0" y="0" height="100" width="100" stroke="#00ffff" stroke-width="4" fill="orange" />
      <text  x="0" y="0" dy="50" dx="50" dominant-baseline="central" text-anchor="middle" fill="white" font-size="74.96px">A</text>
    </g>
  </svg>
</div>

Based on Temani Afif's answer: How can I apply multiple transform declarations to one element? we can use css-variables to get a pseudo svg-grid.
All svg grid elements are basically positioned at x/y=0 and moved by row and column classes setting transform properties like transform: translateX(0) translateY(100) to meet grid column/row positions.

CSS grid approach (using inlined svgs)

.resize{
  overflow:auto;padding:1em;
  border:1px solid #ccc;
  resize:both;
  width:75vmin;

}

.gridWrp{
  aspect-ratio: 4/3;
  width:100%;
  background:#eee;
  display:grid;
  grid-template-columns: [col1] 25% [col2] 25% [col3] 25% [col4] 25%; 
  grid-template-rows: [row1] 33.333% [row2] 33.333% [row3] 33.333% ;
}



.col{
    width:100%;
}

.col-2{
  grid-column-start: col2;
  grid-column-end: col3;
}

.col-3{
  grid-column-start: col3;
  grid-column-end: col4;
}

.col-4{
  grid-column-start: col4;
  grid-column-end: 100%;
}

.row-2{
  grid-row-start: row2;
  grid-row-end:  row3;
}

.row-3{
  grid-row-start: row3;
  grid-row-end: 100%;
}
<div >
  <div >
    <div >
      <svg  viewBox="0 0 100 100">
        <rect  x="0" y="0" height="100" width="100" fill="#cc0000" stroke-width="4" stroke="green" />
      </svg>
    </div>
    <div >
      <svg  viewBox="0 0 100 100">
        <rect  x="0" y="0" height="100" width="100" fill="orange" stroke-width="4" stroke="green" />
      </svg>
    </div>
    <div >
      <svg  viewBox="0 0 100 100">
        <rect  x="0" y="0" height="100" width="100" fill="orange" stroke-width="4" stroke="green" />
      </svg>
    </div>
    <div >
      <svg  viewBox="0 0 100 100">
        <g  name="squareLetter">
          <rect x="0" y="0" height="100" width="100" stroke="#00ffff" stroke-width="4" fill="orange" />
          <text  x="0" y="0" dy="50" dx="50" dominant-baseline="central" text-anchor="middle" fill="white" font-size="74.96px">A</text>
        </g>
      </svg>
    </div>
  </div>
</div>

It's crucial to define an aspect ratio for the parent grid element like so:

.gridWrp{
  aspect-ratio: 4/3;
}

CodePudding user response:

You're already using height="97" width="97" to your rect block, you should update that to height="auto" min-width="97"

  • Related