How to Center Empty CSS Grid in Div and Maintain Aspect Ratio - html

I'm trying to center an empty CSS grid in a div. I need the grid to maintain a 16:9 aspect ratio and fill as much space as possible in the div. It is the only element in the div, and the div will change size since there are collapsible sidebars and a collapsible header in the full document.
The code below maintains the aspect ratio and fills the space, but when I try to center it the grid shrinks to the minimum size.
I have tried to center using place-self: center center; in the grid's CSS and place-content: center center; in the div's CSS, but both of those shrink the grid.
The container div does not have to be a grid if that makes it easier.
Code snippet :
html, body {
width: 100%;
height: 100%;
margin: 0px;
}
.container {
width: 100%;
height: 100%;
display: grid;
}
.canvas-grid {
border: solid red 3px;
max-width: fit-content;
max-height: fit-content;
aspect-ratio: 16 / 9;
margin: 5px;
display: grid;
grid-template-columns: repeat(16, 1fr);
grid-template-rows: repeat(9, 1fr);
grid-column-gap: 3px;
grid-row-gap: 3px;
}
<html>
<link rel="stylesheet" href="styles.css">
<body>
<div class="container">
<div class="canvas-grid"></div>
</div>
</body>
</html>

Try 100vh height
<html>
<link rel="stylesheet" href="styles.css">
<body>
<div class="container">
<div class="canvas-grid"></div>
</div>
</body>
</html>
CSS:
html, body {
width: 100%; /* Does nothing, already 100% height by default */
height: 100%; /* 100% of auto does nothing */
margin: 0px;
}
.container {
width: 100%; /* div is block by default already takes up 100% width */
min-height: 100vh;
place-content: center;
display: grid;
}
.canvas-grid {
border: solid red 3px;
max-width: fit-content;
max-height: fit-content;
aspect-ratio: 16 / 9;
margin: 5px;
display: grid;
grid-template-columns: repeat(16, 1fr);
grid-template-rows: repeat(9, 1fr);
grid-column-gap: 3px;
grid-row-gap: 3px;
}

Related

Is it possible to collapse a css grid column if the contents are empty

I have a component with an OK/Cancel button, where I want the buttons both the same width regardless of the text size (eg different cultures)
So, a simplified mockup which is close to what I have is...
<div id="container">
<div class="button">OK</div>
<div class="button">Cancel</div>
</div>
#container {
background: green;
right: 0;
position: absolute;
display: grid;
grid-template-columns: 1fr minmax(0, 1fr)
}
.button {
text-align: center;
padding: 5px;
min-width: 40px;
width: auto;
margin: 5px;
background: yellow;
}
Can also see at this codepen
So, we can see if the OK text is long, then the Cancel button also grows to the same width
However, the component I am using (3rd party) also used the OK for just close
eg
<div id="container">
<div class="button">Close</div>
</div>
and now I have an unwanted gap on the right hand side
I can target the component classes, but not the structure.
So, is there any way via just CSS I can have this grid to act like a grid-template-columns: 1fr 0 if the second div is not there?
You may check if the span is the :only-child and make it span both columns
#container {
background: green;
right: 0;
position: absolute;
display: grid;
grid-template-columns: 1fr minmax(0, 1fr)
}
.button {
text-align: center;
padding: 5px;
min-width: 40px;
width: auto;
margin: 5px;
background: yellow;
}
.button:only-child {
grid-column: span 2;
}
<p>Test :only-child</p>
<div id="container">
<div class="button">Close</div>
</div>
https://developer.mozilla.org/en-US/docs/Web/CSS/:only-child
You can use the 'auto' value like this:
#container {
background: green;
right: 0;
position: absolute;
display: grid;
grid-template-columns: auto minmax(0, 1fr)
}
you can find more info here: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-columns

why does child divs take 100% height of parent div with display: grid

