Recently while working on a responsive web design at Paravel, we came across an unexpected maxim regarding image aspect ratios and their visual hierarchy.
Image Height == Image Importance
Our design employed a ~3:1 hero image with three ~4:3 thumbs below it. At full width it posessed the proper hierarchy: Biggest == Most Important. However, when resized and folded into a single column, the 3:1 image appears to be about ½ the height of the 4:3 images below it.
Narrow your browser width to see the visual hierarchy breakdown:
Pretty unacceptable to lose hierarchy on such a major feature of the site – especially when e-commerce and products are involved. We had to come up with a solution.
Uncle Dave’s Squeeze n’ Crop Method
We wanted stop the image from scaling once it reached a certain height. Here’s what we did:
<div class="banner-item">
<!-- Using a 2:1 image because the cat picture is better :) -->
<img src="http://placekitten.com/1200/600" />
</div>
First wrap the image in a DIV, this will act as an image-mask of sorts. Then apply some min-height + max-heightheight + overflow: hidden magic to lock the image and hide the overflow:
.banner-item {
overflow: hidden;
min-height: 300px; /* 300px is arbitrary. */
}
.banner-item img {
width: 100%;
}
/* 600px is about the width "locked in" at */
@media screen and (max-width: 700px) {
.banner-item img {
width: auto;
max-width: none;
height: 300px;
}
}
The image hugs the left of the wrapper. Auto-cropping is never perfect, but if you want to adjust the focal point of the image, you can do that with position:relative:
/* OPTIONAL: Use to shift left as necessary */
@media screen and (max-width: 480px) {
.banner-item img {
position: relative;
left: -40%
}
}
Results
There’s a lot of playing around with what “feels good”. Adjust the breakpoint of your media query to where it feels like your image locks-in to the desired height. There might be some “Math” [/quotehands] based off of a conch shell that can help you with this, but I just go with my gut.
Good luck and let us know if you use this technique and/or can make it better.
This looks awesome, Dave! I, too, noticed this on a recent site design. This is a great solution to the problem.
This is the best subheading to a blog post ever. I’m sure of it.
“min-height: 300px; max-height: 300px;” is equal “height: 300px;”.
I’ll see what I can refactor, thanks Aleks. Part of the reason i was initially using that min/max height combo was to override the defaults as well as override the initial
max-width: 100%.You win the internet! Code samples have been updated. Thanks for making this better, Aleks.
You’re welcome :)
I’m viewing this article on my iPhone. In the “after” example, I can’t see the third image at all unless I turn it landscape… And even then, I can only see a sliver of the image. This isn’t good, especially if it’s an ecommerce site. :-/
Good eye! Forgot my
tag. The iframe embedded demo is a little wonky on the phone still, but click through to the examples and it should be alright.I’m glad to have found this. I’m attempting to using it backwards – I have a small img at one aspect ratio that needs to scale up to bigger aspect ration and play a video… I’ll post an example if it works out. Fingers crossed!
PS Unrelated – Thanks for have great articles that are well styled for a good reading experience (not afraid of font-size > 14px)
o<-<]:
Nice solution Dave.
Though i have some comments on this.
1. The solution provided crops the image on desktop not on mobile. This means viewing site on mobile has more importance than viewing on desktop?!
Depending on the project your working on should decide if you use it or not.
2. Problem with user generated content is that you have absolutely no control/idea what they will upload. So for all we know the focus of the image is on the bottom and this solution will fail.
Still a good piece of code! I would say use it wisely ;)
It might just be me, but I’m only seeing broken images.
Ah, darn. It looks like placekitten.com is down. If it doesn’t come back soon, I’ll switch it over to something else. Sorry about that.
Now, if I could only see what you’re talking about… placekitten is down =/
Hey Dave,
This is a pretty smart way of handling the problem at hand. I’ve been trying to apply this technique to a jQuery slideshow instead of a single image though. Basically have five images inside a single ‘slides’ div which cycles through the images. I tried keeping the markup semantic as I could and applying this technique to the ‘slides’ div, with no luck. I also played around with adding an extra ‘slides-img’ div around each of the five images and still couldn’t get that to work. Any thoughts on the subject? I’ve been trying everything I can think of over the last few days. Any comments or tips would be greatly appreciated! Thanks,
-TM
Could depend on what image slider you’re using. Sometimes those inline a height and width onto the
div.slide. Use web inspector for that. Otherwise, not sure why it wouldn’t work. It’s just CSS and should work pretty standard.