CSS grid - align two rows with different number of columns - css

I have a question related to CSS grid. Let's say I have 2 rows:
First row:
<div class="first-row">
<div>
Col 1
</div>
<div>
Col 2
</div>
<div>
Col 3
</div>
<div>
Col 4
</div>
</div>
Second row:
<div class="second-row">
<div>
<span>Under Col 1</span>
</div>
<div>
<span>Under Col 2</span>
</div>
<div class"SPLIT-THIS">
<span>Under Col 3</span>
<span>Under Col 4</span>
</div>
</div>
How can I split the last div element in second row so the content from the first row is perfectly aligned with content from the second one(like if they were identical rows by structure).
CCS That I used:
.first-row {
grid-template-columns: repeat(4, 1fr);
grid-gap: 20px;
align-items: center;
justify-content: center;
text-align: center;
}
.second-row {
grid-template-columns: repeat(3, 1fr);
grid-gap: 20px;
align-items: center;
justify-content: center;
text-align: center;
}

I would implement what is called 'Subgrid' or 'Grid level 2'.
While the container that has both of your initial rows inside is defined in CSS using 'display: grid;', define your 'SPLIT-THIS' with a separate 'display: grid;'.
Then, use 'grid-template-rows: 50%, 50%;' for 'SPLIT-THIS' as well.

First option / approach :
both container would need to have the same amount of column and same size to be matching visually.
The split element then needs to be spanning 2 columns and be itself a grid container .
.first-row {
display: grid;
grid-template-columns: repeat(4, 1fr);
align-items: center;
justify-content: center;
text-align: center;
}
.second-row {
display: grid;
grid-template-columns: repeat(4, 1fr);
align-items: center;
justify-content: center;
text-align: center;
}
.SPLIT-THIS {
grid-column: span 2;
display: grid;
grid-template-columns: repeat(2, 1fr);
}
div,
.SPLIT-THIS span {
box-shadow: inset 0 0 0 1px
}
<div class="first-row">
<div>
Col 1
</div>
<div>
Col 2
</div>
<div>
Col 3
</div>
<div>
Col 4
</div>
</div>
<div class="second-row">
<div>
<span>Under Col 1</span>
</div>
<div>
<span>Under Col 2</span>
</div>
<div class="SPLIT-THIS">
<span>Under Col 3</span>
<span>Under Col </span>
</div>
</div>
Other options is to redefine the grid-column templates if you wish only 3 col
.first-row {
display:grid;
grid-template-columns: repeat(4, 1fr);
align-items: center;
justify-content: center;
text-align: center;
}
.second-row {
display:grid;
grid-template-columns: 1fr 1fr 2fr ;
align-items: center;
justify-content: center;
text-align: center;
}
.SPLIT-THIS{
display:grid;
grid-template-columns:repeat(2,1fr);
}
div, .SPLIT-THIS span {box-shadow:inset 0 0 0 1px}
<div class="first-row">
<div>
Col 1
</div>
<div>
Col 2
</div>
<div>
Col 3
</div>
<div>
Col 4
</div>
</div>
<div class="second-row">
<div>
<span>Under Col 1</span>
</div>
<div>
<span>Under Col 2</span>
</div>
<div class="SPLIT-THIS">
<span>Under Col 3</span>
<span>Under Col </span>
</div>
</div>

Related

Alternating rows using css grids and nth-child

