Flex in Firefox shrinks images automatically, but not in Chrome - html

<h1>Window width:</h1>
<div style="display: flex">
<img src="https://unsplash.it/400/225?image=10" alt="1">
<img src="https://unsplash.it/400/225?image=11" alt="2">
<img src="https://unsplash.it/400/225?image=12" alt="3">
</div>
<h1>Wrapped in 500px wide div:</h1>
<div style="width: 500px; overflow: auto">
<div style="display: flex">
<img src="https://unsplash.it/400/225?image=10" alt="1">
<img src="https://unsplash.it/400/225?image=11" alt="2">
<img src="https://unsplash.it/400/225?image=12" alt="3">
</div>
</div>
This is what the result looks like in Firefox:
This is what the result looks like in Chrome:
As you can see, in Firefox, the images have been nicely shrunk and resized, so that all there images fit in one line without wrapping or cropping. On Chrome, the images remain in their original sizes, which causes cropping in small windows or divs.
Is this expected? Am I doing something wrong? How can I get the same result in both Firefox and Chrome?

These are initial settings in a flex container:
flex-grow: 0
flex-shrink: 1
flex-basis: auto
The shorthand would be:
flex: 0 1 auto
Therefore, even though you haven't specified these rules in your code, they apply to the images.
The images cannot grow, they can shrink (equally and just enough to avoid overflowing the container), and they are initially sized to their natural width (400px).
This is what you're seeing in Firefox. The images are shrinking to fit nicely within the container.
In Firefox, flex rules are overriding the natural dimensions of the image.
In Chrome, however, the reverse is true. The dimensions of the images are prevailing.
The simple cross-browser solution is to wrap the images in another element, so this new wrapper becomes the flex item and takes on the default flex: 0 1 auto, and nothing needs to be overridden.
img {
width: 100%;
}
<h1>Window width:</h1>
<div style="display: flex">
<span><img src="https://unsplash.it/400/225?image=10" alt="1"></span>
<span><img src="https://unsplash.it/400/225?image=11" alt="2"></span>
<span><img src="https://unsplash.it/400/225?image=12" alt="3"></span>
</div>
<h1>Wrapped in 500px wide div:</h1>
<div style="width: 500px; overflow: auto">
<div style="display: flex">
<span><img src="https://unsplash.it/400/225?image=10" alt="1"></span>
<span><img src="https://unsplash.it/400/225?image=11" alt="2"></span>
<span><img src="https://unsplash.it/400/225?image=12" alt="3"></span>
</div>
</div>
In terms of which browser is adhering to spec guidance, it appears that would be Firefox. In a flex container, flex rules should prevail:
7.1. The flex
Shorthand
When a box is a flex item, flex is consulted instead of the main size property to determine the main size of the box.
The flex item’s main size property is either the width or height property.
I say Firefox "appears" to be correct because the spec is saying that flex rules should prevail over the CSS width and height properties.
Of course, the dimensions of the images in this case are not defined in CSS. They are the natural dimensions of the image. So this scenario may be left open for interpretation, and Chrome may not be violating any guidelines.
However, in another scenario, where the height property was a factor, Firefox stuck with flex, while Chrome went with height: Why is Firefox not honoring flexed div's height, but Chrome is?

I this case, add align-items: flex-start to the flex container, and then this rule to the images
img {
min-width: 0;
width: 100%;
}
As align-items defaults to stretch, so they stretches, then min-width defaults to auto which again tell them to be their original size, and finally, give them width: 100% so they fit horizontally and adjust its height to maintain aspect ratio.
Note, after quick browser test, this won't work on IE11 (but works on Edge), so bugs exists little bit everywhere, based on the used code. The second option, where one wraps the image's, works on IE11 though.
Stack snippet
img {
min-width: 0;
width: 100%;
}
<h1>Window width:</h1>
<div style="display: flex; align-items: flex-start;">
<img src="https://unsplash.it/400/225?image=10" alt="1">
<img src="https://unsplash.it/400/225?image=11" alt="2">
<img src="https://unsplash.it/400/225?image=12" alt="3">
</div>
<h1>Wrapped in 500px wide div:</h1>
<div style="width: 500px; overflow: auto">
<div style="display: flex; align-items: flex-start;">
<img src="https://unsplash.it/400/225?image=10" alt="1">
<img src="https://unsplash.it/400/225?image=11" alt="2">
<img src="https://unsplash.it/400/225?image=12" alt="3">
</div>
</div>
Another option is to wrap the images, and set the img to width: 100%
img {
width: 100%;
}
<div style="display: flex;">
<div>
<img src="https://unsplash.it/400/225?image=10" alt="1">
</div>
<div>
<img src="https://unsplash.it/400/225?image=11" alt="2">
</div>
<div>
<img src="https://unsplash.it/400/225?image=12" alt="3">
</div>
</div>
This post, css3-flexbox-maintain-image-aspect-ratio, has links together with a good explanation, about how/why the browsers render differently

