Using flex to align items that have flex already? - html

I am trying to have a container with many child tiles of content inside. Each child tile contains data that I want centered so that is why flex is on the child -- so that I can align the tile content.
I want to align 3 to a line evenly so I put flex on the parent class and wanted to space-evenly but that doesn't seem to work. Any ideas on what I am doing wrong?
<div class="container">
<div class="child">
<img src="">
<span>TITLE</span>
</div>
<div class="child">
<img src="">
<span>TITLE</span>
</div>
<div class="child">
<img src="">
<span>TITLE</span>
</div>
<div class="child">
<img src="">
<span>TITLE</span>
</div>
<div class="child">
<img src="">
<span>TITLE</span>
</div>
<div class="child">
<img src="">
<span>TITLE</span>
</div>
<div class="child">
<img src="">
<span>TITLE</span>
</div>
</div>
CSS
.parent {
display: flex;
max-width: 1200px;
}
.child {
display: inline-flex;
margin-bottom: 26px;
flex-direction: column;
justify-content: center;
align-items: center;
width: 396px;
height:396px;
}

You had a few key things missing. Number one, your parent container was missing the class parent so that CSS never hit its target. Opening tag is now:
<div class="container parent">
Next I added an important flex property to the .parent CSS rule, allowing the items to wrap, otherwise theres no way you can get 3-across with more than 3 items:
flex-wrap: wrap;
Adding space-between to .parent makes sure the items go edge to edge regardless of the width and space between items:
justify-content: space-between;
Then I added a width to the .child elements that is flexible that creates the 3-across layout. I used calc as a quick way to get some space between the elements instead of them touching horizontally:
width: calc(33.333% - 20px);
Also threw little images in there to see more of the inner flex effect too. Hope this helps!
.parent {
display: flex;
max-width: 1200px;
justify-content: space-between;
flex-wrap: wrap;
}
.child {
display: flex;
margin-bottom: 26px;
flex-direction: column;
justify-content: center;
align-items: center;
width: calc(33.333% - 20px);
background-color: #ccc;
}
<div class="container parent">
<div class="child">
<img src="https://picsum.photos/40">
<span>TITLE 1</span>
</div>
<div class="child">
<img src="https://picsum.photos/40">
<span>TITLE 2</span>
</div>
<div class="child">
<img src="https://picsum.photos/40">
<span>TITLE 3</span>
</div>
<div class="child">
<img src="https://picsum.photos/40">
<span>TITLE 4</span>
</div>
<div class="child">
<img src="https://picsum.photos/40">
<span>TITLE 5</span>
</div>
<div class="child">
<img src="https://picsum.photos/40">
<span>TITLE 6</span>
</div>
<div class="child">
<img src="https://picsum.photos/40">
<span>TITLE 7</span>
</div>
</div>

Related

Aligning elements of various widths to a grid without affecting the width of the entire column

