Using flexbox, and based on the following markup, is it possible to get the last item in the list to visually move up and "pack" itself into the available space?
I know this could be accomplished with different markup (3 columns and items within each column), using either floats or flexbox, but I am curious if this is something flexbox can do with this markup.
html,
body {
height: 100%;
}
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
.layout {
background-color: yellow;
display: flex;
flex-flow: row wrap;
align-items: flex-start;
}
.layout__item {
background-color: red;
width: 33.33%;
padding-right: 15px;
}
/* Every 3rd item. */
.layout__item:nth-child(3n) {
padding-right: 0;
}
/* Every item after the first 3. */
.layout__item:nth-child(n+4) {
padding-top: 15px;
}
.layout__item-content {
background-color: green;
height: 100%;
}
.layout__item-img {
background-color: blue;
height: 100%;
}
<ul class="layout">
<li class="layout__item">
<div class="layout__item-content">
<div class="layout__item-img" style="height:300px"></div>
<div class="layout__item-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Odio quos voluptates impedit optio id, fugit, nobis assumenda eveniet, veniam deserunt eum magni. Voluptates quam, deserunt sit pariatur ducimus omnis eligendi!</div>
</div>
</li>
<li class="layout__item">
<div class="layout__item-content">
<div class="layout__item-img" style="height:100px"></div>
<div class="layout__item-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolores, saepe!</div>
</div>
</li>
<li class="layout__item">
<div class="layout__item-content">
<div class="layout__item-img" style="height: 200px;"></div>
<div class="layout__item-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Officia placeat quidem, illum cumque nisi repellat excepturi iusto aperiam tempore quam.</div>
</div>
</li>
<li class="layout__item">
<div class="layout__item-content">
<div class="layout__item-img" style="height:150px;"></div>
<div class="layout__item-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptas natus odio quae nam officia libero.</div>
</div>
</li>
<li class="layout__item">
<div class="layout__item-content">
<div class="layout__item-img" style="height: 321px;"></div>
<div class="layout__item-text">Lorem ipsum dolor sit amet.</div>
</div>
</li>
</ul>
The answer to this question is quite simply no.
A good explanation as to why is available on a similar question: Horizontal masonry layout with flexbox CSS only
Related
In my react and tailwindcss project I have the following code snippet in one of components:
<div className="container">
<div className="grid grid-cols-4 gap-x-2 gap-y-4">
{valueCards.map(
(item,index) => (
<div key={index}>
<ValuesCard description={item.description} isPrimary={index % 2 === 0} />
</div>
)
)}
</div>
</div>
This will produce the following results:
What I'm looking for is first of all to try to make all excess divs appear in the middle of the row like this (note that i don't mind doing it with plain css instead of tailwindcss):
I would also prefer that all the cards have the same height equal to the height of the largest card amongst them all even if that one wasn't on the same row.
The problem with your code is that you are setting the number of columns to 4 while on the second row you only want 3. In a grid the number of columns stays the same. Therefore it might be easier to use flexbox to get the solution you want. So instead of 'display: grid', I would use 'display: flex'.
Instead of setting a fixed number of columns, you might want to specify the maximum width of your cards and let the browser decide how many cards it can fit into one row.
By setting 'flex-wrap: wrap' you're telling the browser that it can start placing cards on a new row if the first one is full. By setting justify-'content: center' the cards will be horizontally centered in their flex-container.
By choosing the max-width of the cards, you can determine how many you want to be grouped into one row. You could also specify a height for the cards to make sure that they have the same height and set overflow: scroll in case the content is longer than what fits in the card.
Here's an example in plain CSS that I've tried to make as simple as possible:
.flex-container {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 10px;
}
.card {
background-color: lightgray;
padding: 0.5rem;
max-width: 20%;
}
<div class="flex-container">
<div class="card">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus
eveniet pariatur libero, sunt deserunt quam accusamus ducimus recusandae
molestias eaque architecto! Nulla, voluptatibus blanditiis? Animi minima
eaque molestiae esse autem.
</div>
<div class="card">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus
eveniet pariatur libero, sunt deserunt quam accusamus ducimus recusandae
molestias eaque architecto! Nulla, voluptatibus blanditiis? Animi minima
eaque molestiae esse autem.
</div>
<div class="card">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus
eveniet pariatur libero, sunt deserunt quam accusamus ducimus recusandae
molestias eaque architecto! Nulla, voluptatibus blanditiis? Animi minima
eaque molestiae esse autem.
</div>
<div class="card">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus
eveniet pariatur libero, sunt deserunt quam accusamus ducimus recusandae
molestias eaque architecto! Nulla, voluptatibus blanditiis? Animi minima
eaque molestiae esse autem.
</div>
<div class="card">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus
eveniet pariatur libero, sunt deserunt quam accusamus ducimus recusandae
molestias eaque architecto! Nulla, voluptatibus blanditiis? Animi minima
eaque molestiae esse autem.
</div>
<div class="card">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus
eveniet pariatur libero, sunt deserunt quam accusamus ducimus recusandae
molestias eaque architecto! Nulla, voluptatibus blanditiis? Animi minima
eaque molestiae esse autem.
</div>
<div class="card">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus
eveniet pariatur libero, sunt deserunt quam accusamus ducimus recusandae
molestias eaque architecto! Nulla, voluptatibus blanditiis? Animi minima
eaque molestiae esse autem.
</div>
It seems that it is not possible to do it with CSS grids.
This is because grid algorithm makes sure that the elements follow the grid lines for their sizes.
An easier solution is to use CSS flex box and use justify-content: center
I have tried doing the same here in this code pen
Check out what I did. It is HTML and plain CSS. Adjust the width and height as necessary. The fundamental is to put the top and lower grids in different DIV's, then center each of the two DIV's.
body{
margin: 0;
}
.container {
background-color: blue;
height: auto;
padding: 10px; /*You may want to increase this*/
}
.top-grid{
display: grid;
grid-template-columns: repeat(4, 1fr);
width: fit-content;
margin: 1.5rem auto;
column-gap: 1rem;
}
.bottom-grid{
margin: 1.5rem auto;
display: grid;
grid-template-columns: repeat(3, 1fr);
width: fit-content;
column-gap: 1rem;
}
/*Resixe this as necessary*/
.grid-div{
display: block;
border: 1px solid none;
width: 110px;
height: 120px;
background-color: white;
}
/*Check here 1st if you face a problem*/
.grid-div .inner{
margin-bottom: 8px;
padding: 5px;
}
.grid-div span{
display: block;
text-align: center;
}
.grid-div span:nth-of-type(2){
margin-top: 1rem;
}
.color-block{
background-color: red;
height: 1rem;
width: 100%;
margin: 0;
}
.material-icon-blue{
color: blue;
}
.material-icon-black{
color: black;
}
<head>
<!--add material icon link here-->
<!--Example-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!--Connect HTML to CSS-->
<!--Check the web if you don't know how. This also applies to adding the specific material icon into the HTML-->
</head>
<section class="container">
<div class="top-grid">
<div class="grid-div">
<div class="inner">
<span class="material-icon-black">Add Material Icon Here</span>
<span>Add text content here</span>
</div>
<div class="color-block"></div>
</div>
<div class="grid-div">
<div class="inner">
<span class="material-icon-blue">Add Material Icon Here</span>
<span>Add text content here</span>
</div>
<div class="color-block"></div>
</div>
<div class="grid-div">
<div class="inner">
<span class="material-icon-black">Add Material Icon Here</span>
<span>Add text content here</span>
</div>
<div class="color-block"></div>
</div>
<div class="grid-div">
<div class="inner">
<span class="material-icon-blue">Add Material Icon Here</span>
<span>Add text content here</span>
</div>
<div class="color-block"></div>
</div>
</div>
<div class="bottom-grid">
<div class="grid-div">
<div class="inner">
<span class="material-icon-black">Add Material Icon Here</span>
<span>Add text content here</span>
</div>
<div class="color-block"></div>
</div>
<div class="grid-div">
<div class="inner">
<span class="material-icon-blue">Add Material Icon Here</span>
<span>Add text content here</span>
</div>
<div class="color-block"></div>
</div>
<div class="grid-div">
<div class="inner">
<span class="material-icon-black">Add Material Icon Here</span>
<span>Add text content here</span>
</div>
<div class="color-block"></div>
</div>
</div>
</section>
You can use flex.
.wrapper {
margin: 0 auto;
max-width: 800px;
}
.cards {
list-style: none;
margin: 0;
padding: 0;
}
.cards li {
border: 2px solid #490A3D;
border-radius:5px;
background-color: #BD1550;
color: #fff;
width: 30%;
}
.cards h2 {
background-color: #490A3D;
margin: 0;
padding: 10px;
}
.cards p {
padding: 10px;
}
.flex {
display: flex;
flex-wrap: wrap;
margin: 0 -10px;
justify-content:center
}
.flex li {
margin: 10px;
}
<div class="wrapper">
<h1>Flexbox</h1>
<ul class="flex cards">
<li><h2>Card 1</h2>
<p>Posuere varius
</p></li>
<li><h2>Card 2</h2>
<p>Posuere varius ullamcorper ipsum adipiscing dignissim ipsum adipiscing a a quisque malesuada quam purus venenatis.
</p></li>
<li><h2>Card 3</h2>
<p>Posuere varius ullamcorper ipsum ipiscing a a quisque malesuada quam purus venenatis sagittis fermentum parturient curabitur montes a metus.
</p></li>
<li><h2>Card 4</h2>
<p>Posuere varius ullamcorper ipsum adipiscing dignissim ipsum adipiscing a a quisque malesuada quam purus venenatis sagittis fermentum parturient curabitur montes a metus.
</p></li>
<li><h2>Card 5</h2>
<p>Posuere varius ullamcorper ipsum adipiscing dignissim ipsum adipiscing
</p></li>
</ul>
</div>
Do you know why, when I resize my browser down and the flex direction is changed to columns, that my images and text no longer sits in the middle and looks left aligned? There's a huge space on the right hand side and I want the content to always sit in the center no matter what size the browser is. I used the obvious tricks like left-align and center etc, but the space remains.
Code below:
HTML:
<body>
<div class="container">
<div class="products">
<div class="product product-1">
<img src="images/product-1.jpg">
<h2>Lorem ipsum dolor sit amet.</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dicta fugit ad in dolores
veniam hic cupiditate aliquam perferendis velit odit.
</p>
</div>
<div class="product product-1">
<img src="images/product-2.jpg">
<h2>Lorem ipsum dolor sit amet.</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dicta fugit ad in dolores
veniam hic cupiditate aliquam perferendis velit odit.
</p>
</div>
<div class="product product-1">
<img src="images/product-3.jpg">
<h2>Lorem ipsum dolor sit amet.</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dicta fugit ad in dolores
veniam hic cupiditate aliquam perferendis velit odit.
</p>
</div>
</div>
</div>
</body>
CSS:
.container {
width: 95%;
max-width: 1280px;
margin: 0 auto;
}
img {
max-width: 100%;
width: 400px;
}
.products {
display: flex;
justify-content: space-evenly;
}
.product-1 {
width: 33%;
margin: 0 0.50em;
}
#media (max-width: 600px) {
.products {
flex-direction: column;
}
.product-1 {
width: 100%;
}
p {
width: 75%;
}
}
You should use flexbox in your product-1 to center items
.product-1 {
display: flex;
flex-flow: column;
align-items: center;
width: 100%;
}
.container {
width: 95%;
max-width: 1280px;
margin: 0 auto;
}
img {
max-width: 100%;
width: 400px;
}
.products {
display: flex;
justify-content: space-evenly;
}
.product-1 {
width: 33%;
margin: 0 0.50em;
}
#media (max-width: 600px) {
.products {
flex-direction: column;
}
.product-1 {
display: flex;
flex-flow: column;
align-items: center;
width: 100%;
}
p {
width: 75%;
}
}
<body>
<div class="container">
<div class="products">
<div class="product product-1">
<img src="images/product-1.jpg">
<h2>Lorem ipsum dolor sit amet.</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dicta fugit ad in dolores
veniam hic cupiditate aliquam perferendis velit odit.
</p>
</div>
<div class="product product-1">
<img src="images/product-2.jpg">
<h2>Lorem ipsum dolor sit amet.</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dicta fugit ad in dolores
veniam hic cupiditate aliquam perferendis velit odit.
</p>
</div>
<div class="product product-1">
<img src="images/product-3.jpg">
<h2>Lorem ipsum dolor sit amet.</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dicta fugit ad in dolores
veniam hic cupiditate aliquam perferendis velit odit.
</p>
</div>
</div>
</div>
</body>
This question already has answers here:
Prevent content from expanding grid items
(3 answers)
Closed 3 years ago.
When using a CSS Grid, I can't seem to manage to make the text-overflow:ellipsis work, even though I am applying it to the dom object containing the text that I want to shorten.
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
.grid-item { border: 1px solid red;}
.grid-item .content{
background-color: lightgray;
}
&.with-ellipsis {
.title {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
}
This is the pen where my code is: https://codepen.io/dbugger/pen/qBBKLgX?editors=1100
Set min-width: 0; on the .grid-item. It's an old solution for ellipsis on children of flexbox items (and grid), and you can read more about it here.
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 10px;
}
.grid .grid-item {
min-width: 0;
border: 1px solid red;
}
.grid .grid-item .content {
background-color: lightgray;
}
.grid.with-ellipsis .title {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.demo {
display: inline-block;
width: 33%;
border: 1px solid red;
}
.demo .content {
background-color: lightgray;
}
.demo .title {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
<h1>But what happens when you want some content inside the cell to have text-overflow: ellipsis</h1>
<div class="grid with-ellipsis">
<div class="grid-item">
<div class="image">Some image</div>
<div class="content">
<div class="title">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nesciunt excepturi obcaecati odio pariatur ipsam doloremque vel labore ipsa explicabo quos.</div>
</div>
</div>
<div class="grid-item">
<div class="image">Some image</div>
<div class="content">
<div class="title">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nesciunt excepturi obcaecati odio pariatur ipsam doloremque vel labore ipsa explicabo quos.</div>
</div>
</div>
<div class="grid-item">
<div class="image">Some image</div>
<div class="content">
<div class="title">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nesciunt excepturi obcaecati odio pariatur ipsam doloremque vel labore ipsa explicabo quos.</div>
</div>
</div>
<div class="grid-item">
<div class="image">Some image</div>
<div class="content">
<div class="title">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nesciunt excepturi obcaecati odio pariatur ipsam doloremque vel labore ipsa explicabo quos.</div>
</div>
</div>
<div class="grid-item">
<div class="image">Some image</div>
<div class="content">
<div class="title">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nesciunt excepturi obcaecati odio pariatur ipsam doloremque vel labore ipsa explicabo quos.</div>
</div>
</div>
<div class="grid-item">
<div class="image">Some image</div>
<div class="content">
<div class="title">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nesciunt excepturi obcaecati odio pariatur ipsam doloremque vel labore ipsa explicabo quos.</div>
</div>
</div>
</div>
I have a job site designed with with css grid. The job listings and email subscribe are divided bygrid-template-columns: (3fr, 1fr), the problem is is that the email subscribe box is the same height as the job listings (if there are 10 listings for example this is quite a large email subscribe box), how can I change this? (Note: jsfiddle included at bottom will make it much more clear and I have tried to set a height value on #item2 and this did not work) Thanks in advance!
.grid {
display: grid;
grid-template-columns: 3fr 1fr;
}
#item1 {
margin-left: 15px;
}
#item1>h1 {
text-align: center;
}
#list_of_jobs {
list-style: none;
}
#item2 {
text-align: center;
margin-right: 15px;
border: 3px solid #eeeeee;
}
<div class="grid">
<div id="item1">
<h1>Jobs in 10529</h1>
<table>
<tbody>
<div>
<ul id="list_of_jobs">
<li>
<h2>Job 1</h2>
<p class="lead"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus itaque minus corporis earum consequuntur unde saepe consequatur commodi harum ut. </p>
</li>
<li>
<h2>Job 2</h2>
<p class="lead"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus itaque minus corporis earum consequuntur unde saepe consequatur commodi harum ut. </p>
</li>
<li>
<h2>Job 3</h2>
<p class="lead"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus itaque minus corporis earum consequuntur unde saepe consequatur commodi harum ut. </p>
</li>
<li>
<h2>Job 4</h2>
<p class="lead"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus itaque minus corporis earum consequuntur unde saepe consequatur commodi harum ut. </p>
</li>
</ul>
</div>
</tbody>
</table>
</div>
<div id="item2">
<form>
<p>Subscribe to recieve job alerts near 105</p>
<!-- query stores zip code-->
<input type="text" placeholder="Email">
<button class="btn" type="submit">Subscribe</button>
</form>
</div>
</div>
<!-- close grid div-->
http://jsfiddle.net/bmy0s93k/2/
Add this to your code:
#item2 {
align-self: start;
}
revised fiddle
A default setting in a grid container (like in a flex container) is align-items: stretch. This means that grid items (like flex items) will stretch the full length of the relevant axis in the container.
You need to override the default.
References:
ยง 6.2. Block/Cross-Axis Alignment: the align-self property
How to disable equal height columns in Flexbox?
I've this code
.container {
width: 960px;
margin: 0 auto;
}
p {
margin: 0;
padding: 0;
}
.col {
width: 50%;
display: inline-block;
}
.col:first-child{
float: left;
}
.col:last-child{
float: right;
}
.text {
background-color: lightblue;
}
<div class="container">
<div class="col">
<div class="text">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Numquam placeat amet dolore asperiores et omnis voluptas dolorum natus nobis. Ad, provident exercitationem tempora vel laudantium iure libero possimus voluptates ipsa.</p>
</div>
<div class="img">
<img src="http://placehold.it/480x150">
</div>
</div>
<div class="col">
<div class="img">
<img src="http://placehold.it/480x50">
</div>
<div class="text">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</div>
</div>
</div>
Without having any height declared. I want my two .col have the same height.
I need to take care about responsive too.
I already try to set a fixed height to my last .text div but it does not help me..
Thanks for your help !
Flexbox can do that:
.container {
width: 960px;
margin: 0 auto;
display: flex;
}
p {
margin: 0;
padding: 0;
}
.col {
border: 1px solid grey;
background:plum;
}
.text {
background-color: lightblue;
}
<div class="container">
<div class="col">
<div class="text">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Numquam placeat amet dolore asperiores et omnis voluptas dolorum natus nobis. Ad, provident exercitationem tempora vel laudantium iure libero possimus voluptates ipsa.</p>
</div>
<div class="img">
<img src="http://placehold.it/480x150">
</div>
</div>
<div class="col">
<div class="img">
<img src="http://placehold.it/480x50">
</div>
<div class="text">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</div>
</div>
</div>