Bootstrap Column Width Ratios - css

The Bootstrap grid system is of course 12 columns.
I want to have and use all the 12 columns across the page.
But I want the first 6 left-hand columns to be half the width (i.e 50%) of the right-hand columns width.
So that the right 6 column will always be double width of the ones on the left.
This width ratio should remain across changing page/window resizing.
How can I do that? Thanks.

This task is not for a boostrap grid system. 12 parts mean 12 equal width parts. And you want not equal 12 block. This is a task for display: grid;.
grid-template-columns: repeat(6, 2fr) repeat(6, 1fr); this part means that we take 6 times for 2fr and then 6 times for 1fr. fr is a new measure for grid. It means all grid is devides on a sum all frs in one row. So 2fr is a block twice bigger then 1fr. In our case we have 2fr 2fr 2fr 2fr 2fr 2fr 1fr 1fr 1fr 1fr 1fr 1fr = 18 parts in a row. It's just for you to know hove does fr works.
Links for some CSS Grid documentation:
Basic Concepts of grid layout
grid-template-columns
.grid-row {
display: grid;
grid-template-columns: repeat(6, 2fr) repeat(6, 1fr);
grid-auto-rows: auto;
grid-row-gap: .5rem;
grid-column-gap: .5rem;
}
.grid-col {
background: #000;
min-height: 50px;
}
/* example of adaptivity for smaller screens */
#media (max-width: 500px) {
.grid-row {
grid-template-columns: repeat(3, 2fr) repeat(3, 1fr);
}
}
<div class="grid-row">
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
</div>
Not sure, but if you want not twice, but 1.5 times wider cols, use next one. Updated only grid-template-columns: repeat(6, 3fr) repeat(6, 2fr);
.grid-row {
display: grid;
grid-template-columns: repeat(6, 3fr) repeat(6, 2fr);
grid-auto-rows: auto;
grid-row-gap: .5rem;
grid-column-gap: .5rem;
}
.grid-col {
background: #000;
min-height: 50px;
}
/* example of adaptivity for smaller screens */
#media (max-width: 500px) {
.grid-row {
grid-template-columns: repeat(3, 3fr) repeat(3, 2fr);
}
}
<div class="grid-row">
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
</div>

Related

css grid fit rows heights

I want to remove the worthless margin between rows, so I want every div takes the content height without giving margin to his side div, I tried everything but nothing works.
.grids {
width: 90%;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(min-content, max-content);
margin: auto;
grid-gap: 32px;
}
.grid {
position: relative;
width: 95%;
height: max-content;
margin: 10px;
padding: 20px;
background: black;
border-radius: 10px;
}
<div class="grids">
<div class="grid"></div>
<div class="grid"></div>
<div class="grid"></div>
<div class="grid"></div>
<div class="grid"></div>
<div class="grid"></div>
</div>
Edit: To make a masonry layout I have wrapped grid items in div tag
so you can nest as many tags as you want.
grid items overflow the content because of the width and height properties.
you're using a grid gap for both rows and columns.
So I guess this might help you out.
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
grid-template-rows: masonry;
grid-gap: 10px;
}
.grid-item {
padding: 20px;
background: red;
border-radius: 10px;
margin-bottom: 24px;
}
<div class="grid">
<div>
<div class="grid-item">
<h1>Hello world</h1>
</div>
<div class="grid-item">
<h1>Hello world</h1>
</div>
</div>
<div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
<div>
<div class="grid-item">
<h1>Hello
<br>
friend
</h1>
</div>
<div class="grid-item"></div>
</div>
</div>
Also, I renamed the classes for naming purposes only.
MDN docs grid-row: row-gap
MDN docs masonry layout: masonry layout
You can try to set grid-gap: 32px to grid-gap: 0 32px, it will remove the margin between grid rows;

Move only one item in CSS Grid

Okay i know i can move my blocks using grid-template-areas or order.
But my question is: can i move only one item to another place without changing order of every other block? Because that is a few lines more of code and i wonder if it can be made easier?
I have a grid:
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(2, 1fr);
I want the item on the 1-st column and 1-st row to change position to 2-nd column and 1-st row. To switch places with the other block.
Simply specify the position using grid-column (and grid-row if needed) and make sure to use grid-auto-flow:dense to avoid empty areas:
.box {
display:grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(2, 1fr);
grid-auto-flow: dense;
grid-gap:10px;
}
.box * {
height:50px;
background:red;
color:#fff;
}
<div class="box">
<div style="grid-column:2">1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</div>
You can still use order. Just set all the children to order:1 and then set the order of the chosen item to 0
.grid {
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(2, 1fr);
}
.item {
border: 1px solid green;
padding: 1em;
}
.grid * {
order:1;
}
.grid :nth-child(2) {
order:0;
}
<div class="grid">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
</div>

Place all items in the center of the screen using CSS Grid