Related

Use flexbox to horizontally align images, maintainin aspect ratio, and scale to a mobile device while centered

I am trying to use CSS3 flexbox to align three images horizontally while responsively changing the width of the picture being displayed. It needs to dynamically resize and center on a mobile device. I have found several related questions.
I have come up with two incomplete approaches as follows:
This works to align them horizontally, but the issue is one of the images has a different height and I am not sure how to make it auto-size. I want that image to preserve its ratio but take up the same with. I also don't know what approach to take to make it center all the images on mobile, other than using a media query and having it float:center. In practice I couldn't get that to work.
My other idea was to create an image grid of sorts. I couldn't figure out how to get them to align correctly, even on desktop. I would want the individual ration of the images to be preserved, but have them take up 1/3 of the window width and resize the image as necessary dependent on the window width. Once it reaches 480px width, center the images with each the same width but still preserving its individual proportion.
With object-fit and flex-aligning the elements to the elements to center, you can have them all aligned no matter the image ration, then for mobile it would be only matter of changing the flex-item width to 50%, 100%, or whatever you want with #media query
*{
box-sizing: border-box ;
}
.flex-container {
background: darkred;
flex-direction:row;
display: flex;
align-items: center;
width: 100%;
flex-flow: row wrap;
}
.flex-item {
padding: 20px;
width: 33.33%;
order: 1;
}
.flex-item img{
max-width: 100%;
object-fit: contain;
}
<div class="flex-container">
<div class="flex-item">
<img src="https://alumni.csum.edu/image/content/emails/TellMeSomethingGood.png" alt="">
</div>
<div class="flex-item">
<img src="https://kyuyoungshipperindo.files.wordpress.com/2014/06/something.jpg" alt="">
</div>
<div class="flex-item">
<img src="https://alumni.csum.edu/image/content/emails/TellMeSomethingGood.png" alt="">
</div>
<div class="flex-item">
<img src="https://kyuyoungshipperindo.files.wordpress.com/2014/06/something.jpg" alt="">
</div>
<div class="flex-item">
<img src="https://kyuyoungshipperindo.files.wordpress.com/2014/06/something.jpg" alt="">
</div>
<div class="flex-item">
<img src="http://www.sypte.co.uk/uploadedImages/Media/Press_Releases/see%20something.JPG" alt="">
</div>
<div class="flex-item">
<img src="https://alumni.csum.edu/image/content/emails/TellMeSomethingGood.png" alt="">
</div>
<div class="flex-item">
<img src="http://www.sypte.co.uk/uploadedImages/Media/Press_Releases/see%20something.JPG" alt="">
</div>
</div>

How to create responsive images with fixed height within <img> tag?