I am trying to align items with various widths to a grid.
Using a min-width attribute, short elements can be aligned like that, but if an element is too wide, it will disrupt the alignment of the following elements in that row:
(apparently I'm not allowed to embed pictures. https://i.stack.imgur.com/YF2Mg.png)
What I would like to accomplish, is that after a long item, the following one will snap to the next "grid position", as I've mocked up here:
(https://i.stack.imgur.com/1tFr5.png)
I do not want there to be line-breaks in an item, and if at all possible, I'd like to avoid using JS.
Using a simple flexbox will of course not accomplish that, but it's the closest I've gotten to what I want.
#content {
color: black;
}
.container {
width: 275px;
background: gray;
border: 1px solid black;
display: flex;
flex-wrap: wrap;
}
.item {
border: 1px solid black;
background: white;
min-width: 55px;
margin: 2.5px;
padding: 2px;
}
<div id="content">
<div class="container">
<div class="item">
<span>Item 1</span>
</div>
<div class="item">
<span>Item 2a</span>
</div>
<div class="item">
<span>Item 2b</span>
</div>
<div class="item">
<span>Item 3</span>
</div>
<div class="item">
<span>Item 4 with a long name</span>
</div>
<div class="item">
<span>Item 5</span>
</div>
<div class="item">
<span>Item 6a</span>
</div>
<div class="item">
<span>Item 6b</span>
</div>
<div class="item">
<span>Item 7</span>
</div>
<div class="item">
<span>Item 8</span>
</div>
</div>
</div>
I have also looked into using grids or tables, but could not find a way for an element to span as many columns as are needed to fit its width.
This is not a fully dynamic solution, as you will have to do some styling on the specific item that is wider than the other items.
Transform the layout into a grid-layout, apply grid-template-columns: repeat(4, minmax(55px, 1fr)); which will make it a 4 column layout, where each item is at least 55px wide (better layout control than applying min-width on each item, IMO).
Target the item that is wider than the rest with nth-child or give it a specific class and use that instead, apply grid-column: span 3 which will make the item span into 3 columns inside a single row, and then give it max-width: fit-content. This way, the specific item's width will only be as wide as it has content to fill it up.
#content {
color: black;
}
.container {
width: 275px;
background: gray;
border: 1px solid black;
/* minmax 55px instead of min-width 55px on each item */
display: grid;
grid-template-columns: repeat(4, minmax(55px, 1fr));
}
.item {
border: 1px solid black;
background: white;
margin: 2.5px;
padding: 2px;
}
.item:nth-child(5) {
grid-column: span 3;
max-width: fit-content;
}
<div id="content">
<div class="container">
<div class="item">
<span>Item 1</span>
</div>
<div class="item">
<span>Item 2a</span>
</div>
<div class="item">
<span>Item 2b</span>
</div>
<div class="item">
<span>Item 3</span>
</div>
<div class="item">
<span>Item 4 with a long name</span>
</div>
<div class="item">
<span>Item 5</span>
</div>
<div class="item">
<span>Item 6a</span>
</div>
<div class="item">
<span>Item 6b</span>
</div>
<div class="item">
<span>Item 7</span>
</div>
<div class="item">
<span>Item 8</span>
</div>
</div>
</div>

if one child than width 100% otherwise 50% using flex sass css

