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>
Related
I'm trying to pass the last two items over each other as shown on the bottom of this photo.
Is this possible as is by forcing a line break or do I have to change the display of the parent div?
The HTML structure looks like this :
<div class="wp-block-cover">
<ul class="articleslisteshp" id="lcp_instance_0">
<li>
<a>Lorem ipsum article title</a>
<span class="testcat" style="width: 100%;">
<a>Category1</a>
<a>Category2</a>
</span>
<a><img width="150" height="150"></a>
</li>
</ul>
</div>
Et voici le CSS que j'ai essayƩ :
ul.articleslisteshp{
display: flex;
flex-direction: column;
}
ul.articleslisteshp > li{
display: flex;
flex-direction: row-reverse;
}
I would take out the a tag from inside the list if possible and put it outside of it. Like so:
<div class="wp-block-cover">
<ul class="articleslisteshp" id="lcp_instance_0">
<a><img width="150" height="150"></a>
<li>
<a>Lorem ipsum article title</a>
<span class="testcat" style="width: 100%;">
<a>Category1</a>
<a>Category2</a>
</span>
</li>
</ul>
</div>
And use the following CSS to achieve what you asked for:
ul.articleslisteshp{
display: flex;
flex-direction: row;
}
ul.articleslisteshp > li{
display: flex;
flex-direction: column-reverse;
}
span.testcat {
display: flex;
flex-direction: column;
}
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>
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>
Is there a CSS Grid configuration that will repeat (wrap) cells but dynamically shrink columns based on the size of the content, instead of using uniformly sized columns?
For example, here is a configuration using the following rules:
display: grid;
grid-template-columns: repeat(auto-fit, 186px);
grid-auto-columns: min-content;
grid example 1
notice that though the last column has narrower content, it uses the same width as the other columns (186px)
I'd like the columns to shrink to the width of the content, while still wrapping as screen size collapses.
grid example 2
notice the last column is now narrower that the others.
It seems grid-template-columns: repeat(); takes two arguments. The first of which can be auto-fit or auto-fill, but the second must be a specific width. Is there any way to allow this to be automatically computed based on content width?
Here is the codepen I've been playing with to try to achieve this.
Here is the real world scenario as well:
real world example
notice the first column should be wider to fill the content, and the second column should shrink to the content.
I'm familiar with flexbox, but I'm not super familiar with grid yet. Any guidance here would be much appreciated.
You can create repeating columns that to fit content, but for fixed a amount columns. When you use auto-fit, auto-fill grid generates all cells the same width.
In your case in look like 3x3.
display: grid;
grid-template-columns: repeat(3, min-content);
*,
::after,
::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: grid;
place-items: center;
background-color: hsl(215, 100%, 98%);
position: relative;
overflow-x: hidden;
}
.container {
background-color: lightgray;
width: 760px;
display: grid;
grid-template-columns: repeat(3, min-content);
resize: horizontal;
overflow: hidden;
gap: 5px;
justify-items: center;
align-items: center;
}
.child {
background-color: gray;
display: flex;
flex-direction: column;
justify-content: center;
}
p {
text-align: center;
}
<div class="container">
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/80x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/120x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/160x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/80x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/120x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/160x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/80x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/120x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/160x75" alt="" />
</div>
</div>
It seems grid-template-columns: repeat(); takes two arguments. The first of which can be auto-fit or auto-fill, but the second must be a specific width. Is there any way to allow this to be automatically computed based on content width?
In repeat() function you can use another function minmax() as the second property. But this will not solve your problem, because the first parametr defines minimal width, example 186px and the second how large it will extend.
display: grid;
grid-template-columns: repeat(auto-fit, minmax(186px, 1fr));
*,
::after,
::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: grid;
place-items: center;
background-color: hsl(215, 100%, 98%);
position: relative;
overflow-x: hidden;
}
.container {
background-color: lightgray;
width: 760px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(186px, 1fr));
resize: horizontal;
overflow: hidden;
gap: 5px;
justify-items: center;
align-items: center;
}
.child {
background-color: gray;
display: flex;
flex-direction: column;
justify-content: center;
}
p {
text-align: center;
}
<div class="container">
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/80x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/120x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/160x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/80x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/120x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/160x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/80x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/120x75" alt="" />
</div>
<div class="child">
<p>title</p>
<img src="https://via.placeholder.com/160x75" alt="" />
</div>
</div>
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>