Center text with images in flexbox - html

I'm making a webpage and need to center-align 3 divs as promo content, like that:
In order to get this spacing and alignment, I added invisible images and made then hidden on mobile, so they get responsive, like that:
<div id="promocontent">
<img class="img-responsive" src="img/iconenope.png">
<img class="img-responsive hidden hide-on-med-and-down" src="img/iconehidden.png">
<img class="img-responsive" src="img/iconenope.png">
<img class="img-responsive hidden hide-on-med-and-down" src="img/iconehidden.png">
<img class="img-responsive" src="img/iconenope.png"><br><br>
</div>
CSS:
#promocontent {
display: flex; /* establish flex container */
flex-direction: row; /* default value; can be omitted */
flex-wrap: nowrap; /* default value; can be omitted */
justify-content: space-between; /* switched from default (flex-start, see below) */
padding: 5px;
}
Now, I need to add text on the center-bottom of these images, something like:
So, how can I do that (responsively working)? Align 2 lines of text (maybe 1, but 2 would be better).
Thank you.

#promocontent {
display: flex;
justify-content: space-between;
padding: 5px;
}
#promocontent > div {
display: flex;
flex-direction: column;
align-items: center; /* horizontally center child elements */
text-align: center; /* horizontally center text on narrow screens;
see http://stackoverflow.com/q/39678610/3597276 */
}
<div id="promocontent">
<div>
<img class="img-responsive" src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt="">
<h2>header text</h2>
<span>text text text text text</span>
</div>
<div>
<img class="img-responsive" src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt="">
<h2>header text</h2>
<span>text text text text text</span>
</div>
<div>
<img class="img-responsive" src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt="">
<h2>header text</h2>
<span>text text text text text</span>
</div>
</div>
https://jsfiddle.net/x2rzj1cu/2/

I would avoid using an extra image for spacing and just rely on justify-content: space-between
Feel free to check out my codepen (basically the same as Michaels).
http://codepen.io/anon/pen/zKmaVJ

Related

Is there a way to have different justify-content values for different rows inside a flexbox-container?