I am working on a product grid with an alternating row pattern like this.
The color containers represent what I think the rows should look like.
Basically there are two products on the first row, and one product on the second row, repeating infinitely. I've been trying to do it with css grids + nth child, but I can't seem to get it right. Here's what I have so far:
.container {
display: grid;
grid-template-columns: 1fr 2fr;
grid-column-gap: 0;
width: 70vw;
margin: 0 auto;
}
.item:nth-child(3n+3) {
grid-column: auto / span 2;
background-color: #e2a7de;
}
/*just for debugging*/
.container{grid-gap:5px;}
.item{background-color: #ffa900;padding: 10px;text-align:center;}
<div class="container">
<div class="item">
X
</div>
<div class="item">
X
</div>
<div class="item">
X
</div>
<div class="item">
X
</div>
<div class="item">
X
</div>
</div>
My brain can't wrap around combining grids and nth-child to create this layout. I'm also open to a better way of creating this 2-1-2 pattern if anyone has other suggestions. Thank you!
You can simplify your code like below:
.container {
display: grid;
grid-auto-columns: 1fr; /* all columns equal */
width: 70vw;
margin: 0 auto;
}
.item:nth-child(3n) {
grid-column: span 2; /* span and create two columns*/
background-color: #e2a7de;
}
/*just for debugging*/
.container{grid-gap:5px;}
.item{background-color: #ffa900;padding: 10px;text-align:center;}
<div class="container">
<div class="item">
X
</div>
<div class="item">
X
</div>
<div class="item">
X
</div>
<div class="item">
X
</div>
<div class="item">
X
</div>
</div>
Update the grid-template-columns to be 1fr 1fr
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 0;
width: 70vw;
margin: 0 auto;
}
.item:nth-child(3n+3) {
grid-column: auto / span 2;
background-color: #e2a7de;
}
/*just for debugging*/
.container{grid-gap: 5px;}.item {background-color: #ffa900;padding: 10px;text-align: center;}
<div class="container">
<div class="item">
X
</div>
<div class="item">
X
</div>
<div class="item">
X
</div>
<div class="item">
X
</div>
<div class="item">
X
</div>
</div>

CSS Flexbox align 1 item horizontally and 2 vertically

I have the following HTML:
<div class="icon-box">
<div class="icon">
<svg>...</svg>
</div>
<h3>Title here</h3>
<p>Lorem ipsum dolor...</p>
</div>
My CSS:
.icon-box {
display: flex;
}
The result:
How can i get the following using flexbox without changing the HTML:
I am trying to align the icon to left and the heading and paragraph to its right on the same column. Without changing/adding new HTML.
Try using flex-direction: column; on main parent and regular display: flex; (flex-direction: row;) on the child of parent.
.icon-box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.icon {
display: flex;
gap: 10px;
}
<div class="icon-box">
<div class="icon">
<img src="https://dummyimage.com/50/000000/f2009d&text=SVG">
<h3>Title here</h3>
</div>
<p>Lorem ipsum dolor...</p>
</div>

why is my grid content not wrapping text, or showing ellipsis?

I am having trouble getting long-string text to wrap &/or show ellipsis. It's kind of like a table, but really it's 2 columns with rows.
I have tried messing around with the .line-flex and the .long-text-maybe classes, but no success.
Is there some sort of conflict between the grid wrapper & flex contents?
.box {
width: 50%;
}
.gridwrapp {
display: grid;
grid-gap: 8px;
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.line-flex {
display: flex;
align-items: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<div class="box">
<div class="gridwrapp">
<div class="line-flex">
<p>Reservation ID: </p>
<p class="long-text-maybe">982398</p>
</div>
<div class="line-flex">
<p>Item Name: </p>
2020 Ram Promaster 1500 HR 136 WB Custom
</div>
<div class="line-flex">
<p>Name: </p>
<p class="long-text-maybe">Kim Bob</p>
</div>
<div class="line-flex">
<p>Location: </p>
<p class="long-text-maybe">Really long name in a place far far away</p>
</div>
</div>
</div>
You have to call directly to the children containing the text elements for ellipsis to take effect. Check out the CSS changes I made.
.box {
width: 50%;
}
.gridwrapp {
display: grid;
grid-gap: 8px;
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.line-flex {
display: flex;
align-items: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.line-flex > p, a {
text-overflow: ellipsis;
overflow: hidden;
}
<div class="box">
<div class="gridwrapp">
<div class="line-flex">
<p>Reservation ID: </p>
<p class="long-text-maybe">982398</p>
</div>
<div class="line-flex">
<p>Item Name: </p>
2020 Ram Promaster 1500 HR 136 WB Custom
</div>
<div class="line-flex">
<p>Name: </p>
<p class="long-text-maybe">Kim Bob</p>
</div>
<div class="line-flex">
<p>Location: </p>
<p class="long-text-maybe">Really long name in a place far far away</p>
</div>
</div>
</div>
You will have to use flex-wrap: wrap; to get your text to wrap automatically. This includes getting rid of the white-space: nowrap; on your line-flex so that the text can wrap.
See here:
.box {
width: 50%;
}
.gridwrapp {
display: grid;
grid-gap: 8px;
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.line-flex {
display: flex;
align-items: center;
overflow: hidden;
flex-wrap: wrap;
}
<div class="box">
<div class="gridwrapp">
<div class="line-flex">
<p>Reservation ID: </p>
<p class="long-text-maybe">982398</p>
</div>
<div class="line-flex">
<p>Item Name: </p>
2020 Ram Promaster 1500 HR 136 WB Custom
</div>
<div class="line-flex">
<p>Name: </p>
<p class="long-text-maybe">Kim Bob</p>
</div>
<div class="line-flex">
<p>Location: </p>
<p class="long-text-maybe">Really long name in a place far far away</p>
</div>
</div>
</div>

Vertical align text in Bootstrap 4 divs (with btn class) with no fixed height when using CSS Grid (and no flexbox)

I have a CSS Grid with Bootstrap 4 divs with btn tags in it. The divs widen (stretch) vertically. I just need to vertical align text in the middle.
I know I can use flexbox but in this project I can't.
Here is an example: https://jsfiddle.net/fredhors/0sw2uLay/5/
.grid-wrapper {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(20vmax, 1fr));
grid-gap: 0.5rem;
height: 100vh;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="grid-wrapper">
<div class="btn btn-primary">Content A</div>
<div class="btn btn-warning">Content B</div>
<div class="btn btn-danger">Content C</div>
<div class="btn btn-success">Content D</div>
</div>
If you have to center the whole btn, just use align-items: center on the grid-wrapper - see demo below:
.grid-wrapper {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(20vmax, 1fr));
grid-gap: 0.5rem;
height: 100vh;
align-items: center; /* center vertically */
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="grid-wrapper">
<div class="btn btn-primary">Content A</div>
<div class="btn btn-warning">Content B</div>
<div class="btn btn-danger">Content C</div>
<div class="btn btn-success">Content D</div>
</div>
If you want the background stretched and have the vertical alignment, its easier if you should use flexbox for btn - see demo below:
.grid-wrapper {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(20vmax, 1fr));
grid-gap: 0.5rem;
height: 100vh;
}
.grid-wrapper > .btn {
display: flex;
align-items: center;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="grid-wrapper">
<div class="btn btn-primary">Content A</div>
<div class="btn btn-warning">Content B</div>
<div class="btn btn-danger">Content C</div>
<div class="btn btn-success">Content D</div>
</div>
I know I can use flexbox but in this project I can't.
If you can't use flexbox for this, you can use a pseudo element that will center the text in the grid items - see demo below:
.grid-wrapper {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(20vmax, 1fr));
grid-gap: 0.5rem;
height: 100vh;
}
.grid-wrapper .btn:after {
display: inline-block;
vertical-align: middle;
content: '';
height: 100%;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="grid-wrapper">
<div class="btn btn-primary">Content A</div>
<div class="btn btn-warning">Content B</div>
<div class="btn btn-danger">Content C</div>
<div class="btn btn-success">Content D</div>
</div>

Align child elements in parent flex containers

I need help horizontally aligning child elements in parent flex boxes.
The layout below shows a flex container (".parent") showing 4 parent containers (".child"):
Please take a look at this flexbox graphic
(I can't show my actual project so I mocked it up in Illustrator.)
The green box (top) represents a variable text headline (max 3 lines).
The blue box (second one down) represents an image with fixed height and width(I want these images to be aligned on top).
The yellow box represents a paragraph of varying copy.
The purple box on the bottom is another fixed-height flex box.
I have the following code (in LESS):
.parent {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-wrap: wrap;
-ms-flex-flow: wrap;
flex-wrap: wrap;
.child {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex: 1;
-ms-flex:1;
flex:1;
-webkit-flex-flow: column;
-ms-flex-flow: column;
flex-flow: column;
-webkit-align-content: space-around;
align-content: space-around;
.green {
-webkit-align-items: baseline;
-ms-flex-align: baseline;
align-items: baseline;
}
.blue {
-webkit-align-items: flex-start;
-ms-flex-align: start;
align-items: flex-start;
}
.purple {
-webkit-flex: 1;
-ms-flex:1;
flex:1;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-flow: row;
-ms-flex-flow: row;
flex-flow: row;
-webkit-align-items: flex-end;
-ms-flex-align: end;
align-items: flex-end;
-webkit-order: 3;
-ms-flex-order: 3;
order: 3;
}
.yellow {
-webkit-order: 2;
-ms-flex-order: 2;
order: 2;
}
}
}
EDIT - and here's the HTML code:
<section class="parent">
<article class="child">
<a href="#">
<h3 class="green">Title of article</h3>
<div class="blue"><img class="img-responsive" src="/stuff/headerImage.png" /></div>
</a>
<section class="purple">
<div class="authorImage"><img src="/writers/JohnDoe.jpg") /></div>
<h4 class="authorTitle">by John Doe</h4>
</section>
<p class="yellow">Paragraph introducing article summary.</p>
</article>
<article class="child">
<a href="#">
<h3 class="green">Title of article</h3>
<div class="blue"><img class="img-responsive" src="/stuff/headerImage.png" /></div>
</a>
<section class="purple">
<div class="authorImage"><img src="/writers/JohnDoe.jpg") /></div>
<h4 class="authorTitle">by John Doe</h4>
</section>
<p class="yellow">Paragraph introducing article summary.</p>
</article>
<article class="child">
<a href="#">
<h3 class="green">Title of article</h3>
<div class="blue"><img class="img-responsive" src="/stuff/headerImage.png" /></div>
</a>
<section class="purple">
<div class="authorImage"><img src="/writers/JohnDoe.jpg") /></div>
<h4 class="authorTitle">by John Doe</h4>
</section>
<p class="yellow">Paragraph introducing article summary.</p>
</article>
<article class="child">
<a href="#">
<h3 class="green">Title of article</h3>
<div class="blue"><img class="img-responsive" src="/stuff/headerImage.png" /></div>
</a>
<section class="purple">
<div class="authorImage"><img src="/writers/JohnDoe.jpg") /></div>
<h4 class="authorTitle">by John Doe</h4>
</section>
<p class="yellow">Paragraph introducing article summary.</p>
</article>
</section>

Resources