I have a paren div which is has display grid and height 100%. for some reason all the children divs inside it now have height 100% even though i didnt specify the height to have 100%. How can i make the child divs have the height based on their content.
.parent {
height: 100%;
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
gap: 0;
}
.child {
width: 100%;
display: flex;
background: red;
}
<div class="parent">
<div class="child">
<div class="child-1">
child
</div>
</div>
</div>
Cause
The reason is that the default value for the CSS property align-items on a grid-container is normal. This property defines the align-self behaviour (vertical alignment) of those grid cells which don't explicitly set align-self.
See MDN:
normal
The effect of this keyword is dependent of the layout mode we are in:
In absolutely-positioned layouts, the keyword behaves like start on replaced absolutely-positioned boxes, and as stretch on all other absolutely-positioned boxes.
In static position of absolutely-positioned layouts, the keyword behaves as stretch.
For flex items, the keyword behaves as stretch.
For grid items, this keyword leads to a behavior similar to the one of stretch, except for boxes with an aspect ratio or an intrinsic sizes where it behaves like start.
The property doesn't apply to block-level boxes, and to table cells.
html, body { height: 100%; margin: 0; color: white; }
.parent {
background-color: orange;
height: 100%;
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
gap: 10px;
}
.child {
background-color: red;
width: 100%;
}
<div class="parent">
<div class="child">
child 1
</div>
<div class="child">
child 2
</div>
</div>
Solution
If you want all your grid-cells to start at the top of the cell and have height: auto, simply apply align-items: start; on your grid container:
html, body { height: 100%; margin: 0; color: white; }
.parent {
background-color: orange;
height: 100%;
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
gap: 10px;
align-items: start;
}
.child {
background-color: red;
width: 100%;
}
<div class="parent">
<div class="child">
child 1
</div>
<div class="child">
child 2
</div>
</div>
If you want only some of your grid-cells to start at the top of the cell and have height: auto, simply apply align-self: start; on those grid cells:
html, body { height: 100%; margin: 0; color: white; }
.parent {
background-color: orange;
height: 100%;
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
gap: 10px;
}
.child {
background-color: red;
width: 100%;
}
.auto-height {
align-self: start;
}
<div class="parent">
<div class="child auto-height">
child 1
</div>
<div class="child">
child 2
</div>
</div>

Tracks of CSS grid not shrinking when other tracks grow [duplicate]

This question already has an answer here:
Why does minmax(0, 1fr) work for long elements while 1fr doesn't?
(1 answer)
Closed 3 years ago.
In the following code, why do the grid track cells not dynamically shrink when the other cells are enlarged?
In the snippet, if you hover over any track section, that cell grows to 75% of the viewpoint, however rather than the other sections of the grid shrinking to accommodate the newly sized section, they all stay at their original size causing the cells to expand out beyond the size of the grid.
I would like to create sections of the grid that can be resized by hovering over them with the other sections of the grid shrinking to accommodate the new size.
Is there a way to do this, and more importantly, why does my code not work?
.grid--container {
height: 100vh;
width: 100vw;
max-height: 100%;
max-width: 100%;
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);
border: 1px solid red;
}
.track--section {
border: 1px dotted grey;
min-height: 0;
min-width: 0;
}
.track--section:hover {
background-color: #333;
height: 75vh;
width: 75vw;
}
<div class="grid--container">
<div class="track--section">section1</div>
<div class="track--section">section2</div>
<div class="track--section">section3</div>
<div class="track--section">section4</div>
</div>
Because you have 1fr in both your row and column definitions, the horizontal and vertical space is constrained - so they will be equally shared by the grid items. Try changing this to auto for both rows and columns and you can see things working just about okay, but not perfect yet - note that there are whitespaces around the hovered grid items:
.grid--container {
height: 100vh;
width: 100vw;
max-height: 100%;
max-width: 100%;
display: grid;
grid-template-columns: auto auto; /* changed */
grid-template-rows: auto auto; /* changed */
border: 1px solid red;
}
.track--section {
border: 1px dotted grey;
min-height: 0;
min-width: 0;
}
.track--section:hover {
background-color: #333;
height: 75vh;
width: 75vw;
}
<div class="grid--container">
<div class="track--section">section1</div>
<div class="track--section">section2</div>
<div class="track--section">section3</div>
<div class="track--section">section4</div>
</div>
Solution
You can try this:
a 2 column layout using grid-template-columns: 1fr 1fr
implicit rows for this using grid-auto-rows: 1fr
See demo below:
.grid--container {
height: 100vh;
width: 100vw;
max-height: 100%;
max-width: 100%;
display: grid;
grid-template-columns: 1fr 1fr; /* 2 columns */
grid-auto-rows: 1fr; /* implicit rows */
border: 1px solid red;
}
.track--section {
border: 1px dotted grey;
min-height: 0;
min-width: 0;
}
.track--section:hover {
background-color: #333;
height: 75vh;
width: 75vw;
}
<div class="grid--container">
<div class="track--section">section1</div>
<div class="track--section">section2</div>
<div class="track--section">section3</div>
<div class="track--section">section4</div>
</div>
You can read more about Explicit and Implicit Grids here: CSS Grid unwanted column added automatically.