I have an article page, so the design is like 2 group article images with 50% width, but when the only one child, then it should apply 100% width.
need help to get 50% when two child comes and 100% when one child come
i used flex on parent
design image:
.blog-body {
padding-top: rem(50);
ul{
padding: 0;
margin: 0;
display: flex;
flex-wrap: wrap;
list-style: none;
li{
position: relative;
width: 50%;
padding: 0 rem(15);
margin-bottom: rem(68);
.img-wrap{
img{
width: 100%;
height: 100%;
}
}
}
}
<section class="blog-group-sec">
<div class="blog-contain">
<div class="blog-wrap">
<div class="blog-body">
<ul class="items">
<li class="item">
<div class="img-wrap">
<img src="https://via.placeholder.com/150
C/O https://placeholder.com/" alt="">
</div>
</li>
<li class="item">
<div class="img-wrap">
<img src="https://via.placeholder.com/150
C/O https://placeholder.com/" alt="">
</div>
</li>
<li class="item">
<div class="img-wrap">
<img src="https://via.placeholder.com/150
C/O https://placeholder.com/" alt="">
</div>
</li>
</ul>
</div>
</div>
</div>
</section>
you need to add the flex-grow property be on the children
<div class="article parent">
<div class="child"> Child 1 </div>
<div class="child"> Child 2 </div>
</div>
<div class="body">
<div class="body"> 100% </div>
</div>
now this is the CSS code for this
.parent{
display: flex;
}
.child{
flex-grow: 1; // grow at equal ratios to the parent
}
This works for me. i hope it works for you too

How to set images under each image in vertical and horizontal order?

I want to align the images and text in the vertical and horizontal order as below:
Expected Image:
I have used display: flex and flex-direction: row as well as justify-content: space-evenly
But I am getting this image as a result:
Result Image:
Suggest some ideas on how to align the items as per the first image.
You can also try using text-align: center, margin: auto, and display: flex. The justify-content property works together with display: flex, which we can use to center the image. For more details, check out this link. Hope that helped!
Have you tried a HTML table?
By using the columns and rows of the table, you could put all icons and text in order.
Find out more about the table tag at w3schools: https://www.w3schools.com/html/html_tables.asp
.row {display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; flex-wrap: wrap;}
.items {width: 20%; float: left; display: block; position: relative;}
.items img{width:80%; height: auto; margin: auto; display: block;}
.items p{max-width:90%;text-align: center; margin: auto; display: block;}
<div class="row">
<div class="items">
<img src="https://img.icons8.com/wired/64/000000/change-user-male.png"/>
<p>lorem loremlorem lorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/doodle/96/000000/user-male--v1.png"/>
<p>loremlorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/doodle/96/000000/cottage--v1.png"/>
<p>lorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/office/160/000000/user-folder.png"/>
<p>lorem lorem lorem</p>
</div>
<div class="items">
<img src="https://maxst.icons8.com/vue-static/icon/collection-favorites.png"/>
<p>lorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/doodle/96/000000/user-male--v1.png"/>
<p>lorem lorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/dusk/64/000000/dog-house--v1.png"/>
<p>loremlorem lorem lorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/doodle/96/000000/user-male--v1.png"/>
<p>lorem lorem lorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/ultraviolet/120/000000/house-lannister.png"/>
<p>lorem lorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/flat_round/64/000000/rental-house-contract.png"/>
<p>loremlor em lorem</p>
</div>
</div>
Try this
.flex-container {
display: flex;
flex-wrap: wrap;
justify-content: space-evenly
}
.flex-container > * { // flex-items
flex: 0 1 160px; // 160px is sort of the maximum width, change it to suit your situation
}
This will work perfectly if there's an equal number of items in the rows and columns, as in your situation.
Why not use display:grid? It has good support in all current browsers and partial support in IE.
.row {display:grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); align-items: center; justify-items: center; gap: 20px}
.items {width: auto; display: block; position: relative;}
.items img{width:80%; height: auto; margin: auto; display: block;}
.items p{max-width:90%;text-align: center; margin: auto; display: block;}
<div class="row">
<div class="items">
<img src="https://img.icons8.com/wired/64/000000/change-user-male.png"/>
<p>lorem loremlorem lorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/doodle/96/000000/user-male--v1.png"/>
<p>loremlorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/doodle/96/000000/cottage--v1.png"/>
<p>lorem lorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/office/160/000000/user-folder.png"/>
<p>lorem lorem lorem</p>
</div>
<div class="items">
<img src="https://maxst.icons8.com/vue-static/icon/collection-favorites.png"/>
<p>lorem lorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/doodle/96/000000/user-male--v1.png"/>
<p>lorem lorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/dusk/64/000000/dog-house--v1.png"/>
<p>loremlorem lorem lorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/doodle/96/000000/user-male--v1.png"/>
<p>lorem lorem lorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/ultraviolet/120/000000/house-lannister.png"/>
<p>lorem lorem</p>
</div>
<div class="items">
<img src="https://img.icons8.com/flat_round/64/000000/rental-house-contract.png"/>
<p>loremlor em lorem</p>
</div>
</div>

Break line using Flex keeping elements centered

