CSS Grid minmax with auto as min - html

I'm wanting to have a grid with two columns where the leftmost column will scale based on the width of its content, but will not exceed 33% of the grid width.
However, it appears that grid-template-columns: minmax(auto, 33%) auto does not work as intended. The leftmost column is always at 33% width even if the content is smaller.
I'm probably misunderstanding what minmax is supposed to accomplish. Is there some other way to achieve what I'm trying to do?
.main {
display: grid;
grid-template-columns: minmax(auto, 33%) auto
}
.firstcol {
background: lightgreen;
}
.secondcol {
background: lightblue;
}
<div class="main">
<div class="firstcol">Short text</div>
<div class="secondcol">Some more text</div>
</div>
<hr />
<div class="main">
<div class="firstcol">This text is wayyyyyy to long and it should be wrapped</div>
<div class="secondcol">Some more text</div>
</div>

What about using grid-template-columns: fit-content(33%) 1fr
.main {
display: grid;
grid-template-columns: fit-content(33%) 1fr;
}
.firstcol {
background: lightgreen;
}
.secondcol {
background: lightblue;
}
<div class="main">
<div class="firstcol">Short text</div>
<div class="secondcol">Some more text</div>
</div>
<hr />
<div class="main">
<div class="firstcol">This text is wayyyyyy to long and it should be wrapped</div>
<div class="secondcol">Some more text</div>
</div>

Related

Having problems with fitting content in div with css grid

I'm playing around with Css Grid and having problems with fitting overlaying content.
There is a top level container defined as css grid (class="container"), then content grid (class="content") which splits into 3 rows (header, label, rows).
Header is just a header, label contains labels for rows and rows is a content of "table".
Here is what it looks like:
When I resize window I got scroll bar on the right but it's for the whole page. Instead I would like to scroll only rows not the whole page.
Here is the the StackBlitz working example:
https://stackblitz.com/edit/angular-ivy-ayujp5
I guess it's simple but having problems with understanding how height is calculated and where and how overflow properties should be defined.
p {
font-family: Lato;
}
.container {
display: grid;
grid-template-columns: 30px 1fr 30px;
grid-template-rows: 30px 1fr 30px;
grid-template-areas: '. . .' '. content .' '. . .';
}
.content {
grid-area: content;
display: grid;
grid-template-rows: 50px 30px 1fr;
grid-template-areas: 'header' 'label' 'rows';
}
.header {
grid-area: header;
}
.label {
grid-area: label;
display: grid;
grid-template-rows: 1fr;
grid-template-columns: repeat(3, 4fr);
align-items: center;
}
.rows {
grid-area: rows;
height: 100%;
}
.row {
background-color: pink;
margin: 5px 0px;
border-width: 1px;
border-radius: 10px;
padding: 25px;
color: black;
}
<div class="container">
<div class="content">
<div class="header">Header</div>
<div class="label">
<div>Name</div>
<div>From</div>
<div>To</div>
</div>
<div class="rows">
<div class="row">
<div class="label">
<div>1</div>
<div>1999/01/01</div>
<div>1999/12/01</div>
</div>
</div>
<div class="row">
<div class="label">
<div>2</div>
<div>1999/01/01</div>
<div>1999/12/01</div>
</div>
</div>
<div class="row">
<div class="label">
<div>2</div>
<div>1999/01/01</div>
<div>1999/12/01</div>
</div>
</div>
<div class="row">
<div class="label">
<div>3</div>
<div>1999/01/01</div>
<div>1999/12/01</div>
</div>
</div>
<div class="row">
<div class="label">
<div>4</div>
<div>1999/01/01</div>
<div>1999/12/01</div>
</div>
</div>
</div>
I go with height calculation .pin-table { height: calc(100vh - 125px); overflow: auto; } but if anyone has better idea feel free to write.

Convert template to pure css grid

