I want to use CSS grid and the following is a mock-up of the aim:
I'm building an interface that should expand rightward to fill the browser screen; my current code causes column 2 of the outer grid to be as wide as the browser in addition to column 1; or maybe one of it's children is causing this and it's just expanding to accommodate. Either way, it's spilling off the page horizontally
So the code:
#main {
width: 100%;
display: grid;
grid-template-columns: 250px 100%;
grid-template-rows: 100px 100%;
}
#col-2-outer {
display: grid;
grid-template-columns: 250px auto;
grid-template-rows: 100%;
}
#row-1-inner {
grid-column: span 2;
}
#col-2-inner table {
width: 100%;
}
<div id="main">
<div id="col-1-outer"></div>
<div id="col-2-outer">
<div id="row-1-inner"></div>
<div id="row-2-inner">
<div id="col-1-inner"></div>
<div id="col-2-inner">
<table></table>
</div>
</div>
</div>
</div>
FYI, for the time being I've forgone template areas until I get a handle on the basics (unless this somehow solves my problem but I gather this is strictly a code organization feature?).
I'd suggest to change your markup with a 3x2 grid like below:
Remove the hierarchical structure like you have in your code and add one element for each section in the grid.
Note that in the rule grid-template-columns: 250px 150px auto, 250px is the width of your col-1-outer and 150px is the width of the col-1-inner.
Span the first column over the two rows by using grid-row: span 2
Span the first row in the second column by using grid-column: span 2.
Extend the table over the last grid item by using 100% width and height.
See demo below:
* {
border: 1px solid; /* For illustration */
}
#main {
width: 100%;
display: grid;
grid-template-columns: 250px 150px auto;
grid-template-rows: 100px auto;
}
#col-1-outer {
grid-row: span 2;
}
#row-1-inner {
grid-column: span 2;
}
#col-2-inner table {
width: 100%;
height: 100%;
}
<div id="main">
<div id="col-1-outer">col-1-outer</div>
<div id="row-1-inner">col2-row-1-inner</div>
<div id="col-1-inner">col2-row2-inner</div>
<div id="col-2-inner">
<table><tr><td>table</td></tr></table>
</div>
</div>
The 100% for the 2nd column in your grid-template-columns is based on the width of the container - rather than occupying the space outstanding within the container, it will push out to the right because the 2nd column is trying to match the width of the container.
Try changing this to auto and this should rectify the issue, as it will only take up the space up to the end of the container and no further.
Source: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns
Related
I'm trying to create a layout like this:
I want the grid height to be according to the content. The pagination area height to be according to its box-sizing and the image area to take up the rest of the available space. I'm relatively new to grid. Help would be highly appreciated.
This is what I'm getting:
.grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: repeat(2, min-content);
}
The problem is pagination and image sections takes half of the grid area. I do not want any section to have a fixed height in pixels.
Based on the response to a previous awnser here i have tried to make the changes that are being looked for.
From what i can gather you are describing 3 total elements Image, Pagination, Content
of these 3 total elements you would like
Content to occupy 100% of the width of the right side
Pagination to live on the left side and occupy a small amount that is just enough to fit the pagination
Image to live on the left side an occupy the remaining space
To do this we can still use grid we just need to specify different values for our template which I have done below. The key here is min-content
html body{
margin: 0px;
padding: 0px;
}
.your_main_class {
width: 100vw;
height: 100vh;
display: grid;
grid-template-columns: 50vw 50vw;
grid-template-rows: 1fr min-content;
grid-template-areas: "image cont"
"pagination cont";
}
div{
height: 100%;
width: 100%;
}
.image{
grid-area: image;
background: red;
}
.pagination{
grid-area: pagination;
background: blue;
}
.content{
grid-area: cont;
background: black;
}
<div class="your_main_class">
<div class="image"> Image </div>
<div class="pagination"> Pagination </div>
<div class="content"> content </div>
</div>
You can do that by specifying the area of the divs. Check the snippet bellow.
.your_main_class {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: repeat(3, 1fr);
}
.image{
grid-area: 1 / 1 / 3 / 6;
background: red;
}
.pagination{
grid-area: 3 / 1 / 4 / 6;
background: blue;
}
.content{
grid-area: 1 / 6 / 4 / 13;
background: black;
}
<div class="your_main_class">
<div class="image"> </div>
<div class="pagination"> </div>
<div class="content"> </div>
</div>
This question already has answers here:
How to create a CSS Grid Layout box that spans 2 columns and 2 rows?
(3 answers)
Make grid container fill columns not rows
(6 answers)
Closed 2 months ago.
I have a css-grid layout set up as 3 columns. When a certain media-query matches, i want it to instead flow as rows where the first column becomes the first row, covering the full with. Column two and three should become one row and share the space equally. How can i achieve that? (i know how to write a media query, code is for demonstrating only)
.thegrid {
display: grid;
grid-template-columns: 1fr auto auto;
gap: 40px;
}
<div class="thegrid">
<div>
content 1
</div>
<div>
content 2
</div>
<div>
content 3
</div>
</div>
If you keep the columns, and add grid-column: 1/-1 to the first div (this makes sure the div covers the complete grid area). Does that give the desired look?
You must display grid then when your #media screen hits its threshold it will begin to flex. You have to tell which rows you want to combine within your flexed column and how far to extend them. Hopefully this helps and makes sense. good luck!
.thegrid {
display: grid;
grid-template-columns: auto auto auto;
grid-template-rows: 80px 200px;
gap: 10px;
background-color: #2196F3;
padding: 10px;
}
#media only screen and (max-width: 600px) {
.thegrid {
display: grid;
grid-template-columns: auto auto auto;
grid-template-rows: 80px 200px;
gap: 10px;
background-color: #2196F3;
padding: 10px;
}
.row-1 {
grid-column: 1/ span 2;
grid-row: 1;
}
.row-2 {
grid-row: 2;
}
}
<div class="thegrid">
<div class="row-1">
content 1
</div>
<div class="row-2">
content 2
</div>
<div class="row-2">
content 3
</div>
</div>
I am trying to have a UI like this :
This is how I have tried doing it :
A div at the top as cover Image
The next div containing two child divs as profile photo & UI details as -
<div>Image Cover photos<div>
<div style="display : flex;">
<div>profile photo</div>
<div>UI Details Card</div>
</div>
Then I'm using the transform : translateY(-50%) to the profile photo div to move 50 percent of the portion on top of the background cover photo.
This, however creates a problem, the UI details remains at the same place(which is ideal), but the baseline has been changed.I want it to have only 50% of the height, so the baseline matches with the profile photo as well, and also UI details wcard will have some text, I do not want it to overlap on the Cover Image background as well(as that of profile photo). How can I achieve this?
One way to solve this problem is to use CSS grid to place everything.
body {
padding: 100px;
}
.card {
height: 300px;
width: 300px;
display: grid;
grid-template-columns: 1fr 2fr;
grid-template-rows: repeat(3, 1fr);
outline: 1px solid;
}
.details {
background-color: blanchedalmond;
grid-area: 3/2/4/3;
}
.photo {
background-color: aquamarine;
grid-area: 2/1/4/2;
}
.cover {
grid-area: 1/1/3/3;
background-color: grey;
}
.cover img,
.photo img {
height: 100%;
width: 100%;
}
<div class="card">
<div class="cover">
<img src="https://source.unsplash.com/random/?1" alt="">
</div>
<div class="photo">
<img src="https://source.unsplash.com/random/" alt="">
</div>
<div class="details">Details here</div>
</div>
Here's a diagram showing the different grid areas :
Notice the overlap region between the blue box (photo) and the red box (cover). Since the photo div appears after the cover div in the DOM, the photo div will have higher priority and will occupy this overlap region.
You can make a 2 column, 3 row grid and place items where you want them.
Here's a simple example:
.container {
display: grid;
grid-template-columns: 1fr 4fr;
grid-template-rows: 1fr 1fr 1fr;
width: 30vw;
height: 20vw;
}
.container :nth-child(1) {
grid-column: 1 / span 2;
grid-row: 1 / span 2;
background: red;
}
.container :nth-child(2) {
grid-column: 1;
grid-row: 2 / span 2;
background: green;
}
.container :nth-child(3) {
background: blue;
}
<div class="container">
<div></div>
<div></div>
<div></div>
</div>
Obviously you will want to alter the relative sizes of the grid to suit your particular case.
Note: it depends on whether you want to put some text in the first item so that it comes directly above the second item or not as to whether you start the first div in the first column or the second column.
I want to achieve 12 column grid behavior similar to what Bootstrap has,
but using CSS grids.
I need to have a fixed gapsĀ in pixels
And have a 12 column grid, so I can decide how to place the children.
I'm facing the issue, that combination of grid-template-columns and column-gap doesn't shrink the columns on a smaller screens, but cause horizontal overflow on a screen.
How can I achieve expected behavior with shrinking without reducing the number of columns and keeping the gap in pixels.
DEMO:
.parent {
max-width: 300px;
height: 500px;
overflow: auto;
border: 1px solid blue;
}
.box {
grid-column: span 6 / span 6;
background: red;
height: 40px;
}
.grid {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
gap: 40px;
}
<div class="parent">
<div class="grid">
<div class="box"></div>
<div class="box"></div>
</div>
</div>
I am wondering if the first two rows of my CSS grid can be equal to the height of the screen excluding the header. The content container below the header has been set to overflow: auto, but I would want only my first two rows of the grid to be equal to the height of the content container (without overflowing). My grid has a total of 3 rows, and basically, I want the first two rows to take up the entire height of the container without overflowing, followed by the third row being completely invisible to the screen unless the container is scrolled down. Do let me know if my explanation is confusing, as I am new to CSS grid, and not too sure if my explanation has been sufficient. Thanks all, and I look forward to your replies!
Here's a sample of my HTML layout
<div class='entire'>
<div class='header'>Header</div>
<div class='content'>
<div class='grid'>
item 1
item 2
item 3
</div>
</div>
</div>
CSS
.entire {
height: 100vh;
}
.content {
overflow: auto;
}
.grid {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: ___ ____ ____;
}
The height of .header should be defined in CSS. If not - it should be get by JS. Let's agree with definition in CSS.
Taking into account your last comment about 1st and 2nd row which should be both fit into one screen, 1st should take auto height and 2nd - all the rest height, I don't see any evidence to include the block 3rd into the grid at all. Moved it away.
html,
body {
margin: 0;
padding: 0;
height: 100%;
}
.entire {
height: 100vh;
}
.header {
background: cyan;
height: 20px;
}
.content {
overflow: auto;
}
.grid {
/* subtracting known height of .header */
height: calc(100vh - 20px);
display: grid;
grid-template-columns: 1fr;
/* this will make 1st row auto height and 2nd - all the rest */
grid-template-rows: auto 1fr;
}
.item1 {
background: #eee;
}
.item2 {
background: #ddd;
}
.item3 {
background: #ccc;
height: 100vh;
}
<div class="entire">
<div class="header">Header</div>
<div class="content">
<div class="grid">
<div class="item1">item 1</div>
<div class="item2">item 2</div>
</div>
<div class="item3">item 3</div>
</div>
</div>