So basically what i want to do is to have 9 Boxes in the middle of the screen.
This is what i tried:
main {
border: 4px solid black;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
width: 100vw;
height: 100vh;
align-items: center;
justify-items: center;
}
.box1 {
background: red;
width: 50%;
}
.box2 {
background: blue;
width: 50%;
}
.box3 {
background: green;
width: 50%;
}
<main>
<div class="box1">
<h1>Box 1</h1>
</div>
<div class="box2">
<h1>Box 2</h1>
</div>
<div class="box3">
<h1>Box 3</h1>
</div>
<div class="box1">
<h1>Box 4</h1>
</div>
<div class="box2">
<h1>Box 5</h1>
</div>
<div class="box3">
<h1>Box 6</h1>
</div>
<div class="box1">
<h1>Box 7</h1>
</div>
<div class="box2">
<h1>Box 8</h1>
</div>
<div class="box3">
<h1>Box 9</h1>
</div>
</main>
This almost does what i want.
So what i get is this:
-b-b-b-
-b-b-b-
-b-b-b-
with - being free space.
What i want is this:
-bbb-
-bbb-
-bbb-
so that the 9 boxes actually touch each other.
Is there a way to do that?
(i want to hold on to the grid-template-columns: 1fr 1fr 1fr and grid-template-rows: 1fr 1fr 1fr)
tyvm :)
Is there a way to do that? (i want to hold on to the grid-template-columns: 1fr 1fr 1fr and grid-template-rows: 1fr 1fr 1fr)
No. There is no way to do this.
Because you've set your columns to 1fr each, they will spread across the width of the container in equal lengths. Therefore, the columns are not centered.
You would have to do something like this: grid-template-columns: 1fr auto auto auto 1fr, with the 1fr columns having no content and used solely for spacing. This set up would pin the three inner columns to the center.

CSS - Grid positioning if element does not exist

Is it possible to prepare the grid in such a way that if a given element is not present, it inserts the elements that are available? For example, if there is no first element, then in the first row we have "item middle item"?
<div class="grid-container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="middle"></div>
</div>
.grid-container {
display: grid;
grid-template-rows: repeat(3, auto);
grid-template-columns: repeat(3, 1fr);
grid-gap: 20px;
grid-template-areas:
"first first first"
". middle ."
". . .";
}
Example
If you add the following, that should do it:
.item:empty {
display: none;
}
You can see in this example, everything will back-fill into empty grid cells.
.grid-container {
display: grid;
grid-template-rows: repeat(3, auto);
grid-template-columns: repeat(3, 1fr);
grid-gap: 20px;
grid-template-areas:
"first first first"
". middle ."
". . .";
}
.item:empty {
display: none;
}
<div class="grid-container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="middle">m</div>
</div>

auto-fill and minmax() don't work when items are not the same size

I'm trying to make a fully responsive grid with different-sized items.
This example works fine with
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr) ) ;
body {
margin: 40px;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
<div class="box g">G</div>
<div class="box h">H</div>
<div class="box i">I</div>
</div>
All items are the same size and on the smallest screen size they line up on top of each other.
Now if you try the same with this example the items that have left the explicit grid and have to move again are not doing so but are shrinking under the specified minmax value. So on the smallest screen size some items cannot be seen.
body {
margin: 40px;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
.a {
grid-column: auto / span 2;
}
.k {
grid-column: auto / span 3;
}
.g {
grid-column: auto / span 2;
grid-row: auto / span 2;
}
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
<div class="box g">G</div>
<div class="box h">H</div>
<div class="box i">I</div>
<div class="box j">J</div>
<div class="box k">K</div>
<div class="box l">L</div>
<div class="box m">M</div>
</div>
Is there a way to get example 2 to behave like example 1, other than adding a media-query?
There's a big hint to the answer in what you wrote:
Now if you try the same with this example, the items that have left the explicit grid and have to move again are not doing so but are shrinking under the specified minmax value.
"...the items that have left the explicit grid..."
This is why your grid items are shrinking below the minmax minimum set in grid-template-columns.
Once you're not in the explicit grid, you're in the implicit grid, and the grid-template-columns property has no effect.
The explicit grid is defined by three properties:
grid-template-columns
grid-template-rows
grid-template-areas
Tracks in the implicit grid ignore these properties. Instead, they are sized using grid-auto-rows and grid-auto-columns.
The default value of grid-auto-columns is auto, which is why your grid items shrink to content size when they exit the explicit grid.
Try this:
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr) ) ;
grid-auto-columns: minmax(200px, 1fr); /* NEW */
}
Then, optionally, to make the grid fill empty cells when re-sizing, add this, too:
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr) ) ;
grid-auto-columns: minmax(200px, 1fr); /* NEW */
grid-auto-flow: dense; /* NEW */
}
body {
margin: 40px;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-auto-columns: minmax(200px, 1fr); /* NEW */
grid-auto-flow: dense; /* NEW */
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
.a {
grid-column: auto / span 2;
}
.k {
grid-column: auto / span 3;
}
.g {
grid-column: auto / span 2;
grid-row: auto / span 2;
}
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
<div class="box g">G</div>
<div class="box h">H</div>
<div class="box i">I</div>
<div class="box j">J</div>
<div class="box k">K</div>
<div class="box l">L</div>
<div class="box m">M</div>
</div>
revised codepen
The simplest answer is no, you can't. The reason is that when you combine auto-fill and minmax(200px, 1fr) you are telling to the browser rendering your code to make grid with columns with the minimum with of 200px and the maximum of 1fr. Then you are telling to your boxes to span 2 or 3 columns which means that they have minimum width of at least 400px or 600px on the big screen. On smaller screens, span rule starts to lose its meaning but auto does not take over. It still has to calculate width of individual columns taking into account individual width differences of .a .b .c etc.
So, unfortunately, you would need to use media queries or find some other type of layout.

Resources