I'm trying to make a page with a simple 3x3
grid layout: header top, footer bottom, two sidebars, and the main display. Everything works fine until I add the SVG element that should fill the main-display div:
<div class="main">
<svg viewBox="0 0 500 500"></svg>
</div>
The whole grid layout gets confused at this point, with the browser eliminating the header, extending the page below the height: 100%
that I have declared, etc.
I can easily "fix" this by setting my SVG max-height
and max-width
arbitrarily small (below ~60% in Firefox 62.0.3; in Safari 12.0, <90%). But that isn't really a fix since it leaves a conspicuous gap (a huge one in Firefox). I much prefer to size my SVG 100%
to fill its space in the grid. I must be missing something. What am I doing wrong?
Edit: Adding a screenshot of what I want and (one version of) what I have.
Here is what I have. Here is what I want.
The stylesheet for what you see is below. The only difference between the two images is the change in max-width
and max-height
from 10%
to 100%
.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
display: grid;
border-style: solid; // to show that body renders improperly
border-color: red;
grid-template-columns: 3fr 9fr 2fr;
grid-template-rows: 1fr 10fr 1fr;
width: 100vw;
height: 100vh;
}
div {
border: solid black 1px; // to show div positions
}
.header {
grid-column: 1 / 4;
grid-row: 1;
}
.main {
grid-column: 2;
grid-row: 2;
}
.side1 {
grid-column: 1;
grid-row: 2;
}
.side2 {
grid-column: 3;
grid-row: 2;
}
.footer {
grid-column: 1 / 4;
grid-row: 3;
}
svg {
max-height: 100%;
max-width: 100%;
}
<body>
<div class="header">Header</div>
<div class="side1">Site 1</div>
<div class="main">
<svg viewBox="0 0 500 500"></svg>
</div>
<div class="side2">Site 2</div>
<div class="footer">Footer</div>
</body>
Not only does it mean that SVG properties can be styled using CSS as presentation attributes or in style sheets, but this also can be applied to CSS pseudo-classes such as :hover or :active . SVG 2 also introduces more presentation attributes that can be used as styling properties.
You can "nest" grids by making a grid item a grid container. These grids however are independent of the parent grid and of each other, meaning that they do not take their track sizing from the parent grid. This makes it difficult to line nested grid items up with the main grid.
It turns out that the problem is not with the svg element at all, but with its containing div (.main
in the question's code snippet). Like flex items, grid items have a default min-width: auto
and min-height: auto
. By setting them to 0
, the svg is able to size automatically, as it should.
I still don't quite understand why the svg disrupted the layout, especially when it was set to 80%
in Firefox, leaving conspicuous space around it, but the problem with the grid layout itself is clear enough.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
display: grid;
grid-template-columns: 3fr 9fr 2fr;
grid-template-rows: 1fr 10fr 1fr;
width: 100vw;
height: 100vh;
}
div {
border: solid black 1px; // to show div positions
}
.header {
grid-column: 1 / 4;
grid-row: 1;
}
.main {
grid-column: 2;
grid-row: 2;
min-width: 0;
min-height: 0;
}
.side1 {
grid-column: 1;
grid-row: 2;
}
.side2 {
grid-column: 3;
grid-row: 2;
}
.footer {
grid-column: 1 / 4;
grid-row: 3;
}
svg {
max-height: 100%;
max-width: 100%;
}
<body>
<div class="header">Header</div>
<div class="side1">Site 1</div>
<div class="main">
<svg viewBox="0 0 500 500"></svg>
</div>
<div class="side2">Site 2</div>
<div class="footer">Footer</div>
</body>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With