I am trying to build a minor template, more specific this is what I am trying to do in css grid layout:
I am not convinced that my way is the modern approach, and would like to know if there is a pure way of doing this in only css grid, instead of mixing it with hights?
This is my fiddle of what I have tried:
https://jsfiddle.net/uwbsd2g6/
.wrapper {
display: grid;
grid-template-columns: 50% 50%;
}
.wrapper .col {
border: 1px solid blue;
min-height: 500px;
}
.wrapper .col-v-1 {
height: 50%;
}
.wrapper .col-v-2 {
height: 50%;
color: #fff;
background-color: blue;
}
<div class="wrapper">
<div class="col">
<div class="col-v-1">Here is some text</div>
<div class="col-v-2">Heres is another text</div>
</div>
<div class="col">
This is a third text
</div>
</div>
You can do this purely with css grid (assuming that you have an element with 100% height of the container as the parent) by using grid-template-column and grid-template-row as seen below
<style>
.wrapper {
height:100vh;
}
.outline{
outline: 1px red solid;
}
.grid {
display:grid
}
.grid-cols-2 {
grid-template-columns: 1fr 1fr;
}
.grid-rows-2 {
grid-template-rows: 1fr 1fr;
}
</style>
<div class="wrapper outline grid grid-cols-2">
<div class="grid grid-rows-2 outline">
<div class="outline">Here is some text</div>
<div class="outline">Heres is another text</div>
</div>
<div class="outline">
This is a third text
</div>
</div>
You can do it with grid template column and row

CSS Grid: auto height including 1 column with multiple content blocks?

I've checked out https://gridbyexample.com/example and have been trying myself to make this work, but can't get it to fit right. Check out the attached image for what I'm trying to do. Is there an easy CSS-Grid way to do this?
What I have so far for CSS:
.main-container {
display: grid;
grid-gap: 15px;
grid-template-columns: repeat(auto-fit, minmax(225px, 1fr));
}
.box {
height: min-content;
}
/* Targeting the 2nd content block in column 3 */
.box.d {
grid-column: 3/6;
}
What I have so far for HTML:
<div class="main-container">
<div class=-"box a">Content Here</div>
<div class=-"box b">Content Here</div>
<div class=-"box c">Content Here</div>
<div class=-"box d">Content Here</div>
<div class=-"box e">Content Here</div>
<div class=-"box f">Content Here</div>
<div>
I think this is what you're looking for:
codepen
.main-container {
display: grid;
grid-gap: 15px;
grid-template-columns: repeat(auto-fit, minmax(225px, 1fr));
grid-template-rows: 2fr 2fr 1fr;
background: #ccc;
padding: 20px;
width: 1200px;
}
.box {
background: #fff;
padding: 20px;
}
.box.d {
grid-area: 2 / 3 / 4 / 3;
}
.box.b {
grid-area: 1 / 2 / 3 / 3;
}
<div class="main-container">
<div class="box a">Content Here</div>
<div class="box b">Content Here</div>
<div class="box c">Content Here</div>
<div class="box d">Content Here</div>
<div class="box e">Content Here</div>
<div class="box f">Content Here</div>
<div>
But it sometimes depends on the content of the columns.

CSS grid create not equal grid

started using CSS grid instead of boostrap, and im having some issue to get it right.
i want to create a grid layout that have 4fr, and 8fr columns (just like boostrap 8 and 4 columns)
and when the divs inside the grid of 4r gets fill its the divs go to a second row just like flex-wrap:wrap.
BUT Its not work its only push it inline one after another, and ignoring the grid boundaries
.home {
display: grid;
grid-template-columns: 4fr 8fr;
grid-template-rows: 100%;
height: 100%;
}
<div class="home">
<div class="col-8">
</div>
<div class="col-4">
<mat-button-toggle-group class="side-menu-button">
<mat-button-toggle>test </mat-button-toggle>
<mat-button-toggle>test</mat-button-toggle>
<mat-button-toggle>test</mat-button-toggle>
<mat-button-toggle>test</mat-button-toggle>
<mat-button-toggle>test</mat-button-toggle>
<mat-button-toggle>test</mat-button-toggle>
<mat-button-toggle>test</mat-button-toggle>
<mat-button-toggle>test</mat-button-toggle>
</mat-button-toggle-group>
</div>
</div>
i even tried changing it to
grid-template-columns: repeat(1, auto-fill, 4fr 8fr);
If you're just wanting to use the grid to have items wrap inside of a div, what you're doing should basically work. Don't forget to tell .col-8 and .col-4 where they belong inside of the grid you've set up, and set the children you want to wrap to inline-block:
* {
box-sizing: border-box;
}
.home {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 100%;
height: 100%;
width: 100%;
grid-gap: 20px;
}
.col-8 {
grid-area: 1/1/1/9;
}
.col-4 {
grid-area: 1/9/1/13;
}
.bluebox,
.blackbox {
display: inline-block;
width: 50px;
height: 20px;
}
.bluebox {
background-color: blue;
}
.blackbox {
background-color: black;
}
<div class="home">
<div class="col-8">
<div class="bluebox"></div>
<div class="bluebox"></div>
<div class="bluebox"></div>
<div class="bluebox"></div>
<div class="bluebox"></div>
<div class="bluebox"></div>
<div class="bluebox"></div>
<div class="bluebox"></div>
<div class="bluebox"></div>
<div class="bluebox"></div>
</div>
<div class="col-4">
<div class="blackbox"></div>
<div class="blackbox"></div>
<div class="blackbox"></div>
<div class="blackbox"></div>
<div class="blackbox"></div>
<div class="blackbox"></div>
<div class="blackbox"></div>
<div class="blackbox"></div>
<div class="blackbox"></div>
<div class="blackbox"></div>
</div>
</div>
The reason I set up 12 columns instead of one that's 8fr and one that's 4fr is because I'm unclear about whether you're wanting a 12 column usable system like bootstrap (which is the way I implemented it), or literally only two columns. Either way should function for what you are describing in your question, but 12 separate columns is arguably more extensible later-on.
Here's a pen that contains the above code:
https://codepen.io/grantnoe/pen/MdOQOv
grid-area is what I used to set the location of .home's children. The format is as follows:
grid-area: <row-start> / <column-start> / <row-end> / <column-end>;
The only caveat is that you've nested the children you're wanting to wrap inside of secondary element <mat-button-toggle-group>. Consider adjusting the width of that element to 100% to fill the grid's child .col-4.