Is there a way to have different justify-content values for different rows inside a flexbox-container?
Here is my html:
<div class="wrapper flex-container">
<div class="flex-item">
<h2>Text</h2>
<p>Text</p>
</div>
<div class="flex-item">
<h2>Text</h2>
<p>Text</p>
</div>
<figure class="flex-item"><img src="materiale/junckers.png" alt="junckers"></figure>
<figure class="flex-item"><img src="materiale/byg-garanti.png" alt="byg-garanti"></figure>
<figure class="flex-item"><img src="materiale/gulvbranchen.png" alt="gulvbranchen"></figure>
</div>
I want the first two flex-items (the two div's) to fill one row and to be aligned in accordance with justify-content: space-between;
And I want the three last flex-items (the three figure's) to fill the next row and to be aligned in accordance with justify-content: space-evenly;
Is that possible in the same flex-container?
The answer is no.
In grid, there is the justify-self property in which this would be true. However, in flex there is no support for this style as of May 2022.
flex does support align-self for aligning flex item's on the y-axis (align-items), but not for the x-axis (justify-content).
The good news.
You can still replicate these styles in your stylesheet but they will have to be done manually. You can target the first and second flex-item and use width: calc(100%/2) for the first two flex items that you want to each take 50%. Then you can add flex-wrap: wrap on to your flex-container so the image flex-items wrap onto a new row. Then you can replicate justify-content: space-between; by adding margin: auto; to those respective flex-items.
See below:
.flex-container {
display: flex;
flex-wrap: wrap;
}
.flex-item:first-child,
.flex-item:nth-child(2) {
width: calc(100%/2);
outline: dotted 1px black;
}
.flex-item:nth-child(3),
.flex-item:nth-child(4),
.flex-item:nth-child(5) {
outline: solid 1px;
background: orange;
padding: 10px;
}
<div class="wrapper flex-container">
<div class="flex-item">
<h2>Text</h2>
<p>Text</p>
</div>
<div class="flex-item">
<h2>Text</h2>
<p>Text</p>
</div>
<figure class="flex-item" style="margin-right: auto;"><img src="https://dummyimage.com/100/000/fff" alt="junckers"></figure>
<figure class="flex-item" style="margin: auto;"><img src="https://dummyimage.com/100/000/fff" alt="byg-garanti"></figure>
<figure class="flex-item" style="margin-left: auto;"><img src="https://dummyimage.com/100/000/fff" alt="gulvbranchen"></figure>
</div>

flexbox - last box heigher than others

I have a problem with flexbox. The last box in a row has more height than others. I see that if I give specific height to the boxes I will achieve the same height on the boxes but since I am trying to make responsive site I wondering it is better way to define height and not using px sizing. The boxes including images and text inside. I have tried to put % on the height but it doesn't change anything. What is the best way to use in this case to avoid many jobs in media query later? is the px the only solution?
Thank you in advance
the boxes look like this:
Code:
.footer-box {
display: flex;
justify-content: center;
width: 100%;
flex-wrap:wrap; // using wrap for wraping on smaller devices
}
.box {
text-align: center;
width:20%;
height: auto;
margin: 10px;
}
<div class="footer-box">
<div class="box box1">
<img src="./images/other/pic1.jpg" alt="">
<p>lorem text</p>
</div>
<div class="box box2">
<img src="./images/other/pic1.jpg" alt="">
<p>lorem text</p>
</div>
<div class="box box3">
<img src="./images/other/pic1.jpg" alt="">
<p>lorem text</p>
</div>
<div class="box box4">
<img src="./images/other/pic1.jpg" alt="">
<p>lorem text</p>
</div>
Thank you in advance
You can use flexbox and flex-direction:column for .box.
Also you should use align-items: stretch for .footer-box. Because all child items will have same heights with this code.
Lastly, through flex: 1 1 auto; we can fill with img.
And bonus: object-fit: cover is for your img sizes.
.footer-box {
display: flex;
justify-content: center;
width: 100%;
flex-wrap: wrap; // using wrap for wraping on smaller devices
align-items: stretch;
}
.box {
text-align: center;
width: 20%;
height: auto;
margin: 10px;
display: flex;
flex-direction: column;
}
.box img {
flex: 1 1 auto;
object-fit: cover;
}
<div class="footer-box">
<div class="box box1">
<img src="https://dummyimage.com/50x50/000/fff" alt="">
<p>lorem text</p>
</div>
<div class="box box2">
<img src="https://dummyimage.com/50x50/000/fff" alt="">
<p>lorem text</p>
</div>
<div class="box box3">
<img src="https://dummyimage.com/50x50/000/fff" alt="">
<p>lorem text</p>
</div>
<div class="box box4">
<img src="https://dummyimage.com/50x70/000/fff" alt="">
<p>lorem text</p>
</div>
</div>

Place wrapping items in the center of the grid

I have a CSS Grid layout which looks like below:
This works perfectly for me, but when I lower the resolution of the screen, the grid's responsiveness makes the grid look like this:
Instead, I want the wrapping items to justify the left and right white spaces, and they should look like this:
How can I achieve the above? The items are dynamic in number. There can be even number of items which will make it look better as the left and right white spaces will be equally spaced. But if the items are odd in number the white spaces should still be equally distributed. I tried with grid-auto-flow and align-items, but they don't seem to be helping.
.accordioninnergrid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.innerbox {
display: flex;
border: 1px solid black;
flex-direction: column;
align-items: center;
word-wrap: break-word;
width: auto;
}
.innerbox>p,
img {
margin: 1%;
}
<div class="accordioninnergrid">
<div class="innerbox">
<img src="some-image" width="50%" height="50%" />
<p>
This is the text
</p>
<p>
Small Tagline
</p>
</div>
<div class="innerbox">
<img src="some-image" width="50%" height="50%" />
<p>
This is the text
</p>
<p>
Small Tagline
</p>
</div>
<div class="innerbox">
<img src="some-image" width="50%" height="50%" />
<p>
This is the text
</p>
<p>
Small Tagline
</p>
</div>
<div class="innerbox">
<img src="some-image" width="50%" height="50%" />
<p>
This is the text
</p>
<p>
Small Tagline
</p>
</div>
<div class="innerbox">
<img src="some-image" width="50%" height="50%" />
<p>
This is the text
</p>
<p>
Small Tagline
</p>
</div>
</div>
This is a problematic layout with Grid or Flex. There's no simple solution with either.
With Grid, there's no way to automatically position items in the middle columns. How does the grid know it needs to place grid items in, let's say, columns 3, 4 and 5, so that they appear centered?
Worse, what if there were only four columns and one item to center? That item would have to span across columns 2 and 3.
There's no grid function that does this automatically. It must be author-defined.
With Flex, the problem above doesn't exist. But there's a trade-off. Flex has a problem that Grid doesn't have.
It stems from this section of the code:
.accordioninnergrid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
The grid-template-columns rule is saying that each column can be a minimum width of 240px, and a maximum width of 1fr (i.e., all available space).
In flex, the property to use in place of the fr function would be flex-grow.
But, because there are no column tracks impeding movement across the line in a flex container, flex-grow is free to expand items across the entire line.
In short, flex-grow and centering cannot co-exist.
If flex-grow were removed, then you'd have no problem centering with flex. But, of course, there would be another trade-off: you would lose the consumption of free space feature:
.accordioninnergrid {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.innerbox {
flex: 1 0 140px; /* fg, fs, fb -- try fg: 0 */
display: flex;
border: 1px solid black;
flex-direction: column;
align-items: center;
word-wrap: break-word;
}
.innerbox > p,
img {
margin: 1%;
}
<div class="accordioninnergrid">
<div class="innerbox">
<img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt="">
<p>
This is the text
</p>
<p>
Small Tagline
</p>
</div>
<div class="innerbox">
<img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt="">
<p>
This is the text
</p>
<p>
Small Tagline
</p>
</div>
<div class="innerbox">
<img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt="">
<p>
This is the text
</p>
<p>
Small Tagline
</p>
</div>
<div class="innerbox">
<img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt="">
<p>
This is the text
</p>
<p>
Small Tagline
</p>
</div>
<div class="innerbox">
<img src="http://i.imgur.com/60PVLis.png" width="50" height="50" alt="">
<p>
This is the text
</p>
<p>
Small Tagline
</p>
</div>
</div>
More details here:
Aligning grid items across the entire row/column (like flex items can)
Targeting flex items on the last or specific row

Specific columns

I've been doing some stuff with HTML and I need to have a few columns. I know how to make them and the basics of how they work. However, there is a certain problem that I have. I need to have 3 columns that have an image on top, then text on bottom. However, the text on bottom can't flow into the next column if the browser is resized - it just needs to go up or down. What I have so far:
body {
background-color: white;
font-family: times, serif;
color: black;
}
div {
display: flex;
margin: 50px;
flex-wrap: wrap;
}
<div>
<div class="first">
<img src="Images/australia_flag.jpg" alt="Australian Flag" title="Australian Flag" height="200" width="300"> text as well </div>
<div class="second">
<img src="Images/brazil_flag.jpg" alt="Brazilian Flag" title="Brazilian Flag"> even more text </div>
<div class="third">
<img src="Images/china_flag.jpg" alt="Chinese Flag" title="Chinese Flag" height="200" width="300"> text again
</div>
</div>
not entirely sure if you mean columns or rows? Based on your code, it looks like rows. If that's the case, I'm not sure what you mean by "flow into the next column"? You might check out the relative and absolute values for CSS position.
If, in fact, you do actually mean columns, I'd strongly advise using Bootstrap's Grid System. This is great for creating responsive columns.
Please take a look at this simple 3 column layout with a full width content area on top and bottom here: https://jsfiddle.net/7drfva0o/2/
.top, .bottom {
width:98%;
padding:1%;
background-color: red;
clear:both;
}
.cols {
width:31%;
padding:1%;
float:left;
background-color:blue;
border: 1px solid #FFF;
}
Is that what you're looking for?
First, you'll need to improve your markup: having images and texts as DOM node to be "flexed"
HTML markup improved
<div class="wrapper">
<div class="column">
<img src="..." />
<p>text</p>
</div>
<div class="column">
<img src="..." />
<p>text</p>
</div>
<div class="column">
<img src="..." />
<p>text</p>
</div>
</div>
Then, each of your div is going to have display: flex + flex-direction: column to allow the image going on top and the text going below. You will be able to adjust margin or whatever. At the minimum, I'd go like this:
CSS improved
.wrapper {
display: flex;
}
.column {
margin: 5px;
display: flex;
flex-direction: column;
}
Wrapped altogether, here is a snippet of what I think you're trying to achieve
Snippet
.wrapper {
display: flex;
}
.column {
margin: 5px;
display: flex;
flex-direction: column;
}
<div class="wrapper">
<div class="column">
<img src="http://fakeimg.pl/300x200" />
<p>text as well</p>
</div>
<div class="column">
<img src="http://fakeimg.pl/300x200" />
<p>text as well</p>
</div>
<div class="column">
<img src="http://fakeimg.pl/300x200" />
<p>text as well</p>
</div>
</div>
Then, feel free to play with flexbox properties to align, wrap, adjust alignments, etc. Great documentation on CSS-Tricks : https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Align elements in a row and horizontally centered in their column

I'm trying to make a grid with some icons and their respective id.
For example, I have this code using bootstrap:
.flex {
display: flex;
align-items: center;
height: 200px;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
rel="stylesheet" />
<div class="row flex">
<div class="col-md-2">
<img src="http://placehold.it/300x300" alt="" class="img-responsive">
<p class="text-center channel-number">2</p>
</div>
<div class="col-md-2">
<img src="http://placehold.it/300x100" alt="" class="img-responsive">
<p class="text-center channel-number">4</p>
</div>
<div class="col-md-2">
<img src="http://placehold.it/300x400" alt="" class="img-responsive">
<p class="text-center channel-number">11</p>
</div>
</div>
now the number will just stay right under the image, but I want the number to be horizontally align with the other numbers and centered below the image.
How can I do this?
Using flex or does bootstrap has a way of doing this?
Thanks!
Fiddle
Try this:
HTML (no changes)
CSS
.flex {
display: flex;
min-height: 200px;
}
.flex > .col-md-2 {
display: flex; /* create nested flex container */
flex-direction: column; /* stack children (image and number) vertically */
}
img { margin: auto;} /* forces numbers to bottom edge of container */
Revised Fiddle
Learn more about justify-content and auto margins here:
Methods for Aligning Flex Items