1

I cannot figure this out. I would like 3 images to sit side by side inside a 930px wide div.

so, when you enter into responsive design mode, or drag the screen browser width wise to make it smaller all the 3 images stay side by side inside the div without wrapping to the next line.

But automatically start to re-size to fit the re-sized div.

The 3 images only start to resize correctly inside the div only when the 3rd image has wrapped under the second image. So it looks like this below.

[]
[] 
[]

Once all the images are vertically aligned the images then start to shrink down correctly. But this image wrapping under the next image is no good for me, as when viewing the website on a mobile phone, or when re-sizing the screen the images are still super large.

Must be a way to stop these images from wrapping underneath each other, and just stay inline but automatically re-size themselves as the div/page width shrinks down?

I've tried white-space: nowrap; display: inline; inline-block; even display: table-cell; nothing seems to do what I need it to do. However, if I use only one image instead of 2, or 3 then it works perfectly fine.

You're probably thinking why not just put all 3 images inside 1 image in photoshop? Well each img is an href link, so that's not possible. Even floating the images all to the left still doesn't help.

Here's my CSS/HTML

img {

max-width: 100%;
height: auto;

}

then

<div style="width: 930px; max-width: 100%; border: 1px solid blue;">
<img src="camera.png"> <img src="lights.png"> <img src="action.png">
</div>

Can someone tell me where I may be going wrong please? How can I stop images wrapping underneath other images when the parent container shrinks down.

I've had to resort to using multiple @media queries of different pre-fixed image sizes per break-point. But there's got to be a much much easier way. Something so simple that I'm missing.

GraphiX
  • 555
  • 1
  • 6
  • 12
  • you can use percentage based widths or flexbox for this – Lewis Briffa May 13 '18 at 21:27
  • Hello thanks for the reply. But that percentage method doesn't work either. I've tried percentages on the div even got it right flush upto the 3rd image. The images still wrap to the next line regardless. Yes it may work using flexbox, but I'd love to know if this can also be done without flex properties for browsers that don't support it. – GraphiX May 14 '18 at 10:48

5 Answers5

6

I figure I might share a flexbox solution as well. I've included the code below so it should be relatively self explanatory. Feel free to leave a comment below if you think I should clarify anything.

.container{
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: flex-start;
}

img {
flex: 1;
max-width: 100%;
height: auto;
max-height: 310px;
}
<div class="container" style="width: 930px; max-width: 100%; border: 1px solid blue;">
<img src="https://cdn.vox-cdn.com/uploads/chorus_image/image/44336734/fujifilmx100t-1.0.0.jpg"> 
<img src="https://d3k7s9wfq6lao0.cloudfront.net/latest/37504/main/7.jpg"> 
<img src="https://upload.wikimedia.org/wikipedia/commons/3/33/Clapperboard%2C_O2_film%2C_September_2008.jpg">
</div>
Michael Sorensen
  • 1,850
  • 12
  • 20
  • 1
    You may want to add `align-items: flex-start;` or some variant of that in `.container` to prevent the images from stretching vertically to fit the container. – subhaze May 13 '18 at 22:17
  • Great suggestion. I went ahead and updated the answer accordingly :) – Michael Sorensen May 13 '18 at 22:25
  • Thanks @MichaelSorensen and subhaze is there any way you can maybe expand on this just for learning purposes. I'm also looking to be-able to do this for older browsers as well that don't support the new flex layout. Can this be done without flex somehow? – GraphiX May 14 '18 at 10:53
  • If you're new to flex I highly encourage you to check out CSS-tricks' article on the subject here: https://css-tricks.com/snippets/css/a-guide-to-flexbox/. If you are concerned with browser support, the good news is that Flex is pretty widely supported nowadays checkout the caniuse on it here: https://caniuse.com/#search=flex . Finally, the other solutions in this thread are also valid for sets of 3 images. However, this solution could support any number of images you wanted to line up in a row. – Michael Sorensen May 14 '18 at 16:34
  • @MichaelSorensen Thank you for your help. I looked at your profile and your bio page. I'd like to contact you. I've been fiddling with flex now and it's coming up with weird issues in Chrome. I would like you help/views why. Don't know how to post code here. – GraphiX May 26 '18 at 14:55
  • @GraphiX sorry about that. I posted my email on my portfolio page which you should be able to find on SO profile. Feel free to email me there. Doesn't seem right to put contact info here. – Michael Sorensen Jun 04 '18 at 00:18
2

you can use inline-block for this. you will need to alter the width with media queries as your screen gets smaller

img {
display:inline-block;
width: 33%;
height: auto;
}

you should also wrap the images in a div.container and give this div a width:100%

Claire
  • 3,146
  • 6
  • 22
  • 37
  • You may want to use `width: calc(100% / 3);` as using 33% can result in quite a bit of a difference when wanting things to line up perfectly. For example, layouts using bootstrap generally go up to 1200px, and this would be 12px short. Of course, that's 1% of 1200, but it does add up. – Thomas May 13 '18 at 22:02
  • @Thomas this is to show the asker that percentage based width and inline block is what he/she wants here. You will find, in fact, that if you use `width: calc(100% / 3);` you will end up needing to add negative margins to keep everything in line as the screen shrinks – Claire May 13 '18 at 22:40
  • @Tom and Thomas thanks for taking the time to reply. I've seen so many questions being answering when it comes to images. Everyone is always using width: 33% even when it's less/more than 3 images. Can someone explain what this value of width: 33%; or 33.333% does, and why is this certain value always used? – GraphiX May 14 '18 at 10:59
  • @GraphiX the value 33.33% in this case means the image will take up 33.33% of its parent container. I would not say this value is "always used", but it is used a lot for 3 elements in a row, because 33.33 x 3 = 99.99 or 100% of the parent container. Ideally you would use `width:33.33%` as a base, then use media queries to change the width to 50% or 100% as the screen shrinks to your breakpoints – Claire May 14 '18 at 23:27
  • @GraphiX if you put your code into a fiddle and reproduce your problem I can help you further – Claire May 14 '18 at 23:28