CSS grid and inline-block design issue

I have made a blog design using CSS grid, having used inline-block to pack DIVs together.
In my blog I have 2 picture-DIVS of height 60 that I want to show next to a text-DIV of height 120. Only the first picture is shown next to the text.
Why is the second picture shown below the text, and please get some pointers on how I can fix this.
.GridCont {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: auto auto auto;
grid-template-areas: "content content content content" "content content content content" "content content content content";
}
.PostContent {
grid-area: content;
background: #B8E986;
}
.Content {
background: #000000;
width: 35%;
color: white;
display: inline-block;
}
.box1 {
height: 120vh;
}
.PicContent {
background: blue;
color: white;
display: inline-block;
}
.pic1 {
height: 60vh;
width: 50%;
}
.pic2 {
height: 60vh;
width: 45%;
}
.cTextP {
padding: 20px;
}
<div class="GridCont">
<div class="PostContent">
<div class="PicContent pic1">
<div class="cTextP">Picture #1</div>
</div>
<div class="Content box1">
<div class="cTextP">Content #1</div>
</div>
<div class="PicContent pic2">
<div class="cTextP">Picture #2</div>
</div>
</div>
</div>
Code is at this JS-fiddle
Why would the second image show right beneath the first? There is no reason for that.
The second image is on the second row.
The second row goes right beneath the first row.
More specifically, the first row is occupied by two elements: image #1 and the content box. The height of the first row is defined by the tallest element. In this case, that would the content box.
So, because image #1 doesn't extend the full height of row #1, there will be a gap between images.
Here's an even more detailed explanation of the problem:
Is it possible for flex items to align tightly to the items above them?
(It's a flexbox-related post, but the logic applies here, as well.)
Instead of inline-block, use Grid properties to get the content box to span both rows:
.PostContent {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 60vh 60vh;
grid-gap: 1em;
grid-template-areas: " pic1 box1 "
" pic2 box1 ";
}
.box1 {
grid-area: box1;
}
.pic1 {
grid-area: pic1;
}
.pic2 {
grid-area: pic2;
}
.PostContent { background: #B8E986; }
.PicContent { background: blue; color: white; }
.Content { background: #000000; color: white; }
.cTextP { padding: 20px;}
<div class="GridCont">
<div class="PostContent">
<div class="PicContent pic1">
<div class="cTextP">Picture #1</div>
</div>
<div class="Content box1">
<div class="cTextP">Content #1</div>
</div>
<div class="PicContent pic2">
<div class="cTextP">Picture #2</div>
</div>
</div>
</div>
revised jsfiddle
Also note that grid properties work only between parent and child elements.
This will fix your problem:
<div class="grid-container">
<div class="image1"></div>
<div class="image2"></div>
<div class="text"></div>
</div>
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas: "image1 image1 text text" "image2 image2 text text";
}
.image1 { grid-area: image1; }
.image2 { grid-area: image2; }
.text { grid-area: text; }
You can see the working example over here:
https://codepen.io/dennisperremans/pen/NeqNJp