I'm using the following code to display 5 images (without the use of background) distributed evenly across a container and with an equal height equivalent to the tallest image (although I wonder if it would be possible to do this with the shortest one). Applying flex: 1; on the image-container gives me the desired effect under firefox, but under chrome the 5 images appear vertically stretched and oversized. The desired effect is to keep every container filled under a given width while minimizing loss of aspect ratio.
Edit: I've loaded this page under both browsers and I do get the effect I wanted although they are rendered differently. Now I need to find what's wrong with my version compared to the one I posted here.
body {
width: 300px;
}
.container {
display: flex;
flex-wrap: wrap;
height: 100%;
width: 100%;
background-color: black;
}
.row1 {
display: flex;
width: 100%;
background-color: blue;
}
.column {
height: 100%;
width: 20%;
display: flex;
flex-flow: column;
position: relative;
background-color: red;
}
.image-container {
overflow: hidden;
display: flex;
flex: 1;
background-color: yellow;
}
img {
width: 100%;
height: auto;
}
.image-label {
width: 100%;
height: 35px;
display: flex;
background-color: green;
justify-content: center;
}
.row2 {
display: flex;
width: 100%;
flex-flow: row wrap;
background-color: cyan;
height: 20px;
}
<div class="container">
<div class="row1">
<div class="column">
<div class="image-container">
<img src="http://www.koka.ac.jp/admission/wp-content/themes/admission/assets/img/common/floating-btn-internet.gif">
</div>
<div class="image-label">img1</div>
</div>
<div class="column">
<div class="image-container">
<img src="http://www.moglix.com/themes/et_poostyle/img/offer.jpg">
</div>
<div class="image-label">img2</div>
</div>
<div class="column">
<div class="image-container">
<img src="http://i.imgur.com/slhFy4T.png">
</div>
<div class="image-label">img3</div>
</div>
<div class="column">
<div class="image-container">
<img src="http://alma-sys.com/images/SLIDE%20MENU%20IMG/WEB%20D%20-%20Copy.jpg">
</div>
<div class="image-label">img4</div>
</div>
<div class="column">
<div class="image-container">
<img src="http://amerpages.com/app/webroot/img/items/121/16716/pds/19682_s.jpg">
</div>
<div class="image-label">img5</div>
</div>
</div>
<div class="row2"></div>
</div>
Related
I'm 99% sure about this but thought i'd ask to see if anyone knew of any clever solutions.
Basically I wish to place an image in a 1/1 aspect containing element, and then for that image to be as as as it possibly can be, eg, landscape images always touch the left and right sides and portrait ones touch the top and bottom.
I then want a line of caption text underneath the image.
My question is, is there any way to get that size of image but without (for landscape images) the large gap between the photo and the caption?
My example image below shows the problem (please note the image is not full left to right edge here like I want).
Anyone know of any clever options to achieve this?
<figure class="photo-1 landscape">
<div class="image-wrapper gallery">
<a href="https://farm66.staticflickr.com/65535/48808899778_bb1d4d1272_b.jpg" data-pswp-width="4032" data-pswp-height="3024" target="_blank">
<img src="https://farm66.staticflickr.com/65535/48808899778_bb1d4d1272_m.jpg">
</a>
</div>
<figcaption>Hersheypark</figcaption>
</figure>
figure {
display: flex;
flex-direction: column;
gap: 0.5rem;
.image-wrapper {
aspect-ratio: 1/1;
}
a {
display: block;
}
img {
display: block;
max-width: 100%;
max-height: 100%;
}
&.landscape {
a {
min-width: 100%;
}
img {
width: 100%;
}
}
&.portrait {
a {
min-height: 100%;
}
img {
height: 100%;
}
}
figcaption {
text-align: center;
color: hsl(var(--color-secondary));
font-size: var(--fs--1);
}
}
This is what I got so far.
body {
background-color: #F8F9F9;
}
.container {
display: flex;
gap: 20px;
}
.card {
display: flex;
flex-direction: column;
flex-basis: 0;
flex-grow: 1;
gap: 10px;
}
.image {
display: flex;
align-items: center;
background-color: #ffffff;
overflow: hidden;
}
.image.hor {
flex-direction: row;
}
.image.ver {
flex-direction: column;
aspect-ratio: 1/1;
}
.image img {
flex-grow: 1;
max-width: 100%;
max-height: 100%;
}
.caption {
padding: 5px 10px;
font-size: 14px;
text-align: center;
background-color: #ffffff;
}
<div class="container">
<div class="card">
<div class="image hor">
<img src="https://dummyimage.com/100x50/000/fff" />
</div>
<div class="caption">
Landscape image (small)
</div>
</div>
<div class="card">
<div class="image hor">
<img src="https://dummyimage.com/1000x500/000/fff" />
</div>
<div class="caption">
Landscape image (large)
</div>
</div>
<div class="card">
<div class="image ver">
<img src="https://dummyimage.com/50x100/000/fff" />
</div>
<div class="caption">
Portrait image (small)
</div>
</div>
<div class="card">
<div class="image ver">
<img src="https://dummyimage.com/500x1000/000/fff" />
</div>
<div class="caption">
Portrait image (large)
</div>
</div>
</div>
Update : I have edited the snippet to show better what I'm trying to achieve...
I have a number of tables of data, each of variable length, on a kiosk display. I want to fill the viewport as columns then overflow to pages below ie paging down would give me next screen of data. I thought Nested Flexbox would allow me to do this but the outer Container doesn't do what I hoped and data just flows to right - see below. Am I just inept or should I be doing it another way? Thx!
.container1 {
background: lightgrey;
display: flex;
width:300px;
flex-direction: column;
flex-wrap:wrap;
}
.container2 {
background: orangered;
display: flex;
flex-direction: column;
height:200px;
width: 300px;
flex-wrap: wrap;
}
.container2 > div{
font-size: 40px;
width: 100px;
}
.green {
background: yellowgreen;
}
.blue {
background: steelblue;
}
My effort doesn't work ...
<div class="container1">
<div class="container2">
<div class="green">1a<br>1b<br>1c</div>
<div class="blue">2a<br></div>
<div class="green">3a<br>3b</div>
<div class="blue">4a<br>4b<br>4c</div>
<div class="green">5a<br>5b</div>
<div class="blue">6a<br></div>
<div class="green">7a<br>7b</div>
<div class="blue">8a<br>8b<br>8c</div>
<div class="green">9a<br>9b<br>9c</div>
<div class="blue">10a<br></div>
<div class="green">11a<br>11b</div>
<div class="blue">12a<br>12b<br>12c</div>
</div>
</div>
I want output like this but ...
<div class="container2">
<div class="green">1a<br>1b<br>1c</div>
<div class="blue">2a<br></div>
<div class="green">3a<br>3b</div>
<div class="blue">4a<br>4b<br>4c</div>
</div>
<div class="container2">
<div class="green">5a<br>5b</div>
<div class="blue">6a<br></div>
<div class="green">7a<br>7b</div>
<div class="blue">8a<br>8b<br>8c</div>
</div>
<div class="container2">
<div class="green">9a<br>9b<br>9c</div>
<div class="blue">10a<br>10a<br></div>
<div class="green">11a<br>11b</div>
<div class="blue">12a<br>12b<br>12c</div>
</div>
You don't want to use flex-direction: column on the inner container2. You still want that to be row.
Setting flex-direction: column only establishes that the direction of children should flow from top to bottom (or reverse with column-reverse).
Setting flex-wrap: wrap on a parent with flex-direction: column wraps the elements on the cross axis (row in this case).
You don't even need the outer parent container, since there was only one flex child container2.
.container2 {
background: orangered;
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 300px;
height: 200px;
overflow: scroll;
}
.container2 > div {
font-size: 40px;
flex: 0 0 33.33333%;
min-height: 200px;
}
.green {
background: yellowgreen;
}
.blue {
background: steelblue;
}
<div class="container2">
<div class="green">1a<br>1b<br>1c</div>
<div class="blue">2a<br></div>
<div class="green">3a<br>3b</div>
<div class="blue">4a<br>4b<br>4c</div>
<div class="green">1a<br>1b<br>1c</div>
<div class="blue">2a<br></div>
<div class="green">3a<br>3b</div>
<div class="blue">4a<br>4b<br>4c</div>
<div class="green">1a<br>1b<br>1c</div>
<div class="blue">2a<br></div>
<div class="green">3a<br>3b</div>
<div class="blue">4a<br>4b<br>4c</div>
</div>
I'm trying to achieve the following:
I was able to replicate the image but only if my div is not floating in the page (without the margin applied and without the position: absolute), otherwise I can't see the green rectangle.
My HTML structure is the following:
<div class="app">
<div class="interface">
<div class="view">
<div class="body">
<div class="top">
Top content
</div>
<div class="middle">
Middle content
</div>
<div class="bottom">
Bottom content
</div>
</div>
</div>
</div>
</div>
In the .interface CSS I have the following:
.interface
{
position: absolute;
top: 15%;
}
With this CSS I'm unable to see the green rectangle. If I remove the position: absolute (and therefore the top: 15% stops applying) I'm able to see the green rectangle.
You can see the issue in this JSFiddle: https://jsfiddle.net/v9euwdz3/
So, how do I manage to have the DIV showing at a certain level (margin from top) and without compromise my HTML structure?
Here is what you're trying to achieve using flex:
.body {
display: flex;
flex-direction: column;
background-color: blue;
justify-content: space-between;
height: 100vh;
}
.navetc {
background-color: white;
height: 15vh;
}
.top {
background-color: green;
height: 60px;
}
.middle {
background-color: yellow;
flex-grow: 1;
}
.bottom {
background-color: red;
height: 50px;
}
<div class="app">
<div class="interface">
<div class="view">
<div class="body">
<div class="navetc">
SPACE
</div>
<div class="top">
Top content
</div>
<div class="middle">
Middle content
</div>
<div class="bottom">
Bottom content
</div>
</div>
</div>
</div>
</div>
You could also use margin-top: 15%; instead of a placeholder div
.body {
display: flex;
flex-direction: column;
background-color: blue;
justify-content: space-between;
height: 100vh;
}
.top {
margin-top: 15vh;
background-color: green;
height: 60px;
}
.middle {
background-color: yellow;
flex-grow: 1;
}
.bottom {
background-color: red;
height: 50px;
}
<div class="app">
<div class="interface">
<div class="view">
<div class="body">
<div class="top">
Top content
</div>
<div class="middle">
Middle content
</div>
<div class="bottom">
Bottom content
</div>
</div>
</div>
</div>
</div>
(I used vh instead of % to get it to show up correctly in this code snippet)
as we know the content that have height which is 100% means is 100% of its parent and while the height of the parent is not defined will cause an error that's what you was stuck with you set the with of body to 100% but was not right you would set it to 100vh to fit the screen if you are on computer and the other mistakes that I found was in your calculation where you used to subtract the measurement which is in parcentages from the one in pixels height: calc(100% - 150px); and the others where simple mistakes
html,
body {
height: 100vh;
}
.app {
position: relative;
height: 100%;
display: flex;
}
.interface {
position: absolute;
height: 100%;
top: 15%;
}
.view {
position: fixed;
height: 100%;
background-color: #ccc;
width: 350px;
}
.body {
position: relative;
height: 100%;
}
.body .top {
height: 15%;
border: 1px solid #000;
}
.body .middle {
height: 60%;
border: 1px solid red;
}
.body .bottom {
height: 20%;
border: 1px solid green;
}
<div class="app">
<div class="interface">
<div class="view">
<div class="body">
<div class="top">
Top content
</div>
<div class="middle">
Middle content
</div>
<div class="bottom">
Bottom content
</div>
</div>
</div>
</div>
</div>
to see the result in the snippet you should observe it in full page and also when you see the result through jsfiddle there at the result section there is bar downward which hide some part of footer
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I need help laying out my html with css flexbox (I hope this is doable with flexbox).
I have a Container with a variable amount of images. Image can be either landscape or portrait orientation. If image is landscape (Image 1) - it will occupy one 'row'. If image is portrait - there are two cases:
If there is one portrait image in a 'row' (either it's the last image, or the next one is landscape) - then Image 2 should be centered on the 'row'.
If there are two successive portrait images - I'd like them to both fit into one 'row'
Pls note, that the 'rows' are an abstract notion here. I don't want to use css grid (unless there are absolutely no other options).
Using a flexbox in combination with the justify-content: center; and flex-wrap: wrap; should achieve the exact effect you are looking for.
Please see the two code snippets below for the two examples. I have used multiple coloured div with a width and height to simulate the horizontal and vertical image types you referred to.
.flex {
display: flex;
flex-wrap: wrap;
width: 100px;
border: 2px black solid;
padding: 1em;
justify-content: center;
}
.horizontal {
background: yellow;
width: 100px;
height: 50px;
margin-bottom: 1em;
}
.vertical {
background: green;
width: 50px;
height: 100px;
}
<div class="flex">
<div class="horizontal">Image 1</div>
<div class="vertical">Image 2</div>
</div>
.flex {
display: flex;
flex-wrap: wrap;
width: 100px;
border: 2px black solid;
padding: 1em;
justify-content: center;
}
.horizontal {
background: yellow;
width: 100px;
height: 50px;
margin-bottom: 1em;
}
.vertical {
background: green;
width: 50px;
height: 100px;
}
#blue {
background: blue;
}
<div class="flex">
<div class="horizontal">Image 1</div>
<div class="vertical">Image 2</div>
<div class="vertical" id="blue">Image 3</div>
</div>
This can be done with align-items: center and flex-wrap:wrap:
.flex{
width: 220px;
display:flex;
align-items: center;
flex-wrap:wrap;
}
.flex img{
border: solid 4px #efefef;
box-sizing:border-box;
margin: 0 auto;
}
<h3>Example 1</h3>
<div class="flex">
<img src="https://placekitten.com/220/60">
<img src="https://placekitten.com/110/120">
</div>
<h3>Example 2</h3>
<div class="flex">
<img src="https://placekitten.com/220/60">
<img src="https://placekitten.com/100/120">
<img src="https://placekitten.com/100/120">
</div>
You can easily achieve this using the same grid system as Bootstrap using class like container, row, col:
.container {
display: flex;
flex-direction: column;
}
.row {
display: flex;
}
.align-center {
align-items: center;
justify-content: center;
}
.image1 {
width: 500px;
height: 300px;
background-color: red;
}
.image2,
.image3 {
width: 250px;
height: 500px;
}
.image2 {
background-color: yellow;
}
.image3 {
background-color: blue;
}
.image1,
.image2,
.image3 {
border: solid #000 2px;
}
<div class="container align-center">
<div class="row">
<div class="col image1">
<h1>image1</h1>
</div>
</div>
<div class="row align-center">
<div class="col image2">
<h1>image2</h1>
</div>
</div>
</div>
<div class="container align-center">
<div class="row">
<div class="col image1">
<h1>image1</h1>
</div>
</div>
<div class="row align-center">
<div class="col image2">
<h1>image2</h1>
</div>
<div class="col image3">
<h1>image3</h1>
</div>
</div>
</div>
I have a list of flex items within a flexbox. The order of the items matter, and for accessibility purposes, the items need to show up in the correct order in the dom.
[[itema][itemb][itemc]]
When the flexbox shrinks I would like to have the items wrap in reverse order, e.g. itema wraps first, etc. Is there any way to have the itema wrap first? Thanks!
Edit:
Here is the code
<div class="flex">
<div class="container">
<div class="item">item1</div>
<div class="item orange">item2</div>
<div class="item blue">item3</div>
</div>
<div class="last-item green">menu</div>
</div>
.flex {
display: flex;
background-color: yellow;
height: 80px;
overflow: hidden;
color: #fff;
}
.container {
display: flex;
flex: 1 1 auto;
flex-wrap: wrap;
}
.item {
flex: 0 0 auto;
background-color: red;
height: 80px;
padding: 0 40px;
}
.last-item {
width: 40px;
flex: 0 0 auto;
height: 80px;
}
JSFiddle
All the behavior is as desired except I want the first item to wrap first. Any ideas? Thanks!
You can use the flex-direction: column-reverse to get your solution.
#media (max-width: 768px) {
.flex-box {
display: flex;
flex-direction: column-reverse;
}
}
.first,
.second,
.third {
display: inline-block;
}
<div class="flex-box">
<div class="first">
<p>First Box</p>
<img src="http://placehold.it/300x300" />
</div>
<div class="second">
<p>Second Box</p>
<img src="http://placehold.it/300x300" />
</div>
<div class="third">
<p>Third Box</p>
<img src="http://placehold.it/300x300" />
</div>
</div>
JSfiddle Demo
To make item1 wrap first, you can use flex-wrap: wrap-reverse on your flex container.
Try this simplified version of you code:
<div class="container">
<div class="item">item1</div>
<div class="item orange">item2</div>
<div class="item blue">item3</div>
</div>
.container {
display: flex;
flex: 0 1 auto;
flex-wrap: wrap-reverse;
}
.item {
background-color: red;
height: 80px;
padding: 0 40px;
}
.orange {
background-color: orange;
}
.blue {
background-color: blue
}
See the MDN reference for browser support.