This is another CSS Flex question, I'm sorry but I've been struggling a lot using Flex, I'm trying to make a kind of slider, in which it will have a left and right arrow and elements in between, like so:
The problem I'm facing is that in certain number of elements I need to break a line, keeping the alignment center both vertically and horizontally, like this: (paint pro editing)
I can't find a way to do this, I'm lost.
This is my actual code for the first image:
HMTL:
<div class="main allin">
<div class="left-arrow">
<i class="material-icons">keyboard_arrow_left</i>
</div>
<div class="flex-con ">
<div class="item-1">
<img src="https://via.placeholder.com/250" />
</div>
<div class="item-2">
<img src="https://via.placeholder.com/250" />
</div>
<div class="item-3">
<img src="https://via.placeholder.com/250" />
</div>
</div>
<div class="right-arrow">
<i class="material-icons">keyboard_arrow_right</i>
</div>
</div>
<div class="main break">
<div class="left-arrow">
<i class="material-icons">keyboard_arrow_left</i>
</div>
CSS:
.main{
display:flex;
justify-content: center;
align-items: center;
}
.flex-con{
display:flex;
align-items: center;
}
.flex-con div{
padding:20px;
}
And this is a CodePen
How can I achieve this? thanks.
Put all your item-x elements within the same flex-con wrapper.
Then, simply add the following properties:
flex-wrap: wrap; // to wrap its children into multiple lines
justify-content: center; // to center horizontally
.main {
display: flex;
justify-content: center;
align-items: center;
}
.flex-con {
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: center;
}
.flex-con div {
padding: 20px;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/material-design-icons/3.0.1/iconfont/material-icons.min.css" />
<div class="main break">
<div class="left-arrow">
<i class="material-icons">keyboard_arrow_left</i>
</div>
<div class="flex-con ">
<div class="item-1">
<img src="https://via.placeholder.com/250" />
</div>
<div class="item-2">
<img src="https://via.placeholder.com/250" />
</div>
<div class="item-3">
<img src="https://via.placeholder.com/250" />
</div>
<div class="item-4">
<img src="https://via.placeholder.com/250" />
</div>
<div class="item-5">
<img src="https://via.placeholder.com/250" />
</div>
</div>
<div class="right-arrow">
<i class="material-icons">keyboard_arrow_right</i>
</div>
</div>
Click Full page for better demonstration.

Flexboxes overlapping in IE 11

I'm currently debugging a website to make it work on IE 11. Now there is one page, were there are two div tables inside a flexbox container. Under the container, there is another flexbox 'navLine', which should be positioned directly under the container. This works fine in every browser except IE 11. There the container and the navLine seem to overlap. Oddly enough, the navLine sticks to a button within the container. The button is within a cell of the div table, without any additional CSS properties.
Any help?
Here's the simplified code:
#NavLine
{
margin-bottom: 8px;
display: -webkit-flex;
display: -ms-flex;
display: flex;
justify-content: space-between;
align-items: center;
}
.SelectionBox
{
background: #f7f7f7;
border: 1px solid #d9d9d9;
padding: 16px;
margin-bottom: 16px;
min-width: 570px;
min-height: 410px;
}
.Container
{
display: -webkit-flex;
display: -ms-flex;
display: flex;
-webkit-justify-content: space-around;
-ms-justify-content: space-around;
justify-content: space-around;
width: 100%;
flex: 1 1 auto;
}
#Box1, #Box2
{
flex: 1 1 auto;
padding: 16px;
}
.Table
{
display: table;
table-layout: fixed;
overflow: hidden;
height: 100%;
width: 75%;
}
.Title
{
display: table-header-group;
width: 100%;
height: 80px;
}
.Row
{
display: table-row;
}
.Cell
{
display: table-cell;
padding-left: 5px;
padding-right: 5px;
vertical-align: middle;
height: 70px;
}
<div class="Container">
<!-- First Box -->
<div id="Box1">
<div class="Table SelectionBox">
<div class="Title">
<h2>Box One</h2>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell"></div>
<div class="Cell">
<span> ([[result]]) Results</span>
<span>Reset (this is a button)</span>
</div>
</div>
</div>
</div>
<!-- Second Box -->
<div id="Box2">
<div class="Table SelectionBox">
<div class="Title">
<h2>Box Two</h2>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell">
<span>Some Item</span>
</div>
<div class="Cell">
<span>Some Value</span>
</div>
</div>
<div class="Row">
<div class="Cell"></div>
<div class="Cell">
<span> ([[result]]) Results</span>
<span>Reset (this is a button)</span>
</div>
</div>
</div>
</div>
</div>
<div id="NavLine">
<span>Back</span>
<span>Next</span>
</div>
The problem in IE is that height: 100% in .Table.SelectionBox is causing that element to overflow its container (#Box1). It then overlaps the #NavLine element, which is not causing any problem.
One way to fix the problem is to remove that height rule.
"IE 11 requires a unit to be added to the third argument, the flex-basis property" - see "known issues" tab https://caniuse.com/#feat=flexbox
also, a min-height might be required
so, try for example:
#container > div {
flex:1 1 8em;
min-height:8em;
}