Makings spaces between columns using grid layout

I have a problem with making spaces between grid elements. This is my HTML code:
<div class="container">
<div class="col">Hello1</div>
<div class="col">Hello2</div>
<div class="col">Hello3</div>
<div class="col">Hello4</div>
</div>
And this is my CSS code:
body {
background-color: green;
}
.col {
margin: 0 2vw;
padding: 1vh 1vw;
}
.container {
width: 80vw;
margin: 0 auto;
display: grid;
grid-template-columns: 25% 25% 25% 25%;
background-color: maroon;
}
I have used this layout before, and it has worked just fine, but for some reason this doesn`t work now. I want to make space between each of the four columns, and make that space the same colour of the background color (in this case green).
Use grid gap for spacing and move the background color to grid item instead of grid container so you can see the gap:
body {
background-color: green;
}
.col {
padding: 1vh 1vw;
background-color: maroon;
}
.container {
width: 80vw;
margin: 0 auto;
display: grid;
grid-gap:2vw;
grid-template-columns: 1fr 1fr 1fr 1fr;
}
<div class="container">
<div class="col">Hello1</div>
<div class="col">Hello2</div>
<div class="col">Hello3</div>
<div class="col">Hello4</div>
</div>

Css grid header not displaying right on Chrome and Opera but works on Firefox

First time I'm trying to make a website layout using grid and it works just fine on Firefox. Header takes all the desired space but on Chrome and Opera it clumps with all its content into more less 1/3 of the width leaving the rest empty. Everything else besides the header works fine on every browser, including the mobile layout.
All my browsers are up to date.
I don't know how to approach the issue.
div.container {
display: grid;
grid-template-columns: auto 1fr auto;
grid-template-rows: auto 1fr;
grid-template-areas:
"site-header site-header site-header"
"site-nav content sidebar";
grid-gap: 0;
max-width: 100%;
min-height: 100%;}
.site-header {
grid-area: site-header;
height: 250px;
border-bottom: 2px solid #999;
text-align: center;
display: table;
background-color: green;}
It seems to be a problem with display: table inside a Grid. In your situation, Chrome computes the width to 0.
If you explicitly set the width property it appears to work.
fiddle
div.container {
display: grid;
grid-template-columns: auto 1fr auto;
grid-template-rows: auto 1fr;
grid-template-areas: "site-header site-header site-header" "site-nav content sidebar";
grid-gap: 0;
max-width: 100%;
min-height: 100%;
background: grey;
}
.site-header {
grid-area: site-header;
height: 250px;
border-bottom: 2px solid #999;
text-align: center;
display: table;
background-color: green;
width: 100%;
}
<div class="container">
<header class="site-header"></header>
</div>