could you please tell me how to show equal height of column using flex-box.I tried like this
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.grid {
display: flex;
flex-wrap: wrap;
}
.card {
background-color: #eee;
padding: 20px;
}
.grid-item {
width: calc(50vw - 0px);
}
here is my code
https://codesandbox.io/s/prod-sea-ng305?file=/index.html:255-550
currently it look like this
To maintain the equal height of the div we have to use align-items: stretch property. That will maintain the height of the elements. Please find the code below.
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.grid {
display: flex;
flex-wrap: wrap;
align-items: stretch;
}
.grid-item {
display: flex;
width: calc(50vw - 0px);
margin: 0 0 1px 0;
}
.card {
width: 100%;
background-color: #eee;
padding: 20px;
}
<div class="grid">
<div class="grid-item">
<div class="card">A very short text.</div>
</div>
<div class="grid-item">
<div class="card">
Debitis nam, porro officia dolorum cupiditate magnam perspiciatis quis
corrupti cumque, est perferendis provident vel accusamus ullam cum
similique. Quasi, quidem beatae. Debitis nam, porro officia dolorum
cupiditate magnam perspiciatis quis corrupti cumque, est perferendis
provident vel accusamus ullam cum similique. Quasi, quidem beatae.
</div>
</div>
<div class="grid-item">
<div class="card">
Officia autem sunt obcaecati voluptas sit, architecto cumque quaerat
aperiam fuga eveniet necessitatibus aliquid eum beatae, mollitia saepe
ab ut!
</div>
</div>
</div>
Here's the answer using flexbox as requested in the post. Though grid is likely an easier answer in terms of making a grid, and as such I included it at the end of the post.
align-items: stretch makes the elements change size on their cross axis (height when flex is set to row, and width when set to column) to stretch to fit. This makes the elements in the flexbox stretch to the same height as the largest element in the row.
Then by setting .card to have a height of 100%, the card will now take up that full height, though setting the .grid-item to use flex instead is also perfectly valid.
CSS Tricks Flex is a good resource for what flexbox can do.
* {
padding: 0;
margin: 0;
box-sizing: border-box;
/* Makes the scrollbar not take up space so the demo shows on the small runner */
overflow-y: overlay;
}
.grid {
display: flex;
flex-wrap: wrap;
/* Makes the items cross axis of the flexbox stretch to the full size
of the cross axis
*/
align-items: stretch;
}
.card {
background-color: #eee;
padding: 20px;
/* Make the card take the height of it's containing item */
height: 100%;
}
.grid-item {
/* Makes the grid item take up half the width of the page */
width: calc(50vw - 0px);
}
#supports not (overflow: overlay) {
/* Backup to make sure the demo looks good on small runner on all devices
since overlay isn't supported on everything
*/
.grid-item {
width: calc(50vw - 8px);
}
}
<div class="grid">
<div class="grid-item">
<div class="card">
hello
</div>
</div>
<div class="grid-item">
<div class="card">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Error molestiae reiciendis voluptate cum fugiat nisi exercitationem quos ipsum iusto dolore. Quasi expedita accusantium at odio repellat explicabo corrupti veniam hic?
</div>
</div>
<div class="grid-item">
<div class="card">
third locthiLorem, ipsum dolor sit amet consectetur adipisicing elit. Error molestiae reiciendis voluptate cum fugiat nisi exercitationem quos ipsum iusto dolore. Quasi expedita accusantium at odio repellat explicabo corrupti veniam hic?
</div>
</div>
</div>
Here's the same but in a grid. It's simpler and uses fewer properties to get the same result.
This is all the CSS Grid related properties set:
.grid {
/* Make the grid use css grid */
display: grid;
/* Make 2 columns, each one fraction of the available width */
grid-template-columns: 1fr 1fr;
}
Though again, we need to set some height for the card because while the grid-item stretches height to fit, the card doesn't.
CSS Tricks Grid is a good resource for CSS Grid.
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.grid {
display: grid;
/* Make 2 columns, each one fraction of the available width */
grid-template-columns: 1fr 1fr;
}
.card {
background-color: #eee;
padding: 20px;
/* Make the card take the height of it's containing item */
height: 100%;
}
<div class="grid">
<div class="grid-item">
<div class="card">
hello
</div>
</div>
<div class="grid-item">
<div class="card">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Error molestiae reiciendis voluptate cum fugiat nisi exercitationem quos ipsum iusto dolore. Quasi expedita accusantium at odio repellat explicabo corrupti veniam hic?
</div>
</div>
<div class="grid-item">
<div class="card">
third locthiLorem, ipsum dolor sit amet consectetur adipisicing elit. Error molestiae reiciendis voluptate cum fugiat nisi exercitationem quos ipsum iusto dolore. Quasi expedita accusantium at odio repellat explicabo corrupti veniam hic?
</div>
</div>
</div>
Related
I'm trying to make a layout with a fixed navbar, a fixed-size content area, and a scrollable sidebar. This is a pretty standard setup (though usually the sidebar is fixed while the content scrolls, but that's just semantics), but it's important that the content's box doesn't overflow the overall container, since I'm filling it with an image that gets an object-fit applied so it can scale happily within the viewport while maintaining its aspect ratio.
I actually have a functioning version of it using grid (embedded and linked below). The problem there is that if I want the sidebar to go away, I have to change the styling on the parent divs, which is messy (but doable) in the component system I'm using. Ideally I'd be able to simply set the sidebar to display: none and the content would fill the space.
I've tried converting the whole thing to flexbox, and making the second row into a nested grid, but I can't seem to do either of those while retaining the overall height lock.
Here's the working grid (and a CodePen).
html,
body {
margin: 0;
}
.wrapper {
height: 100vh;
display: grid;
grid-template-columns: 1fr 150px;
grid-template-rows: auto 1fr;
}
nav {
height: 50px;
grid-row: 1;
grid-column: 1 / span 2;
background-color: darkseagreen;
}
.content {
background-color: salmon;
position: relative;
}
img {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
object-fit: contain;
}
.sidebar {
overflow-y: scroll;
background-color: cornflowerblue;
}
<div class="wrapper">
<nav>Navbar should stay fixed</nav>
<div class="content">
<img src="http://placehold.it/640x360">
</div>
<div class="sidebar">
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Porro repudiandae, laboriosam dolorum mollitia fugit autem officiis explicabo minima! Maxime ea a unde alias laboriosam vel pariatur delectus. A, quas ratione?</div>
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Neque temporibus sunt, nesciunt et assumenda asperiores fuga aperiam nulla voluptas reprehenderit iusto molestias blanditiis corrupti, nobis ab id dolorum obcaecati ullam!</div>
</div>
</div>
Is there a way to craft this so the second row becomes a flexbox while keeping its height from expanding, so I could collapse the sidebar without having to re-layout a whole grid? (If there's a more clever way to get the img scaling I'm attempting, I'm open to that, too.)
Simply update the template to grid-template-columns: 1fr auto; and make the width of sidebar to be equal to 150px;
html,
body {
margin: 0;
}
.wrapper {
height: 100vh;
display: grid;
grid-template-columns: 1fr auto;
grid-template-rows: auto 1fr;
}
nav {
height: 50px;
grid-row: 1;
grid-column: 1 / span 2;
background-color: darkseagreen;
}
.content {
background-color: salmon;
position: relative;
}
img {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
object-fit: contain;
}
.sidebar {
overflow-y: scroll;
background-color: cornflowerblue;
width:150px;
}
<div class="wrapper">
<nav>Navbar should stay fixed</nav>
<div class="content">
<img src="http://placehold.it/640x360">
</div>
<div class="sidebar" style="display:none;">
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Porro repudiandae, laboriosam dolorum mollitia fugit autem officiis explicabo minima! Maxime ea a unde alias laboriosam vel pariatur delectus. A, quas ratione?</div>
<div>Lorem ipsum dolor sit amet consectetur adipisicing elit. Neque temporibus sunt, nesciunt et assumenda asperiores fuga aperiam nulla voluptas reprehenderit iusto molestias blanditiis corrupti, nobis ab id dolorum obcaecati ullam!</div>
</div>
</div>
I want to take the read more button and push it to the bottom of this card. Is there an equivalent of align-content:space-between for flex-col? The top section, middle paragraph, and see more button are all in their own div wrapped inside the parent card div.
You can achieve this with a combination of justify-content: space-between and text-align: right to the readmore button.
This results in:
.card {
background: #ddd;
margin: 1rem;
padding: 2rem;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.child-2 {
text-align: right;
}
.child {
background: #eee;
padding: 1rem;
}
<div class="card">
<div class="child">
<h1>Article Awesome</h1>
<p>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ratione inventore, dolor dolorem vero, tenetur rerum tempora autem repudiandae deleniti rem sunt perferendis quasi dolore voluptatum fugit quisquam asperiores exercitationem. Exercitationem?
</p>
</div>
<div class="child child-2">Read More ...</div>
</div>
Note that you can set whatever height to the card and it will scale accordingly with the readmore button in the bottom.
I have a CSS grid with two columns. I may or may not render content inside the first column. In other words, the column div will always be present, its just that sometimes it might not have content therein. When there is no content in the first column I don't want that column to take up space, and when there is content I want it to have a max width of 100px. Is it possible to do this via the CSS Grid definition alone?
#container {
display: grid;
grid-template-columns: minmax(auto, 100px) auto;
grid-gap: 5px;
height: 200px;
width: 100%;
background-color: #8cffa0;
padding: 10px;
}
#container > div {
background-color: #c0c0c0;
}
<div id="container">
<div>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</div>
<div>
Placeat, rerum illo eligendi, hic eum magnam quo architecto necessitatibus sunt sequi repellendus suscipit fuga tenetur atque corrupti modi saepe! Iusto, provident.
</div>
</div>
Using grid-template-columns: fit-content(100px) (see https://developer.mozilla.org/en-US/docs/Web/CSS/fit-content) with an absolute length the column-width fits to its contents (with no minimum) clamped to a maximum width (of 100px in this case).
#container {
display: grid;
grid-template-columns: fit-content(100px) auto;
grid-gap: 5px;
height: 200px;
width: 100%;
background-color: #8cffa0;
padding: 10px;
}
#container > div {
background-color: #c0c0c0;
}
<div id="container">
<div>Lorem</div>
<div>
Placeat, rerum illo eligendi, hic eum magnam quo architecto necessitatibus sunt sequi repellendus suscipit fuga tenetur atque corrupti modi saepe! Iusto, provident.
</div>
</div>
The problem you're facing isn't the grid-template-columns property. It makes sense to think that, simply using that property, you would be able to collapse empty columns.
The problem is that you have a maximum width limitation.
With this requirement, grid-template-columns and grid-auto-columns can't do the job by themselves because in a minmax() rule, the argument defaults to the max value.
minmax() defaulting to max
This means that in your layout, defined as such:
grid-template-columns: minmax(auto, 100px) auto
… the empty column will always be 100px wide.
If you didn't have a max-width limitation, you can hide empty columns by using implicit columns (grid-auto-columns), instead of explicit columns (grid-template-columns).
CSS Grid: How to make a column span full width when a second column is not there?
In case you can work beyond the scope of grid-*-columns properties, here's a solution that may work for you:
.container {
display: grid;
grid-template-columns: auto 1fr;
grid-gap: 5px;
height: 100px;
background-color: #8cffa0;
padding: 10px;
}
.container > div:first-child:not(:empty) {
max-width: 100px;
}
.container > div {
background-color: #c0c0c0;
}
<div class="container">
<div>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</div>
<div>
Placeat, rerum illo eligendi, hic eum magnam quo architecto necessitatibus sunt sequi repellendus suscipit fuga tenetur atque corrupti modi saepe! Iusto, provident.
</div>
</div>
<hr>
<div class="container">
<div></div>
<div>
Placeat, rerum illo eligendi, hic eum magnam quo architecto necessitatibus sunt sequi repellendus suscipit fuga tenetur atque corrupti modi saepe! Iusto, provident.
</div>
</div>
This question already has answers here:
One flex/grid item sets the size limit for siblings
(6 answers)
Closed 6 years ago.
I'm trying to create a flexbox layout that does something I thought would be a little easier, but I'm having trouble finding the right way to do it.
I want to have a row of items with dynamic height that allows one child to grow as tall as need be, but limits the height of the other item so that content is cut off.
I want to use flexbox, so browser issues associated with that are not an issue, but I would like to avoid any use of JavaScript in the solution.
Any ideas? This might be a trivial problem, but I'm having trouble finding anything with the search terms I've been using. Thanks!
Here's a CodePen demo in case you'd like to modify it for use in your answer.
This is my reference flexbox layout:
.row {
display: flex;
}
.info {
flex: 0 0 200px;
}
.description {
flex: 1 1 auto;
}
<div class="row">
<div class="info">This should grow dynamically</div>
<div class="description">This should be limited in height by the .info div</div>
</div>
Flexbox can't do that natively but it is possible.
You will need an inner element inside the second child which is positioned absolutely.
Here the extra content is/can be hidden with overflow:hidden...or revealed by adding overflow:auto.
.wrapper {
display: flex;
width: 80%;
margin: 1em auto;
border: 2px solid red;
}
.child {
flex: 1;
border: 2px solid green;
}
.child:nth-child(2) {
position: relative;
overflow: auto;
/*overflow: hidden; */ /* removed for demo purposes */
}
.inner {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
<div class="wrapper">
<div class="child">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Debitis tenetur, laboriosam! Ab facilis, officia id delectus eaque expedita quia, incidunt eligendi aut, minus temporibus tenetur.</div>
<div class="child">
<div class="inner">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae molestiae, libero inventore nobis et veritatis, laborum vitae, vel eaque omnis ad adipisci quia velit blanditiis qui. Cum voluptas quisquam itaque possimus accusamus repellendus quia iure
asperiores. Unde, rerum nihil maiores nisi, iusto voluptate id cumque incidunt, perspiciatis facilis perferendis explicabo.
</div>
</div>
</div>
So imagine I have the following Markup
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
And the following styles (SASS)
#mixin max-width($width) {
#media screen and (max-width: $width) {
#content;
}
}
.container {
display: flex;
#include max-width(992px) {
number: 4; //Hypothetical property that is supposed to control number per row
}
#include max-width(640px) {
number: 2; //Hypothetical property that is supposed to control number per row
}
}
.item {
background-color: tomato;
padding: 20px;
margin-right: 20px;
flex: 1;
}
Is there a real Flexbox CSS alternative to my hypothetical number property that can control how many items to show per row ?
The float-like grid was handy because you could fit unlimited .items per one .row because of the width. But with flexbox I have to use workarounds like numerous .row classes to control the layout and number of items at different width. I've been lucky so far, but there are certain type of layout which will fail with such an approach.
Codepen link to demonstrate
I had to get rid of the margin around the blocks, because percentage widths are difficult to cleanly apply to elements with margins, but you can see the changes at http://codepen.io/anon/pen/jPeLYb?editors=110 :
#mixin max-width($width) {
#media screen and (max-width: $width) {
#content;
}
}
.container {
position: relative;
display: flex;
flex-flow: row wrap;
}
.item {
background-color: tomato;
box-sizing: border-box;
padding: 20px;
outline: 2px solid blue;
flex: 1;
}
#include max-width(992px) {
.item {
flex-basis: 25%;
background-color: red;
}
}
#include max-width(640px) {
.item {
flex-basis: 50%;
background-color: green;
}
}
The important parts here are:
flex-flow: row wrap which allows the flexbox to appear on multiple rows (the default is nowrap)
flex-basis which is the equivalent of width in this case
position: relative which makes the widths relative to the container, rather than the body (this would screw up the rounding)
I have found a better solution for restricting the number of columns in a row in different devices without using media queries:
HTML:
<div class="flex-container">
<div class="item">
<h3>ONE</h3>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Cumque maxime odit ipsam, fugit pariatur quis eos
maiores nostrum? Alias tempora voluptate veritatis omnis quae corporis vero excepturi in rem ipsam.
</div>
<div class="item">
<h3>TWO</h3>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Cumque maxime odit ipsam, fugit pariatur quis eos
maiores nostrum? Alias tempora voluptate veritatis omnis quae corporis vero excepturi in rem ipsam.
</div>
<div class="item">
<h3>THREE</h3>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Cumque maxime odit ipsam, fugit pariatur quis eos
maiores nostrum? Alias tempora voluptate veritatis omnis quae corporis vero excepturi in rem ipsam.
</div>
<div class="item">
<h3>FOUR</h3>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Cumque maxime odit ipsam, fugit pariatur quis eos
maiores nostrum? Alias tempora voluptate veritatis omnis quae corporis vero excepturi in rem ipsam.
</div>
</div>
CSS:
.flex-container {
display: flex;
flex-wrap: wrap;
}
.item {
box-sizing: border-box;
flex: 1 0 250px;
margin: 1rem;
padding: 1rem;
border: 1px solid #000;
border-radius: 5px;
}
Codepen link: https://codepen.io/bala285/pen/YzqpLod
Source: https://www.fourkitchens.com/blog/article/responsive-multi-column-lists-flexbox/