How do I responsively handle a div wrapping an image and text? - html

I have a div wrapping an image on the left and a div containing text on the right with some margin between the two. When the window size narrows I want the text to shrink between its max-width and min-width, the image to shrink at the same time so they stay next to each other, and only after the text shrinks to have it jump below the image.
But what happens is - as soon as the text hits the image it jumps below instead of shrinking to its min-width and trying to stay next to the image.
My code is something like this:
<div class="container">
<img class="headshot" src="..." />
<div class="bio-text">
<h3>BIO</h3>
<p>Lorem ipsum...</p>
</div>
</div>
.container {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
align-items: center;
width: 80%;
margin: auto;
}
.headshot {
max-width: 100%;
height: auto;
margin: 40px;
}
.bio-text {
max-width: 450px;
min-width: 250px;
}
Any insight would be greatly appreciated!

One problem you have is that you are mixing a flexbox with min and max widths, which conflict with the layout of .container. One option is to assign .bio-text a flex of 250px, and let it grow to take the rest of the space. If the container cannot fit both, it will wrap the text below the image.
I have a codepen with that idea: https://codepen.io/sirech/pen/BYJJdz
Would this fit your needs?

Related

Container does not shrink when inner text wraps

I am trying to have two elements horizontally aligned where the one on the left has text that may wrap then sizing the screen, and the one on the right allows for no wrapping. When the content wraps, the first element maintains the width of content + (wrapped word - pixels causing wrapping), instead of shrinking to fit the content.
I created an example on Fiddle where you can see the grey background of the first element having no content for a couple of pixels, instead of resizing to only include the text.
.container {
display: flex;
width: 760px;
}
.item {
background-color: grey;
width: fit-content;
block-size: fit-content;
}
.item2 {
background-color: green;
white-space: nowrap;
align-self: flex-start;
}
<div class="container">
<div class="item"><span> This Text to auto-adjust to only fit the content when wrapping</span></div>
<div class="item2">This should be right next to last word on first line on the left</div>
</div>
JSFiddle Demo
Is there a way of achieving an auto-size to only fit-content on resizing of the screen so the 2 element stays as close to the text of the first one as possible?
Elements inside a flexbox has flex-grow and flex-shrink set by default, which allows them to bypass the basic width and height properties.
To solve this problem, just disable flex-grow and flex-shrink:
.item {
background-color: grey;
width: fit-content;
block-size: fit-content;
flex-grow: 0;
flex-shrink: 0;
}

inline div not resizing for image but works for other div

I need to fit an image into a fixed width/height div (say 80%/80%), but I also need the image to be wrapped in another div so that I can place an absolutely positioned element on top of the image (using that wrapper div as the anchor). I have accomplished the first point by just setting the max-height and max-width of the image to 100% so that it will always take up 100% of one dimension and won't exceed the other while maintaining aspect ratio, but I am unable to figure out a way to wrap the image in a div such that there is no extra space in the wrapper. I was under the impression that using display: inline or display: inline-block on the .wrapper div should shrink to the size of it's content (the image in my case), but that does not appear to be the case. When I replace the image with a test div with a defined width and height, the wrapper works as expected, i.e. there is no excess yellow background from the wrapper, it is exactly the same size as the div. How can I achieve the same behavior with the image? I've tried using all sorts of combinations of different display modes (flexbox/inline/block) and various min/max heights/widths but none have worked.
I've put an example of what my HTML looks like now, and what I would like it to look like if I could get this to work below. The .window element is a stand in for whatever the parent of the container is. The .container element is where I'd like to fit the image. In the example with the image, the inline wrapper is still larger than the image (which can be seen by the yellow overflowing on the sides). In the example after that with just a fixed size div (colored green), the wrapped properly shrinks to exactly the size of the div. Can this be accomplished with just css without knowing anything about the size of the image itself?
.window {
height: 400px;
width: 600px;
display: flex;
justify-content: center;
align-items: center;
background: red;
}
.container {
height: 80%;
width: 80%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: blue;
}
.wrapper {
display: inline;
max-height: 100%;
max-width: 100%;
background: yellow;
}
img {
max-height: 100%;
max-width: 100%;
}
.test {
width: 64px;
height: 128px;
background: green;
}
<div class='window'>
<div class='container'>
<div class='wrapper'>
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/ReceiptSwiss.jpg/1920px-ReceiptSwiss.jpg" />
</div>
</div>
</div>
<div class='window'>
<div class='container'>
<div class='wrapper'>
<div class='test' />
</div>
</div>

