Display image original size, if possible, else shrink - css

There are lots of questions on this general subject, but none that do what I need.
I need to present multiple images, each in a div of its own, but I have no prior knowledge of whether they're portrait, landscape, or low resolution. What I want to do is show them original size (and centered) if they will fit (i.e. I don't want to stretch a low-resolution image), but if they're larger than the div then shrink them appropriately according to their aspect ratio.
This sounds simple but I gave up with the img element, and solutions suggesting width:100%;height:auto; were neglecting the fact that this presumes a landscape image.
I started using background properties and had much more success. If I could make this work then it would have the added benefit that it worked with IE11 too. For instance:
background-image: url("http://example.jpg");
background-position:center center;
background-size: auto;
background-repeat: no-repeat;
works fine if the image is smaller than the div, but crops the image if the original size is too large.
Is there a way to scale the size appropriately in this case (as with background-size:contain), but display original size when possible?

I think you can achieve what you want with a combination of the two properties: max-width: 100% and max-height: 100%:
.container {
display: flex;
}
.item {
margin: 1rem;
width: 200px;
height: 200px;
border: 1px solid;
display: flex;
}
img {
max-width: 100%;
max-height: 100%;
margin: auto;
}
<div class="container">
<div class="item">
<img src="https://via.placeholder.com/150x150" />
</div>
<div class="item">
<img src="https://via.placeholder.com/300x200" />
</div>
<div class="item">
<img src="https://via.placeholder.com/200x300" />
</div>
</div>
1st item: image is smaller, keeps its original size.
2nd item: image is landscape, shrinked to fit.
3rd item: image is portrait, shrinked to fit.
Is this what you needed?

Related

CSS: keep image aspect ratio as viewport width decreases

At this page, there are 3 "doorway" graphics:
<div class="textwidget">
<div class="one-third first">
<div id="doorway1" class="doorway">
<h3>The Best Core Exercise Ever</h3>
<div class="doorway-action">
<img src="http://vmpersonal.com/wp-content/themes/vmpersonal/images/doorway-action.png" alt="Watch Video Now" title="Watch Video Now" /> Watch Video Now
</div>
</div>
</div>
<div class="one-third">
<div id="doorway2" class="doorway">
<h3>Core Strength Level 1 Program</h3>
<div class="doorway-action">
<img src="http://vmpersonal.com/wp-content/themes/vmpersonal/images/doorway-action.png" alt="Watch Video Now" title="Watch Video Now" /> Watch Video Now
</div>
</div>
</div>
<div class="one-third">
<div id="doorway3" class="doorway">
<h3>Cardio Program</h3>
<div class="doorway-action">
<img src="http://vmpersonal.com/wp-content/themes/vmpersonal/images/doorway-action.png" alt="Watch Video Now" title="Watch Video Now" /> Watch Video Now
</div>
</div>
</div>
</div>
I'd like to make the graphics and the divs that contain them responsive.
They are contained in div.one-third containers.
The images are 409px x 292px, meaning the height is 71.39364303% of the width.
I thought if I used CSS:
#doorway1 {background-image: url('images/doorway1.png'); height: 71.39364303%;}
#doorway2 {background-image: url('images/doorway2.png'); height: 71.39364303%;}
#doorway3 {background-image: url('images/doorway3.png'); height: 71.39364303%;}
they would scale down with the div.one-third as the viewport decreased in width, but they don't, the images are cut off.
How can I keep the images aspect ration consistent as the viewport width decreases?
Help appreciated.
Update: AJ Funk has helped me make the background images scale down, but how do I make the divs that contain them scale down proportionally too?
You should combine the background-size: contain with a padding-bottom CSS trick to maintain aspect ratio. This could work as follows. Note that the main ideas are the background-size: contain and padding-bottom: 71.39364303% on .doorway elements, in combination with height: 0. The rest is minimal styling to illustrate the point.
It should be straightforward to apply this on your linked test page.
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.textwidget {
width: 100%:
font-size: 0; /* to prevent space between inline-block doorways */
}
.one-third {
display: inline-block;
vertical-align: top;
box-sizing: border-box;
width: 30%;
padding: 20px;
}
.doorway {
box-sizing: border-box;
width: 100%;
height: 0;
padding-bottom: 71.39364303%;
background-image: url('https://placehold.it/409x292');
background-size: contain;
border: 1px solid #000;
font-size: 1rem; /* reset font-size */
}
<div class="textwidget">
<div class="one-third">
<div id="doorway1" class="doorway">
<h3>The Best Core Exercise Ever</h3>
<div class="doorway-action">
Watch Video Now
</div>
</div>
</div>
<div class="one-third">
<div id="doorway2" class="doorway">
<h3>Core Strength Level 1 Program</h3>
<div class="doorway-action">
Watch Video Now
</div>
</div>
</div>
<div class="one-third">
<div id="doorway3" class="doorway">
<h3>Cardio Program</h3>
<div class="doorway-action">
Watch Video Now
</div>
</div>
</div>
</div>
You need to set the background-size to contain
#doorway1,
#doorway2,
#doorway3 {
background-size: contain;
}
I believe that you can use img {max-width:100%} to make the images scale down responsively. Then as for scaling down the divs, I cannot see why it would be necessary. div tags don't serve a purpose on their own, and are only important because of the content you put inside of it. The links will remain the size of the image, no matter what size the image is. This is because the link is represented by the image.
But, if you displayed the content you need to manipulate, h3, etc. as block elements, which should allow you to set the dimensions using
.doorway h3{ //h3 is a child element of the class doorway
display: block;//Or "inline-block", if you are using inline currently
//Then you should be able to set the max-width or max-height whatever the case may be
max-height: xx%;
}
The reason that using the percentage value you wer using is because saying height: 71% does not mean height: 71% of width It actually means height: 71% of the viewport or the size of the device screen / window (depending on the way you set the viewport) so you could calculate what the amount of viewport you want the content to take up is, 3 images so roughly 33.33% for all 3 to take up all of the screen or you can use different units like pixels, which works less kindly with RWD (Responsive Web Design) but it can work if you use 'max' and 'min' for the width, as well as make some other accommodations, such as using percentages everywhere where it can be used.
I truly hope this helped or at least points you toward the answers you are looking for.
You have two choices :
This working for responsive (You keep the full image, no crop) :
img {
max-width: 100%;
height: auto;
}
This working for backgroud image (The image will crop) :
div { background-size: contain; }
Else you can have a look to some jquery plugins that auto resize an html element depending the window height/width.