1

Image width set to 100% occupy all the horizontal space of the container, since you want to fit three images inline to each other, divide the 100% by 3 so that when the container is resized the three images will occupy one third of the available space. The margin-left: -2px is to make sure that the image border don't touch the edge, otherwise it will wrap to new line. Try this sample:

CSS:

img {
  display: inline-block;
  width: 33%;
  height: auto;
  margin-left: -2px;
  box-sizing: border-box;
}

HTML element:

<div style="width: 930px; max-width: 100%; border: 1px solid blue;">
  <img src="camera.png"> 
  <img src="lights.png"> 
  <img src="action.png">
</div>
Cocest
  • 147
  • 1
  • 2
  • 15
0

My answers' more or less a follow up to Tom's which I'm writing on here so I don't overflow the comments section.

The problem with max-width: 100% is that the relative sizing doesn't start to kick in until each image outgrows its parent, in this case, the div. Since all images have a default absolute size based on their image src they force themselves onto a new line before resizing and so only then will max-width start doing what you want it to. As per Tom's response, the percentage sizing of 33% forces the images to have a relative size which causes them to shrink immediately.

Naturally 'img' tags are given the display of inline which means you could opt to just use the following code:

img {
  width: 33.3%;
}

Now here's the biggest gotcha I had when dealing with inline images.

A display of inline and inline-block is respective of the whitespace that exists within your HTML markup.

Therefore the small presence of whitespace below whilst not evident is enough to cause images to still move over to a new line.

img {
  width: 33.3%;
}
<div style="width: 930px; max-width: 100%; border: 1px solid blue;">
  <img src="https://picsum.photos/250/250/?random1">
  <img src="https://picsum.photos/250/250/?random2">
  <img src="https://picsum.photos/250/250/?random3"> 
</div>

But once this whitespace is removed the images all fit perfectly across the screen whilst resizing.

img {
  width: 33.3%;
}
<div style="width: 930px; max-width: 100%; border: 1px solid blue;"><img src="https://picsum.photos/250/250/?random1"><img src="https://picsum.photos/250/250/?random2"><img src="https://picsum.photos/250/250/?random3"></div>

Now compressing the HTML markup above makes it rather unwieldy and so as an alternative, you could opt to use the floating method. By setting a float of left for each image you'll force each 'img' tag to sit flush, regardless of the extra spacing between them. Just be sure to give the parent div a float of left as well or an overflow of auto to stop it from collapsing.

img {
  width: 33.3%;
  float: left;
}
Lewis Briffa
  • 557
  • 3
  • 6
  • 15
  • that is very detailed and thank you for taking the time to explain what this magical 33.3% is that I've seen everywhere. The white space you shown above is perfect, only the images would have say 40px padding, or margin to space them out. This then causes problem with white space as the div crushes down. Even when the images are floated left. display: flex seems to be the best way of doing this. Was just hoping I could replicate the flex method exactly using some other methods. – GraphiX May 14 '18 at 18:01
  • in that case, try combining it with "box-sizing: border-box" as shown in Cocest's answer, this will cause the widths of the images to take up 33.3% of only the leftover space after the padding has been applied ;) – Lewis Briffa May 14 '18 at 18:24
0

After many days testing various ways out here's the perfect way to do this without flex. Make sure each image is wrapped in its own div that's important.

<style>
* {
    box-sizing: border-box;
}

img {

width: 100%;
max-width: 100%;
height: auto;

}

.column {
    float: left;
    width: 33.33%;
    padding: 5px;
}

/* Clearfix (clear floats) */
.row::after {
    content: "";
    clear: both;
    display: table;
}

</style>

Now, here's where I've changed it up a little bit for more flexibility. Since each image is now in its own div we can then make the image width: 100%; or max-width: 100%; then add the width: 33.33%; part that used to be under img {} to each of the new 3 div columns instead.

<div class="row">
  <div class="column"> /* 33.33% width */ 
    <img src="flash-tooltip.png">
  </div>

  <div class="column"> /* 33.33% width */ 
    <img src="html-tooltip.png">
  </div>

  <div class="column"> /* 33.33% width */ 
    <img src="portables-tooltip.png">
  </div>

</div>

Lot's of people provided great advice.

The easiest way is using flex. But, something people don't tell you when using flexbox. You should still wrap each of the images inside their own div container. Otherwise, you will get some weird things happening when you encase them in hyperlink anchors, that is if all three images are just placed inside the first flex container div. And without their own div container images won't keep any kind aspect ratio when they shrink/enlarge. They just squash and skew together.

And finally very important! Always make sure any images inside a flex container is set up the same way. Either width: 100%; or max-width: 100%; otherwise, the images will not shrink up/down at all in Google Chrome.

I've included this same method as above, only this time in a flexbox version.

GraphiX
  • 555
  • 1
  • 6
  • 12