Home > Mobile >  SVG aspect ratio is preserved when width is greater than height despite of the preventive setting
SVG aspect ratio is preserved when width is greater than height despite of the preventive setting

Time:05-08

I want the blue line to always connect top left and bottom right corners without overflow and scroll bar being displayed. Currently it only happens for when the width is less than height (more or less), otherwise it increases the height thus resulting in a screen overflow and scrollbar being displayed. No preserveAspectRatio option seems to give it out of the box. I'm looking for a markup only solution ideally.

<!DOCTYPE html>
<html style="height: 100%;">

<body style="height: 100%; margin: 0;">
    <div
        style="width: 100%; height: 100%; display: grid; grid-template-rows: min-content auto; grid-template-columns: auto;">
        <div style="grid-row: 1; grid-column: 1; border-bottom: 1px solid #ccc;">
            <p style="margin: 5px;">Header</p>
        </div>
        <div style="grid-row: 2; grid-column: 1; display: grid;">
            <svg width="100%" height="100%" viewBox="0 0 1000 1000" preserveAspectRatio="none">
                <polyline points="0,0 1000,1000" stroke="blue" stroke-width="5px" />
            </svg>
        </div>
    </div>
</body>

</html>

Edit: Working sample following the brilliant explanation from Dave:

<!DOCTYPE html>
<html style="height: 100%;">

<body style="height: 100%; margin: 0;">
    <div
        style="width: 100%; height: 100%; display: grid; grid-template-rows: min-content minmax(0, 1fr); grid-template-columns: auto;">
        <div style="grid-row: 1; grid-column: 1; border-bottom: 1px solid #ccc;">
            <p style="margin: 5px;">Header</p>
        </div>
        <div style="grid-row: 2; grid-column: 1; display: grid;">
            <svg width="100%" height="100%" viewBox="0 0 1000 1000" preserveAspectRatio="none">
                <polyline points="0,0 1000,1000" stroke="blue" stroke-width="5px" vector-effect="non-scaling-stroke" />
            </svg>
        </div>
    </div>
</body>

</html>

CodePudding user response:

If I've understood correctly, you want the svg to change aspect ratio such that the diagonal line is always wholly in view.

Your svg is structured correctly to do this with preserveAspectRatio="none" on an image drawn with user units for the line and viewbox matching.

The reason your svg is extending beyond the page height is because the container div extends beyond the page height.

I've added a class to the parent div containing the svg and styled it to have height of 100vh ( minus a nominal pixel value to ensure scroll bars don't show). I also gave the div a border so you can see it now occupies the viewable screen and the SVG remders the line from top left to bottom right corners.

On a resizable page, the div will resize and the svg will change aspect ratio to always occupy it.

.svgFrame {
border: 1px solid red;
width: 100%;
height: calc(100vh - 20px);
}
        <div  style="grid-row: 2; grid-column: 1; display: grid;">
            <svg width="100%" height="100%" viewBox="0 0 1000 1000" preserveAspectRatio="none">
                <polyline points="0,0 1000,1000" stroke="blue" stroke-width="5px" />
            </svg>
        </div>

The key is to constrain the parent div such that it remains entirely in view on the page; without constraint the preserveAspectRatio="none" has no effect as the there is no reason to change the aspect ratio.

In this example based on a grid layout, styling the grid containing the parent div using minmax(0, 1fr) had the desired effect.

  • Related