Fluid image that is not width:100%

I have a scenario in which images of varying dimensions appear in a column that's 50% page width.
On large screens where the column width exceeds an image's native width, the image should render to its native width while still being fluid.
Image dimensions vary (i.e. landscape vs. portrait orientation), so no single width or height can be applied to the img element. I can constrain parent element to a max-width that matches the largest image width that will display, but images of lesser widths expand too wide once made fluid.
The basic structure is:
<div class="column">
<figure>
<img>
</figure>
</div>
With this CSS:
.column {width:50%;}
.column figure {
display:block;
margin:0 auto;
width:100%;
max-width:800px; /* the largest image width */
text-align: center; /* to center images of lesser width */
}
.column img {?}
I can add a data attribute to the img element indicating orientation, using this to apply max-width, but this requires more work for site editors, which I need to avoid. Hence, I seek a CSS-only solution...but I'm stuck.
Any ideas?
How about using max-width again, allowing the image to fully expand to the width of its container, but not larger? Something like:
.column img {
max-width: 100%;
}
This will allow the image to be responsive as needed - scaling with the size of its parent, but never exceeding its native width. Here's a demo with some random images - note how the natively smaller and larger image stop at different widths when given enough space:
.column {
width: 50%;
}
.column figure {
display: block;
margin: 0 auto;
width: 100%;
max-width: 800px;
/* the largest image width */
text-align: center;
/* to center images of lesser width */
}
.column img {
max-width: 100%;
}
<div class="column">
<figure>
<img src="http://www.ltsgrill.com/wp-content/uploads/2014/09/red_lobster.jpg" />
</figure>
</div>
<div class="column">
<figure>
<img src="http://www.mjseafood.com/_assets/400x300/Crayfish.jpeg" />
</figure>
</div>

How to reposition div on decrease in screen size with css?

I have been trying to build a website having a 3 column layout. All of the body is given a margin:0 auto to keep it at the centre, and has a minimum width of 1218px.
Now, what I want to do is reposition the right column in such a way the it goes below the left column without affecting the centre column. A live example would be twitter home page, where at the left I can see my profile and trends, the centre column features the tweets and the right column shows suggestions on a 1366x768 screen, now if I change the screen size to 1024x768, the column of suggestions at right goes down below the left column but the central timeline is unaffected.
The definition would be:
<div class="containter" style="margin:0px auto;">
<div class="left-col" style="width:290px; float:left;">Left Stuff goes here </div>
<div class="center-col" style="width:590px; float:right;"> Center body </div>
<div class="right-col" style="width:290px; float:right;">right Stuff goes here </div>
</div>
Now note that the central column has a right float, copied from twitter.
I can't use media queries for that since the website is going to deal with a lot of old browsers and also I would like to avoid JavaScript if possible.
Any help?
You can't do that with "min-width" of the main container. You must use "max-width" since you want to make sure something happens when the screen width gets more narrow. And the main column (in the center) has to be left-floated, not right. Here's a possible solution. However the whole questions seems weird to me since you want to make a responsive layout in an old browser that doesn't support responsive CSS.
<style>
.container {
max-width: 1218px;
}
.leftColumn {
float: left;
width: 300px;
height: 500px;
background-color: brown;
}
.mainColumn {
float: left;
width: 700px;
height: 500px;
background-color: darkgreen;
}
.suggestions {
float: left;
width: 218px;
height: 500px;
background-color: darkorange;
}
.cleaner {
clear: both;
}
</style>
<div class="container">
<div class="leftColumn">
LEFT
</div>
<div class="mainColumn">
MAIN
</div>
<div class="suggestions">
SUGGESTIONS
</div>
<div class="cleaner"></div>
</div>

