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

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.

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

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

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;
}

grid layout with resize horizontal not resizing columns [duplicate]

This question already has an answer here:
resize column across multiple rows using html grid layout
(1 answer)
Closed 1 year ago.
I've got a grid layout and I'm using resize: horizontal on one. It lets me resize the box but it doesn't resize the other columns as I would expect it to.
html,
body,
.main {
height: 100%;
margin: 0;
}
.main {
display: grid;
grid-template-columns: minmax(100px, 200px) 1fr;
grid-template-rows: 50px 1fr;
gap: 2px 2px;
grid-auto-flow: row;
grid-template-areas: "header-box header-box" "left-box main-box";
}
.header-box {
background-color: lightblue;
grid-area: header-box;
overflow: hidden;
}
.left-box {
background-color: lightgreen;
grid-area: left-box;
resize: horizontal;
overflow: auto;
}
.main-box {
background-color: lightpink;
grid-area: main-box;
overflow: auto;
}
<div class="main">
<div class="header-box">header box</div>
<div class="left-box">left box</div>
<div class="main-box">main box</div>
</div>
minmax(100px, 200px) is as good as 200px if you want shrinking behavior change to minmax(100px, 1fr)
If you want the grid to responsed to the content rather than the available width of it's own parent change to display: inline-grid;
html,
body,
.main {
height: 100%;
margin: 0;
}
.main {
display:inline-grid;
grid-template-columns: minmax(100px, 1fr) 1fr;
grid-template-rows: 50px 1fr;
gap: 2px 2px;
grid-auto-flow: row;
grid-template-areas: "header-box header-box" "left-box main-box";
}
.header-box {
background-color: lightblue;
grid-area: header-box;
overflow: hidden;
}
.left-box {
background-color: lightgreen;
grid-area: left-box;
resize: horizontal;
overflow: auto;
}
.main-box {
background-color: lightpink;
grid-area: main-box;
overflow: auto;
}
<div class="main">
<div class="header-box">header box</div>
<div class="left-box">left box</div>
<div class="main-box">main box</div>
</div>

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>