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>
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:
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:
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"