Resize Row Heights Depending on Background Image Details in Zurb's Foundation

This is a hard one to explain, so I'll do my best.
As it stands now, I have a wrapper div that has the iceberg image as it's background. It's styled in that the background image sizes to fit the user's screen. Within that wrapper div, I have two .rows, each containing a column.
Now the tricky part: I want one row to just span the top of the water, with the other spanning the bottom of the water. Here's a rough concept.
Right now these rows are given a min-height to match that horizon, however when the user resizes their screen or has a different browser width than my dev environment, of course it doesn't work the same.
Now, how can I go about getting these rows to match heights with the background image? I had considered slicing the image into two, but I imagine there's got to be a much more resourceful way. Here's the CodePen I'm working with: http://codepen.io/jwindeknecht/pen/qOqwPp
If you can offer any advice or if I can clear anything up, let me know! Thanks.
<div class="hero">
<div class="row over">
<div class="large-6 large-offset-6 columns">
<div class="inside">
<h1>Hello World</h1>
</div>
</div>
</div>
<div class="row under">
<div class="large-6 large-offset-6 columns">
<div class="inside">
<h1>Hello World</h1>
</div>
</div>
</div>
</div>
.hero {
background: url(http://i.imgur.com/fdRuNIF.jpg) center top no-repeat;
background-size: cover;
min-width: 100%;
div {
display: table;
.inside {
display: table-cell;
vertical-align: middle;
}
}
}
.over div { min-height: 275px; }
.under div { min-height: 275px; }
Okay! I figured this out. I know the dimensions of the image, so I had the min-height of the row set to a certain percentage of the the width of the image.
e.g. The image is 1500px wide. The row that covers just the horizon is 300px high. Therefor the min-height of the row is set to 20vw.
So regardless of the background image width, the height of the row matches up due to using the vw. Here's a pen example: http://codepen.io/jwindeknecht/pen/RWyBGW
And the new code is simple:
.over div { min-height: 275px; }
to
.over div { min-height: 20vh; }

How to stop an image shrinking on responsive site whilst also keeping it centred

This is my first post, so please be gentle. I've searched thoroughly for an answer but had no luck - I'm sure it must be something simple but I'm running out of ideas...anyway:
I'm making a responsive site but there's an image that I want to keep at a fixed size. It took me ages to work out how to do this (by removing "max-width: 100%"), however this has had the bizarre effect of changing its alignment so it is no longer centred on the page.
How can I have both? Centred and a fixed size?
Any help much appreciated.
Oh and this is what my image css is looking like at the moment:
img {
height: auto;
min-width: 100%;
display: inline-block;
margin-left: auto;
margin-right: auto;
}
Thanks for all your help so far - although this is still far from resolved I'm afraid. Figured I'd show my code in full as some of you have suggested, so I put it into jsfiddle. However it works absolutely fine there - the window can be resized with the image still retaining it's full dimensions and still remaining in the centre of the page. Yet with exactly the same code, when I load the 'index' page from my PC into Chrome, the image at the bottom either retains its size but drifts to the right when the window is shrunk, or it stays in the centre but shrinks to a ridiculous size. Any idea why there might be such a discrepancy?
Here's my jsfiddle anyway, which might have some clues:
http://jsfiddle.net/eggwhite/0yz6ndjh/
Thanks again.
If I understand you right, you want to add an image which should still be centered even if the parent element's width is smaller than the image. This could be done by using an image wrapper div which is pretty wide and position it accordingly. Also, the image itself should be centered in that wrapper.
In the following example, the layout has two columns, each with an image of 300x300px. If you resize the viewport (use the "Full page" view mode), the images will still be centered (see how the "x" in the placeholder images stays visible).
html, body, .column {
padding: 0;
margin: 0;
}
.column {
display: block;
float: left;
width: 50vw;
height: 100vh;
background-color: #ccf;
overflow: hidden;
}
.column + .column {
background-color: #ffc;
float: right;
}
.img-wrapper {
width: 10000px;
margin-left: calc(-5000px + 50%);
text-align: center;
}
.img-wrapper img {
margin: 0 auto;
}
<div class="column">
Column 1
<div class="img-wrapper">
<img src="http://placehold.it/300x300" />
</div>
</div>
<div class="column">
Column 2
<div class="img-wrapper">
<img src="http://placehold.it/300x300" />
</div>
</div>
Can be done by wrapping the image in a <div> like so:
HTML:
<div>
<img src="..." alt="random blue sky image" />
</div>
CSS:
div {
width: 100%;
text-align: center;
}
img {
width: 250px; /* or whatever width you need the image to be */
}
Here's a demo of the code.
If that didn't help, we'll ask that you present us with the problematic code. Jsfiddle.net is an easy way to do that.

Resources