CSS GRID content everywhere except last column in first row - css

Let's say there's a scenario where you have a grid with 3 columns and 2 rows, something like this:
<div class="wrapper">
<div class="content"></div>
<div class="info"></div>
</div>
Elements have these simple styles:
.wrapper {
position: relative;
display: grid;
grid-template-columns: 1fr 1fr 400px;
grid-template-rows: 400px auto;
}
.content {
grid-column: 1/4;
grid-row: 1/3;
}
.info {
position: absolute;
top: 0;
right: 0;
width: 400px;
height: 400px;
}
This would fill the contents of .content element to the whole .wrapper available space and the .info element would be positioned absolute over in the right top corner.
Is it possible to display the contents of .content into everything except to top right cell - like this (red is where the content is):

Related

Display grid center child elements horizontally

I'm sure this has been answered before but I can't seem to get it working. I'm trying to horizontally center grid items with a display:grid parent. I've got a 12 column grid (76px column / 56px gap at full screen), with various column width child elements (for this example I'll just use span 8 1000px).
.main-container{
max-width:1528px;
margin: 0 auto;
}
.parent{
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
grid-column-gap: 56px;
justify-items: center;
}
.grid-8{
grid-column: span 8;
background: red;
opacity: 0.6;
width: 100%;
}
<div class="main-container">
<div class="parent">
<div class="grid-8">8</div>
</div>
</div>
Also once the child element is centred is it possible for it to keep its width (1000px) until the .main-container starts to touch either side? once the browser starts to get pulled smaller (horizontally). Sorry, this is a little tricky for me to explain what I mean. The .main-container if the browser window is pulled in so this is at say 1200px wide the span 8 column will no longer be 1000px wide it will have shrunk (I'm guessing because it is relative to the main container size). But ideally, I'd like it to stay 1000px until the .main-container hits it and then the span 8 can start reducing in width.
Thanks
You can't align items in grid automatically with justify/align props.
You can try using grid-column-end: -N; syntax for each child nodes, but it's not best way to do that.
Much better to use flex - in this case you can align child nodes as you wish.
Anyway, if you want to continue working with grid, you can do something like this (like an option):
.main-container {
max-width: 1528px;
margin: 0 auto;
}
.parent {
--columns-amount: 12;
display: grid;
/*grid-template-columns: repeat(12, minmax(0, 1fr));*/
grid-template-columns: repeat(var(--columns-amount), 1fr);
grid-column-gap: 56px;
/*justify-items: center;*/
}
.grid-8 {
/* edit --column-size to see changes */
--column-size: 8;
grid-column: calc((var(--columns-amount) - var(--column-size)) / 2 + 1) / span var(--column-size);
background: red;
opacity: 0.6;
/*width: 100%;*/
}
/* flex */
.parent--flex {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.parent--flex>.grid-8 {
flex: 0 0 auto;
width: 66.66667%;
}
<div class="main-container">
<div class="parent">
<div class="grid-8">Grid</div>
</div>
</div>
<hr />
<div class="main-container">
<div class="parent--flex">
<div class="grid-8">Flex</div>
</div>
</div>

How to create UI with different size rows in CSS with grid/flex?

I need to create a UI as in the diagram, which will change its layout depending on the class passed to its elements (2 views).
the first layout looks like two columns, in the first column 2 divs (a and b) one on top another without a gap and the third div (c) in the second column aligned to the top.
the second layout - all 3 divs are in one column but the div from the second column(c) enters in between them (a and b)
I tried to use grid css and 2 columns for the first layout (grid-template-columns: auto auto) to turn it to one column in the 2nd view (grid-template-columns: auto) but the problem is that C block is longer than A so the grid row lengthens according to the longest div so there is a big gap between A and B. Any ideas preferably using flex or grid?
.a {
width: 50px;
height:30px;
background: pink;
}
.b {
width: 50px;
height:80px;
background: green;
}
.c {
width: 50px;
height:80px;
background: red;
}
.cont {
display: grid;
grid-template-columns: auto auto;
width: 120px;
}
<div class="cont">
<div class="a">A
</div>
<div class="c">C
</div>
<div class="b">B
</div>
</div>
The problem is that you're dealing with only two rows. An auto-sizing row will take the height of the tallest item. This will create a gap between shorter items and the bottom of the row.
Take a different approach:
Break down the rows to a common multiple for each grid item (i.e., 10px).
Have each item span across rows to achieve their height.
.cont {
display: grid;
grid-template-columns: 50px 50px;
grid-auto-rows: 10px;
grid-gap: 10px;
width: 120px;
}
.a {
grid-row: 1 / span 3;
grid-column: 1;
background: pink;
}
.b {
grid-row: 4 / span 8;
grid-column: 1;
background: green;
}
.c {
grid-row: 1 / span 8;
grid-column: 2;
background: red;
}
<div class="cont">
<div class="a">A</div>
<div class="b">B</div>
<div class="c">C</div>
</div>

CSS grid dimensions

I'd like to know if there is a way to limit the dimensions of a grid (not the element to which it's applied, the grid itself). I explain :
Let's say we've got a footer, with a dark background, spanning all the width of your page.
This footer contains 2 sub-blocks, classnames .footer__1 and .footer__2, and we want them to occupy 2/3 and 1/3 of the available width, with a 2rem gutter.
Is there a way to give the grid containing the two sub-blocks a grid-max-width (yes, i made that up) of 60rem, without changing the block width (remember, it has a background which must be full width), without using a wrapper ?
So, the occupied width (.footer__1 + gap + .footer__2) should be 60rem max, centered horizontally.
<footer>
<div class="footer__1">foo</div>
<div class="footer__2">whatever</div>
</footer>
.footer {
display: grid;
grid-template_columns: 2fr 1fr;
grid-column-gap: 2rem;
/* grid-max-width: 60rem */
}
Thanks
You have to wrap it with an additional element and limit the width to the additional element.
footer {
background-image: linear-gradient(20deg, red, pink);
}
.container {
display: grid;
grid-template-columns: 2fr 1fr;
grid-column-gap: 2rem;
/* just for demo purpose */
max-width: 300px;
margin: 0 auto;
min-height: 150px;
background: white;
}
<footer>
<div class="container">
<div class="footer__1">foo</div>
<div class="footer__2">whatever</div>
</div>
</footer>
Without another container, I think it is not possible.
However, you can mimic it by making the footer width: 60rem and set the background as a pseudo-element and expand it.
footer {
position: relative;
z-index: 1;
width: 60rem;
margin: 0 auto;
}
footer:before {
content: '';
position: absolute;
top: 0;
left: 50%;
z-index: -1;
transform: translateX(-50%);
width: 9999px;
height: 100%;
background: green;
}
<footer>
<div class="footer__1">foo</div>
<div class="footer__2">whatever</div>
</footer>
The best approach, as I think, is to add div.footer__inner that will hold the two divs - .footer__1 and .footer__2.

CSS Grid - unexpected behavior of fr with grid gap

I'm trying to create a layout with CSS grid that looks like this (ie: a section on the left that has a fixed width and height, a section at the top which takes up the minimum height possible, and a section underneath that which takes up all the remaining space):
However, what I'm getting is this (where the space at the bottom of the orange section is equal to the grid-row-gap):
I'm wondering why the fr is being calculated like this instead of compensating for the grid gap?
(In my project I can fix this issue by adding a margin to the bottom right element instead of using grid-row-gap, but I'd like to know if there's something I'm misunderstanding about CSS grid)
span {
display: inline-block;
}
.grid {
border: 1px solid black;
display: inline-grid;
grid-template-columns: repeat(2, auto);
grid-template-rows: auto 1fr;
grid-row-gap: 1rem;
}
.left {
background: orange;
height: 120px;
width: 120px;
grid-row: 1/span 2;
}
.right-top {
background: yellow;
height: 20px;
width: 300px;
}
.right-bottom {
background: blue;
}
<div class="grid">
<span class="left"></span>
<span class="right-top"></span>
<span class="right-bottom"></span>
</div>

How to collapse the width of CSS-grid to center it in the grid-container

Is it possible to collapse the width of a CSS grid with auto-filled columns to the minimal width required to have equal width columns that are centered with respect to the grid container?
IE if I have grid defined like this:
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
and the grid-container is 800px wide, is there a way to ensure the grid itself is only 600px wide instead of 800px?
Since I'm not sure how to explain it properly I've made a fiddle: https://jsfiddle.net/mhozx4ns/10/
I'm looking for a way that makes the top container behave like the bottom one if it is wider than what is required to place all children in one row.
body {
width: 800px;
background: black;
}
.grid div {
height: 50px;
background: #ededed;
}
.css {
display: grid;
justify-content: center;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-column-gap: 64px;
grid-row-gap: 64px;
background: red;
}
.manual {
width: 664px;
margin: 32px auto 0;
background: blue;
}
.manual:after {
content: '';
display: table;
width: 100%;
}
.manual.grid div {
width: 300px;
float: left;
margin-bottom: 64px;
}
.manual.grid div:nth-of-type(even) {
margin-left: 64px;
}
.manual.grid div:last-child {
margin-bottom: 0;
}
}
<div class="css grid">
<div>
</div>
<div>
</div>
<div>
</div>
</div>
<div class="manual grid">
<div>
</div>
<div>
</div>
<div>
</div>
</div>
When you say minmax(300px, 1fr) in your rule, you're saying this:
Each column must be a minimum width of 300px and a maximum width of 1fr.
The fr unit consumes free space in the grid container. So if your container is 800px wide, the fr will factor in all that space.
Also, since fr consumes all free space, justify-content, which functions by distributing free space, is rendered useless.
Why not just remove the 1fr?
body {
width: 800px;
background: black;
}
.css {
display: grid;
justify-content: center;
grid-template-columns: repeat(auto-fill, 300px);
grid-auto-rows: 50px;
grid-column-gap: 64px;
grid-row-gap: 64px;
background: red;
}
.grid div {
background: #ededed;
}
<div class="css grid">
<div></div>
<div></div>
<div></div>
</div>

Resources