I want the content of a grid to be centered. Like the example above.
The Boxes are dynamic. Like the example there can be multiple Box on a row and multiple rows. The Nav is always there.
I want the Boxes and Nav to be centered.
My problem is in the above image. When the screen becomes smaller the Boxes should line break like the example however the distance between Boxes and Nav is of. This is becuase I can't set width:fit-content on the left column since the boxes are dynamic.
Here is a CodeSandbox
Update
This is what the end result should look like.
The sidebar is always there to the right but the number of boxes to the left can vary per row. The amount of rows with boxes can also vary.
Understand you, here is what you need.
*,
*::before,
*::after {
box-sizing: border-box;
}
img,
picture {
max-width: 100%;
display:block;
}
body{
min-height: 100vh;
background-color: bisque;
overflow: hidden;
}
.container{
width: 100%;
margin: 0 auto;
display: grid;
place-content: center;
grid-template-columns: 1fr auto 1fr 1fr ;
grid-template-rows: 1fr 1fr 1fr;
gap:2rem;
}
.first-row{
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.second-row{
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.box{
min-width: 5rem;
width:100px;
max-width: 100px;
height: 100px;
background-color: greenyellow;
border: 1px solid black;
display: flex;
flex-basis: 5rem;
flex-grow: 1;
}
.nav{
width: 100px;
height: 300px;
background-color: aquamarine;
border: 1px solid black;
}
<div class="container">
<div class="boxes">
<div class="first-row">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="second-row">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
<div class="nav"></div>
</div>
Also check this please
flex-box: shrink before wrap
Related
I have a two column layout. Left has an image. Right has 2 images on top of each other. My goal is to have the images increase as much as possible but have to keep their aspect ratio. And of cause can't overflow outside the containing height.
Right now if you change the width of the browser window, the image resize respecively in a correct way. But if you decrease the height of the window, the images does not decrease in size.
Any tips.
outer-container has height calc(100vh -100px). it is suppose to simulate having a sticky footer.
.outer-container {
display: flex;
background-color: green;
height: calc(100vh - 100px);
clear: auto;
}
.left-column {
}
.right-column {
display:flex;
justify-content: top;
flex-direction: column;
}
.left-image {
width: 100%;
}
.right-image {
width: 100%;
}
/* Currently using image tag but meant to work with video as well, easier to create a snippet for img though!*/
<div class="outer-container">
<div class="left-column">
<img class="left-image" src="https://via.placeholder.com/200x500/333300">
</div>
<div class="right-column">
<img class="right-image" src="https://via.placeholder.com/500X250/33000">
<img class="right-image" src="https://via.placeholder.com/500x250/003300">
</image>
</div>
</div>
Just add max-height properties to the .left-image and .right-image rules so they do not overflow their parent containers.
.outer-container {
display: flex;
background-color: green;
height: calc(100vh - 100px);
clear: auto;
}
.left-column {
}
.right-column {
display:flex;
justify-content: top;
flex-direction: column;
}
.left-image {
width: 100%;
max-height: 100%;
}
.right-image {
width: 100%;
max-height: 50%;
}
/* Currently using image tag but meant to work with video as well, easier to create a snippet for img though!*/
<div class="outer-container">
<div class="left-column">
<img class="left-image" src="https://via.placeholder.com/200x500/333300">
</div>
<div class="right-column">
<img class="right-image" src="https://via.placeholder.com/500X250/33000">
<img class="right-image" src="https://via.placeholder.com/500x250/003300">
</image>
</div>
</div>
This might work as a starting point. Not 100% sure how you want the first column in relation to the second.
I added a footer since you seemed to indicate that?
.outer-container {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr) 100px;
background-color: green;
height: 100vh;
}
.left-column {
/* keeps the left image in the box */
min-height: 0;
grid-row: 1 / 2;
grid-column: 1 / 1;
border: solid cyan 2px;
display: flex;
justify-content: center;
}
.right-column {
border: solid yellow 2px;
display: flex;
align-items: start;
justify-content: top;
flex-direction: column;
}
.left-image {
height: 100%;
}
.right-image {
width: 100%;
}
.footer {
/* put accross all columns of last row and super center content */
grid-column: 1 / 3;
grid-row: 3 / 3;
background-color: #ffdd88;
display: grid;
align-items: center;
justify-content: center;
}
<div class="outer-container">
<div class="left-column">
<img class="left-image" src="https://via.placeholder.com/200x500/333300">
</div>
<div class="right-column">
<img class="right-image" src="https://via.placeholder.com/500X250/33000">
<img class="right-image" src="https://via.placeholder.com/500x250/003300">
</div>
<div class="footer"> I am the footer thing</div>
</div>
The issue
The last column/padding in a grid disappears when overflow is present. We initially attempted to use padding on our grid. Looking into this question, we were able to confirm that it's not just us facing this challenge.
Unfortunately, the way our app is structured, we're unable to use the suggestions made by some of the answers to that question:
Right border: really more of a hack than a solution, does not work for us.
Pseudo-elements: same as above
What we have
We figured, why not try to place our grid inside another grid and "fake" the padding by making the container grid contain surrounding rows/columns to mimic padding?
It works well to ensure items are of correct width across multiple screen sizes:
3 columns, 2 rows on larger screens
2 columns, 3 rows on medium screens
1 column, 6 rows on smaller screens
It fails again, however, to maintain the last column/row in the grid even though it's specified in pixels. To see this effect, you will need to resize the screen (make it smaller) to show the overflow appear and the last column disappear.
html, body {
margin: 0px !important;
}
.gallery {
position: relative;
display: grid;
grid-template-columns: 22px [main] 1fr 22px;
grid-template-rows: 22px [main] 1fr 22px;
box-sizing: border-box;
align-items: stretch;
justify-items: stretch;
height: 100vh;
width: 100vw;
overflow: auto;
}
.visuals {
position: relative;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(32%, 1fr));
grid-area: main;
align-items: stretch;
justify-items: stretch;
width: 100%;
height: 100%;
gap: 22px;
}
.content {
width: 100%;
height: 100%;
background-color: #444;
color: white;
white-space: nowrap;
}
#media only screen and (max-width: 858px) {
.visuals {
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
}
<div class="gallery">
<div class="visuals">
<div class="content">I have some content here that shouldn't be cut off.</div>
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
</div>
</div>
Our confusion
According to the documentation:
The new fr unit represents a fraction of the available space in the
grid container.
So I would assume here that the explicitly defined 22px row/column would maintain its size and that 1fr would resize according to the remaining space. The last 22px row/column disappears altogether once the overflow appears.
The question
So, how can we ensure that the last column/row in a grid layout remains visible after the scrollbar appears?
Your problem is not that the outer grid isn't working ok.
The second column is dimensioned ok, but the content overflows it.
I have added overflow hidden in the snippet, and as afar as I can tell, it's working
html, body {
margin: 0px !important;
}
.gallery {
position: relative;
display: grid;
grid-template-columns: 22px [main] 1fr 22px;
grid-template-rows: 22px [main] 1fr 22px;
box-sizing: border-box;
align-items: stretch;
justify-items: stretch;
height: 100vh;
width: 300px;
overflow: auto;
box-shadow: inset 0px 0px 0px 22px red;
}
.visuals {
position: relative;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(32%, 1fr));
grid-area: main;
align-items: stretch;
justify-items: stretch;
width: 100%;
height: 100%;
gap: 22px;
opacity: 0.6;
}
.content {
width: 100%;
height: 100%;
background-color: lightgreen;
white-space: nowrap;
}
#media only screen and (max-width: 858px) {
.visuals {
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
}
<div class="gallery">
<div class="visuals">
<div class="content">this is a long sentence that won't wrap and overflow</div>
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
</div>
</div>
I have a simple grid layout, that has a limited height and scrolls.
.outer {
border: 1px solid red;
display: grid;
grid-auto-flow: row;
padding: 30px;
grid-gap: 30px;
max-height: 150px;
overflow-y: scroll;
}
.inner {
background-color: gray;
height: 100px;
width: 100px;
}
<div class="outer">
<div class="inner">
one
</div>
<div class="inner">
two
</div>
</div>
The padding is being applied at the top, left and right of the grid:
But when I scroll down, the padding on the bottom isn't applied:
If I remove the max-height the padding at the bottom is now applied:
Why isn't the bottom padding being used? How can I ensure padding works on a grid item with limited height?
Clarity around overflow and padding is a current issue in the CSS spec and the behavior may differ based on each case.
Until the spec is clarified or browsers change their behavior, a workaround for your use case is to add an empty element at the end (since your padding is equal to the gap).
.outer {
border: 1px solid red;
display: grid;
grid-auto-flow: row;
padding: 30px;
grid-gap: 30px;
max-height: 150px;
overflow-y: scroll;
}
.inner {
background-color: gray;
height: 100px;
width: 100px;
}
.outer::after {
content:"";
height:0.1px;
}
<div class="outer">
<div class="inner">
one
</div>
<div class="inner">
two
</div>
</div>
You need to wrap the inner content with a div/container and give the container the grid display, in that case the padding will be applied on that div.
.outer {
border: 1px solid red;
max-height: 150px;
overflow-y: scroll;
}
.outer-content {
display: grid;
grid-auto-flow: row;
padding: 30px;
grid-gap: 30px;
}
.inner {
background-color: gray;
height: 100px;
width: 100px;
}
HTML
<div class="outer">
<div class="outer-content">
<div class="inner">one</div>
<div class="inner">Two</div>
</div>
</div>
There are lots of similar questions, I have reviewed all of them, but none solved my problem.
Premises:
I have a flexbox layout with flex column and the bottom flex-item filling the remainder of the page height. The flex-item gets stretched to the remainder of the page by flex 1.
Goal:
I need my grid (with its children) inside this flex-item to expand to the height of the flex-item.
Problem:
The html wrapper only has a min-height 100vh set. This makes the grid stretch to the flex-item, but not its children!
The only solution I can find is to also set height 100vh on the html wrapper, but I do not want to do this. Is there any way to solve my problem without setting height?
See the codepen here:
https://codepen.io/mesqueeb/pen/aGeKjm
See the animated GIF here to show you what I mean:
You can try this.
remove the flex-direction: column; in the .remaining and it will expand the height.
main{
min-height: calc(100vh - 51px);
display: flex;
flex-direction: column;
}
div{
border: solid goldenrod thick;
padding: 2px;
margin: 2px;
}
.full-page{
display: flex;
flex-direction: column;
height: 100%;
flex: 1;
}
.top-row{
height: 100px;
}
.remaining{
flex: 1;
display: flex;
}
.grid{
border: solid teal thick;
flex: 1;
display: grid;
grid-template-rows: 1fr 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr;
}
.key{
border: thin green solid
}
.small{
font-size: .8em
}
<main>
<div class="full-page">
<div class="top-row">
grid below will take full height only if body height is set...
</div>
<div class="remaining">
<div class="grid">
<div class="key">1</div>
<div class="key">2</div>
<div class="key">3</div>
<div class="key">4</div>
<div class="key">5</div>
<div class="key">6</div>
<div class="key">7</div>
<div class="key">8</div>
<div class="key">9</div>
<div class="key">C</div>
<div class="key">0</div>
<div class="key">➕</div>
</div>
</div>
</div>
</main>
Not sure if it solves your problem in the best way, but this works:
.remaining {
flex: 1;
/* display: flex; */
flex-direction: column;
position: relative;
}
.grid {
border: solid #008080 thick;
/* flex: 1; */
display: grid;
grid-template-rows: 1fr 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
So I'm struggling to achieve this simple concept with CSS and i've also searched the entire internet but couldn't find anything. I think I'm just not wording it correctly so a visual image of what i'm trying to do is this:
The top box should be positioned on top and the bottom one should be positioned at the bottom. Then the boxes in between them should have equal spacing on top and bottom. This is more like the vertical version of this answer: https://stackoverflow.com/a/6880421/7150896
You can use Flexbox for this. You just need to set flex-direction: column and justify-content: space-between.
body,
html {
margin: 0;
padding: 0;
}
.content {
display: flex;
height: 250px;
border: 1px solid black;
justify-content: space-between;
flex-direction: column;
width: 200px;
}
.box {
background: #0479D9;
height: 50px;
}
<div class="content">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
You can also achieve this using grid css layout:
.content {
display: grid;
align-content: space-between;
height: 275px;
border: 1px solid black;
width: 200px;
}
.box {
background: #0479D9;
height: 75px;
}
<div class="content">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>