I'm working on a website project where in the header section I have a grid of 6 images (2 rows with 3 images in each). It's not a problem to make them responsive (kinda "liquid") with max-width:100% and height:auto, however this website should be linked with some admin tool in the future, so the end user(s) could upload their own images.
Hence, I need to understand how keep these two rows of images responsive but at the same time give them a fixed height (in this case they should be 220px). When I crop the images and make them all equal in height (using Photoshop), everything works fine, but as soon as I use images with different height values, the grid starts to break. Is there any known workaround for this?
Thanks in advance!
Use percents and #media
Example :
#media only screen and (min-width : 320px) {
img {
width:40%;
height:60%; /*Images should be bigger in small devices*/
}
}
#media only screen and (min-width : 480px) {
img {
width:30%;
height:55%;
}
}
Please Note : The percent is calculated from parent. For example if you put an image in a div with width : 400px and height : 300px, it will show the image with 160px width and 180px height on device with min-height of 320px.
max-height is another choice.
Well, let's see if I understood good enough your question (my bad english, not yours).
If yoy want 2 rows, 220px height each with 3 images each filling the width of the row while keeping the same height as the parent, the problem you may have is that the images will distort to adapt to their responsive parent container.
This may not work for you as even if your images are simillar in aspect ratio (height x width) once the window width is small (responsive) they will get distorted too much.
Here is an example: I've use different sizes images some horizontal and some vertical so it can be easier to understand.
Basic html:
<div class="header">
<div class="row">
<div class="img">
<img src="" />
</div>
<div class="img">
<img src="" />
</div>
<div class="img">
<img src="" />
</div>
</div>
<div class="row">
<div class="img">
<img src="" />
</div>
<div class="img">
<img src="" />
</div>
<div class="img">
<img src="" />
</div>
</div>
</div>
Please notice that the row is 240px insteed of 220 just so you can see easily the row (with red background) and I add for the same reason a white border to the image containers.
FIDDLE
The option I would try though is to make the images fit into the container without distortion, they will fit in height OR in width, but of course, they will leave space at the sides if it fit height or on top and bottom if fit in width but at least the images will be always centered in the container:
the green color is the background of the images container:
FIDDLE
There may be better options but without the help of jquery I can't help you more
If your goal is to keep the images (or their container's) height fixed, that will mean that the images will not be stretching or contracting in a fluid way. Given that this concept is contradictory in practice, I will instead show you a 'responsive' solution that comes from making container elements themselves responsive rather than instead of the images.
The case you're referring to (2 rows 3 images) sounds like a great place to implement a cascading images look-and-feel. When the page width shrinks the images will float under each other whereas viceversa when the website width is stretched; this in essence achieves a fluid and responsive functionality without affecting the image heights themselves. The below code should apply the 'building blocks' you'll be needing for in order to achieve this effect... granted there is a lot of custom work you can do here (like using background: cover, instead of img tags as suggested in the comments). Take a look and let me know if this helps you get closer to what you're trying to achieve.
HTML
<div class="wrapper bg-purple center-div">
<div class="img-container left">
<img src="http://placehold.it/200x200"/>
</div>
<div class="img-container left">
<img src="http://placehold.it/200x200"/>
</div>
<div class="img-container left">
<img src="http://placehold.it/200x200"/>
</div>
</div>
<div class="clear-both"></div>
<div class="wrapper bg-cyan center-div">
<div class="img-container left">
<img src="http://placehold.it/200x200"/>
</div>
<div class="img-container left">
<img src="http://placehold.it/200x200"/>
</div>
<div class="img-container left">
<img src="http://placehold.it/200x200"/>
</div>
</div>
CSS
.wrapper {
display: table;
}
.img-container {
height: 50px;
padding: 2px;
}
.center-div {
margin: 0 auto;
}
.left {
float: left;
}
.clear-both {
clear: both;
}
.bg-purple {
background-color: purple;
}
.bg-cyan {
background-color: cyan;
}
#media only screen and (max-width: 450px) {
.left {
clear: both;
}
}

Prevent images from wrapping but use scrolling

In the code below I have 3 images. I want to confine the width of the container to 300px. When the total number of images exceeds this width, I want to let the user scroll horizontally to vew the images. My code however is causing the images to wrap. Here is the fiddle:
http://jsfiddle.net/AndroidDev/Asu7V/10/
<div style="width:300px; overflow-x: scroll">
<div style="">
<div class="x">
<img src="http://25.media.tumblr.com/avatar_dae559818d30_128.png" />
</div>
<div class="x">
<img src="http://scottsdalepethotel.com/wp-content/uploads/et_temp/cat-648150_128x128.jpg" />
<img src="http://playgo.ro/wp-content/themes/play3.0/play.png" style="position:absolute; left:0; top:0" />
</div>
<div class="x">
<img src="http://blog.sureflap.com/wp-content/uploads/2011/11/Maru.jpg" />
</div>
</div>
</div>
Use white-space: nowrap; on the parent element which will force the elements not to wrap up if they fall short of parent width. And I've changed overflow-x: scroll; to overflow-x: auto; so that it doesn't show unnecessary scrollbar if the images are not exceeding the parent element. Just a tweak for a better UI, if not, you can use overflow-x: scroll; as well..
<div style="width:300px; overflow-x: auto; white-space: nowrap;">
Demo
Also, don't use inline styles, consider using class and id instead.

CSS - Margin-top won't work on one selector, but does in compatability mode