Resizing images dynamically

I have a div element on top of which I am overlaying a vertical sidebar that consists of vertically stacked svg icons. I need the sidebar to be always the same height as the parent and either shrink/grow the icons whenever the window size is changed, to fill the empty space.
I've managed to atleast keep them the same size when making the window bigger, but the sidebar refuses to shrink down from a certain point.
I think that the images won't shrink because their parent div (sidebar) doesn't shrink beyond the sum of 7 icons' heights combined. Nor does it really scale the images bigger, flexbox actually just adds more empty space as the height is increased, which at this point is okay. Actually, it would be ideal that they are not initially bigger than x, and scaling up would increase the space and scaling down would first shrink the empty space as much as possible and then shrink down the icons.
I've tried 2 Google searches pages worth of solutions, along with min-width, object-fill and others. and I can't seem to solve it - the sidebar indefinitely overflows from the parent if parent is compressed so that it's height will be less than the heights of all 7 icons combined.
.sidebar {
position: absolute;
right: 12px;
top: 0;
bottom: 0;
display: inline-flex;
flex-direction: column;
align-items: stretch;
}
.sidebar-item {
flex: 1 1 auto;
background-color: black;
position: relative;
z-index: 1;
}
.sidebar-item img {
width: 100%;
height: auto;
}
<div id="map">
<div id="sidebar" class="sidebar">
<div class="sidebar-item">
<img src="https://via.placeholder.com/150?text=icon1" alt="icon1">
</div>
<div class="sidebar-item">
<img src="https://via.placeholder.com/150?text=icon2" alt="icon2">
</div>
<div class="sidebar-item">
<img src="https://via.placeholder.com/150?text=icon3" alt="icon7">
</div>
</div>
</div>
Solved by adding these properties to sidebar-item:
display: flex;
min-width: 0;
min-height: 0;

How to stop 3 images side by side inside a div from wrapping to the next line?

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.
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>
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%
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>
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;
}
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.

How to keep the height of a containing div element?

I'm trying to draw three rectangles in a page. The top rectangle has to be much smaller than the other two. You can see the top rectangle has a flex-grow: 1 (compared with 5 for other rectangles).
However, once I put three images inside the top rectangle, it gets taller, so it becomes bigger than other rectangles.
What can I do to prevent the top rectangle from getting taller? I just want the pictures' size to be adjusted to fit in the original container size.
I'll be glad for a solution using flexbox features (because I'm trying to learn it).
html,
body {
width: 100%;
height: 100%;
flex-flow: column wrap;
display: flex;
}
div {
flex-grow: 5;
display: flex;
border: solid;
margin: 1em;
}
#top {
flex-grow: 1
}
<div id="top">
<img src="http://i164.photobucket.com/albums/u8/hemi1hemi/COLOR/COL9-6.jpg">
<img src="http://i164.photobucket.com/albums/u8/hemi1hemi/COLOR/COL9-6.jpg">
<img src="http://i164.photobucket.com/albums/u8/hemi1hemi/COLOR/COL9-6.jpg">
</div>
<div id="middle"></div>
<div id="bottom"></div>
http://codepen.io/CrazySynthax/pen/ZBPXry
Your max-height of 30% is bigger than the rectangles initial size. Try setting fixed height for it or lower the max-height to match the initial size. On the code pen I used max-height: 20%; and got the result you are looking for, however to be consistent on all displays I would just set the height to a fixed percentage. ex: height: 20%. Also there is no point of using max-height if you don't want your div's height to change.