I am making a website and have split the site into the usual header, maincontainer and footer divs. The maincontainer contains 3 extra divs and all 3 divs (section 1,2,3) have a margin-top: 5px command associated to them. The first 2 divs (section 1 and 2) work perfectly, but the 3rd div (section 3) doesn't work at all. It just stays glued beneath section 2. However, if I go to IE compatibility mode, the 3rd div will drop down by the 5px specified in the CSS.
Code below.
CSS:
#middlecontainer {
width: 960px;
height: auto;
}
.section1, .section2, .section3{
width: 960px;
margin-top: 5px !important;
}
HTML:
<div id="middlecontainer">
<div class="section1">
<div class="promo1">
<h1>Celebrate the real flavour of Indian cuisine at Mela.</h1>
<p>&nbs</p>
<p>&nbsp</p>
</div>
<div class="promo2">
<img src="images/home-1.jpg" alt="Mela West End, London" />
</div>
</div>
<div class="section2">
<div class="promo3">
<img src="images/mela-limitless.gif" alt="Up to 50% off Mela Limitless" />
</div>
<div class="promo4">
<img src="images/gift-vouchers.gif" alt="Mela's Gift Vouchers" />
</div>
<div class="promo5">
<img src="images/food-1.jpg" alt="Mela Curries" />
</div>
</div>
<div class="section3">
<div class="promo6">
<img src="images/visit-redhill.gif" alt="Visit Mela Redhill in Surrey" />
</div>
<div class="promo7">
<img src="images/recipe-of-the-month.jpg" alt="Mela's Recipe of the Month" />
</div>
<div class="promo8">
<img src="images/cookery-class.gif" alt="Did you buy a cookery class" />
</div>
</div>
</div>
If needed I can provide the CSS code for the .promo divs, but as they are child elements I didn't think that would effect the parent div.
Keith
EDIT:
Here is the code put into jsFiddle, it seems to work fine in here though so I am completely stumped as to why it won't work in my browser. http://jsfiddle.net/8xpxH/4/
Because you float your promo-elements, the parent elements (.sectionX) have height 0. This messes up your margins.
You need to clear the floats. Easiest way to to this is to set overflow:auto and everything is fine. (auto might make (unnecessary) scrollbars appear which can be problematic, so if you are sure, your stuff fits perfectly and there will be no overflow issues take hidden instead.)
.section1, .section2, .section3{
width: 960px;
margin-top: 5px;
overflow: hidden;
}

How to make a div inside a table cell "height: 100%"

I have a layout using table cells. I know, using tables is quite out-dated, but I needed it for this one to make each row the same height without using absolute values for their height
See this fiddle or this draft.
I needed the .wrapper div, to display the .infobox correctly in firefox. Before that, I had the .infobox set as 100% height (with position absolute) which worked fine on chrome, since the parenting td-element had position:relative.
I want the hover-effect to be applied to the whole table cell but I'm desperate to figure out, how. I only want to use relative values (like em or %) for height and width, to make the layout sort of responsive/fluid.
Edit: Ok, using #OneTrickPony's idea, I tried wrapping them around in another "table-row"-div. So how can I now make both "table-cell"-divs the same height, with kind of vertical-align: middlebut without specifying an absolute height for "table-row"-div?
There is another option, but whether or not it is a good fit for your project depends on which browsers you want to support.
http://caniuse.com/#search=flexbox
I've simplified your markup a bit and completely removed the table.
<div id="pictures">
<article class="entry picture">
<div class="entry picture">
<img class="picture" src="./images/150x150.jpg" width="150" height="150"></img>
</div>
<div class="entry picture infobox">
<a href="#" class="entry">
<h3 class="entry picture headline">contents_0 alpha headline</h3>
<div class="view picture">
<span class="comments_amount">5</span>
<span class="articlenk info">Bild zeigen</span>
</div>
</a>
</div>
</article>
<article class="entry picture"><div class="picture wrapper">
<div class="entry picture">
<img class="picture" src="./images/150x71.jpg" width="150" height="71"></img>
</div>
<div class="entry picture infobox">
<a href="#" class="entry">
<h3 class="entry picture headline">contents_0 beta headline</h3>
<div class="view picture">
<span class="comments_amount">5</span>
<span class="pictures info">Bild zeigen</span>
</div>
</a>
</div></div>
</article>
</table>
The CSS for this is very simple, but I've left off the prefixes:
div#pictures {
display: flex;
flex-flow: row wrap;
}
article {
flex: 1 1 50%;
box-sizing: border-box; /* optional */
position: relative;
}
div.infobox {
position: absolute;
bottom: 0;
}
http://jsfiddle.net/NDMTH/1/
Figure/figcaption would probably be a more appropriate choice here than article.
Ok, so I figured that there actually is no way to set the height of two (or more) divs to equal values without defining absolute values. As a workaround, I wrote this little script, which does that job:
$(window).load(function() { /* Important because the script has to "wait" until the content (images) has been loaded */
$('.picture-row').each(function() {
var rowHeight = 0;
$(this).children('.picture.item').each(function() {
if ($(this).outerHeight() > rowHeight) {
rowHeight = $(this).outerHeight();
}
});
$(this).children('.picture.item').each(function() {
$(this).height(rowHeight + 'px');
});
});
});