How to shrink a DIV around a scaled IMG? - css

A simple (one might think!) question to all CSS gurus: I would like to shrink a DIV snugly around an IMG. The IMG is 600 x 800 and I needed it much smaller. So I go {height: 100%; width: auto;} and constrain the height via a wrapper DIV. However, to maintain the (unknown to me) AR, I cannot fix the width on the DIV. I tried to set the wrapping DIV to "display: inline-block" or "float: left" or "position: absolute" or ... - no matter: most browsers will stretch that DIV 800px wide - the original width of the full-size IMG - so it looks sthg like this:
[[IMG].............................]
Bizarrely, I can add some text to the DIV (just to test), and that text will actually appear right next to the scaled IMG:
[[IMG]Hello world..................]
Does anyone here know why the original size of the IMG matters (for dimensioning the width, it does not affect the height)? And what I might be able to do to shrink the DIV?
Thanks for looking.
EDIT:
To test Pär Wieslander's idea, I wrote a little test bed that should help clarify what I am on about:
<style type="text/css">
html, body {
height: 100%;
}
#dialog {
background: green;
height: 50%;
position: relative;
}
#frame {
border: 2px solid black;
display: inline-block;
height: 100%;
position: absolute;
}
#img {
height: 100%;
width: auto;
}
</style>
<body>
<div id="dialog">
<div id="frame">
<img id='img' src='...' />
</div>
</div>
</body>
Just pick any large IMG of your choice. You should find an inexplicably wide frame around and image that has squeezed - height-wise - onto the green carpet.

If you specify the image's width or height as a percentage, that percentage is calculated in proportion to the size of the parent block. So specifying width: 50% on the image doesn't mean 50% of the original image width -- it means 50% of the width of the parent block. The same goes for the height. Thus, there will always be extra space around the image as long as you specify the width or height as a percentage.
The solution is simple -- specify the dimensions in pixels, ems or any other unit other than a percentage:
HTML
<div class="wrapper">
<img class="small" src="myimage.jpg">
</div>
CSS
img.small {
width: 150px; /* or whatever you like */
display: block; /* to avoid empty space below the image */
}
div.wrapper {
display: inline-block;
border: 1px solid #000;
}
Edit: Based on your comments and updated post, I understand that what you really want to do is to set the width of the surrounding div and make the image fill up that div. Here's an example that does that:
HTML
<div class="wrapper big">
<img src="myimage.jpg">
</div>
<div class="wrapper small">
<img src="myimage.jpg">
</div>
CSS
img {
display: block;
width: 100%;
}
.wrapper {
margin-top: 1em;
border: 1px solid #000;
}
.big {
width: 600px;
}
.small {
width: 300px;
}

So I go height="50%", say, and width="auto" (to maintain AR).
Why not just go width="50%" too as this would resolve it.

I think Pär's approach is right: don't do { height: fix; width: auto; } but do instead { height: auto; width: fix; } Works better.

Related

how to keep original ratio of image within square div

I have seen lot of solution about this. The solutions are either for wider or taller image. But my problem is the image which need to keep in ratio, I have no idea it could be taller or wider.
Just give it width: 100% to make it responsive or adjustable to the parent's size:
.square {
width: 400px;
max-width: 100%; /* also make its parent responsive (advisable) */
}
.square > img {
display: block; /* removes bottom margin/whitespace, alternative: "vertical-align: bottom" */
width: 100%; /* responsiveness */
}
<div class="square">
<img src="https://placehold.it/1600x900" alt="img">
</div>

Place two images side by side

I am trying to place two images side by side. I want them to be full width and responsive. However, I can't figure out how to get them on the same line. Does anyone have solutions? Here is a fiddle - https://jsfiddle.net/0je558ex/
<div class="food-featured-posts">
<div class="food-featured-posts-first">
<img src="https://static.pexels.com/photos/2855/landscape-mountains-nature-lake.jpg"/ >
</div>
<div class="food-featured-posts-second">
<img src="https://static.pexels.com/photos/4164/landscape-mountains-nature-mountain.jpeg"/ >
</div>
</div>
food-featured-posts {
width: 100%;
margin-bottom: 100px;
}
.food-featured-posts-first img {
width: 50%;
height: 50%;
display:inline-block
}
.food-featured-posts-second img {
width: 50%;
height: 50%;
display:inline-block
}
You have two problems actually.
First, you're setting the styling of the img, but the div which wraps them are implicitly styled to basically be: display:block;width:100%;.
Simply remove the divs.
Second, and slightly more interestingly, your img elements still will not render next to each other at 50% because any whitespace between two display:inline-block elements means that the total size is greater than 100%, so the second element is kicked to the second line.
You therefore need to put the img tags on the same line—frustrating, I know.
See this question: CSS two div width 50% in one line with line break in file
<div class="food-featured-posts">
<!-- Note these are on the same line -->
<img src="https://static.pexels.com/photos/2855/landscape-mountains-nature-lake.jpg"/ ><img src="https://static.pexels.com/photos/4164/landscape-mountains-nature-mountain.jpeg"/ >
</div>
food-featured-posts {
width: 100%;
margin-bottom: 100px;
}
.food-featured-posts img {
width: 50%;
display:inline-block;
}
Set the divs that wrap the image to width: 50%; display: inline-block; and set the img tags to width: 100%; so they will take up the entire div, then remove the space between the inline-block div elements in your HTML since spaces on inline elements take up space and the space will exceed 100% width (since each div takes up 50%).
img {
width: 100%;
}
.food-featured-posts > div {
width: 50%;
display: inline-block;
}
<div class="food-featured-posts">
<div class="food-featured-posts-first">
<img src="https://static.pexels.com/photos/2855/landscape-mountains-nature-lake.jpg"/ >
</div><div class="food-featured-posts-second">
<img src="https://static.pexels.com/photos/4164/landscape-mountains-nature-mountain.jpeg"/ >
</div>
</div>

Relative values over a scaled image

First, please consider this fiddle.
I need to get some links over specific image regions, however those images are scaled according to the parent size...
that's why the link's position and size are relative(percentages) to the image.
But the fiddle shows the problem of this approach.
Is there anyway to get the .image-wrapper to "mimic" the img size and position after scaled?! Any trick or whatever?
Note: I'm OK with webkit-only solutions!
Edit 1
Actually I'm more focused in making the image fit on the content div, then making the image wrapper follow the resulting image size. Here's what I achieved so far...
Now I'm trying to get it working with the image centralized.
Here is the CSS skeleton for a solution.
Suppose your HTML looks like the following:
<div id="content1" class="content portrait">
<div class="panel-wrapper">
<div class="image-wrapper">
<img src="http://placekitten.com/200/250" />
</div>
</div>
</div>
<div id="content2" class="content landscape">
<div class="panel-wrapper">
<div class="image-wrapper">
<img src="http://placekitten.com/300/200" />
</div>
</div>
</div>
The HTML is similar to your original code except that there is an extra wrapper .panel-wrapper.
I used the following CSS:
.content {
background: lightgray;
display: table;
margin: 40px 0;
}
#content1 {
width:100px;
height:150px;
}
#content2 {
width:150px;
height:150px;
}
.panel-wrapper {
display: table-cell;
vertical-align: middle;
text-align: center;
}
.image-wrapper {
outline: 1px solid green;
position:relative;
display: inline-block;
}
.content img {
display: block;
width: 100%;
}
.portrait .image-wrapper {
height: calc(100% - 2px);
}
.portrait .img {
height: 100%;
}
.landscape .image-wrapper {
width: calc(100% - 2px);
}
.landscape .img {
width: 100%;
}
.sample-link {
background:rgba(0, 0, 255, 0.3);
position:absolute;
display:block;
width: 50%;
height:20%;
top:5%;
left:5%;
}
I apply display: table to .content and display: table-cell to .panel-wrapper so that I can get a get the image centered both vertically and horizontally.
The .image-wrapper has display: inline-block.
To get the scaling right, you need to consider two cases depending on the aspect ratio of the image.
For portrait images, apply height: 100% to the .image-wrapper and the child img.
For landscape images, apply width: 100% respectively.
If you have a border on .image-wrapper, use the CSS calc() function to adjust for the 2px width of the borders.
What you need to do is use JavaScript/jQuery to determine the aspect ratio of the image and then apply the correct class (.portrait or .landscape) to the .content block.
See demo at: http://jsfiddle.net/audetwebdesign/SZjvJ/
A possible way is to work with image ratio and to adjust link ratio and margins according to image dimensions, with Jquery.
Have a look at this example fiddle: http://jsfiddle.net/t7Ucj/
The Js measures width and height of the image and according to its ratio, it works on the width or on the height of the link.
var width = $('#content2 img').width();
var height = $('#content2 img').height();
//vertical image
if(height > width){
var left = $('#content2 img').css('margin-left');
$('#content2 .sample-link').css({'width': width, 'left' : left});
}
else{
var top = $('#content2 img').css('margin-top');
$('#content2 .sample-link').css({'height': height*0.2, 'top' : top + height*0.4});
}
Then you can wrap all the instructions in a simple function obviously.
I know it can be tricky to put all the possible cases but i had a similar problem and solved in this way.
hope it helps

Fluid image, vertical align (middle) within width fluid DIV

So yet another question about vertically aligning an image within a div, but I think mine is different than the others I've found on here. I can't seem to find a solution that works for my situation.
I have a DIV that is 100% width (to it's container, which is floating left and has a set pixel width) and has a set pixel height. I have an image inside that I am positioning absolute to get it to the background of content within the DIV. The image is fluid with a width of 100%.
All works well, but I want to get the image to vertically align to the middle of the container and height is unknown.
Here is some sample code that shows what I'm trying to do:
<div class="container">
<div class="image-wrapper">
<img src="http://farm5.staticflickr.com/4111/4968056789_d872094672_o.jpg"
width="100%" />
</div>
<p>Some text</p>
</div>
And some sample CSS:
.container {
width:100%;
margin-top:10px;
height:100px;
overflow:hidden;
}
.image-wrapper {
position: relative;
}
.image-wrapper > img {
position: absolute;
z-index: -1;
}
p {
text-align: center;
padding-top: 10px;
color:#fff;
font-weight: bold;
}
But the flower should show up with it's center visible within the container div.
Any thoughts? I'm trying to avoid any Javascript sizing (the outer container, not shown in this sample, is already being sized). I'm not opposed to more DIVs, tables.. whatever you got!
A jsFiddle to demo this:
http://jsfiddle.net/JonMcL/sNz9h/
Why not go for the background-image property? That allows vertical centering...
http://jsfiddle.net/urrWS/
Assuming you want to only scale the image down and not stretch it beyond its native resolution this should do the trick. A little bit of jQuery is involved but it's minimal. Essentially, this adjusts the top-margin of the IMG on the window.resize event.
HTML
<div id="container">
<img id="image" src="image.jpg"> <!-- native size is 480x300 -->
</div>
CSS
#container {
margin: auto;
width: 80%;
height: 300px;
border: 1px solid gray;
}
#image {
display: block;
width: 100%;
max-width: 480px;
margin: auto;
}
jQuery
function adjustImage() {
$("#image").css('margin-top', ($("#container").height() - $("#image").height()) / 2);
}
$(window).load(function() {
adjustImage();
$(window).resize(function() {
adjustImage();
});
});
If I get what you need I would suggest setting the background image via css, then you can set the position correctly etc.
.container {
width:100%;
margin-top:10px;
background-image:url("http://farm5.staticflickr.com/4111/4968056789_d872094672_o.jpg");
background-repeat:no-repeat;
background-position:left center;
height:100px;
overflow:hidden;
}
http://jsfiddle.net/sNz9h/6/

CSS: how to get scrollbars for div inside container of fixed height

I have the following markup:
<div class="FixedHeightContainer">
<h2>Title</h2>
<div class="Content">
..blah blah blah...
</div>
</div>
The CSS looks like this:
.FixedHeightContainer
{
float:right;
height: 250px;
width:250px;
}
.Content
{
???
}
Due to its content, the height of div.Content is typically greater than the space provided by div.FixedHeightContainer. At the moment, div.Content merrily extends out of the bottom of div.FixedHeightContainer - not at all what I want.
How do I specify that div.Content gets scrollbars (preferably vertical only, but I'm not fussy) when its height is too great to fit?
overflow:auto and overflow:scroll are doing nothing, for some bizarre reason.
setting the overflow should take care of it, but you need to set the height of Content also. If the height attribute is not set, the div will grow vertically as tall as it needs to, and scrollbars wont be needed.
See Example:
http://jsfiddle.net/ftkbL/1/
FWIW, here is my approach = a simple one that works for me:
<div id="outerDivWrapper">
<div id="outerDiv">
<div id="scrollableContent">
blah blah blah
</div>
</div>
</div>
html, body {
height: 100%;
margin: 0em;
}
#outerDivWrapper, #outerDiv {
height: 100%;
margin: 0em;
}
#scrollableContent {
height: 100%;
margin: 0em;
overflow-y: auto;
}
Code from the above answer by Dutchie432
.FixedHeightContainer {
float:right;
height: 250px;
width:250px;
padding:3px;
background:#f00;
}
.Content {
height:224px;
overflow:auto;
background:#fff;
}
This is a great question because the answer is not immediately obvious, for such a simple task. The problem has hit me several times over the years, and It seems I always have to think about it before I get it right.
Below is my solution which uses (only) two CSS-classes, 'innerDiv' and 'outerDiv'.
<div id="outerDiv">
<div id="innerDiv">
A <p> B <p> C <p> D <p>
</div>
</div>
<style>
#outerDiv
{ height : 200px;
margin : 44px; border: solid 4px Red;
}
#innerDiv
{ height : 80%;
overflow-y : auto;
border : solid 4px Green; font-size: 300%;
}
</style>
Why does that work, and why do I say the answer is "not immediately obvious"?
In the example above both the outerDiv and innerDiv have fixed height because we set the height: -property for both of them.
We have the innerDiv height less than the height of the outerDiv. Therefore innerDiv "fits" into the outer-div and therefore the outer div should not get a scrollbar, right? Yes except if the innerDiv has so much content that it does not fit into the fixed height of the innerDiv but overflows. Therefore the question is how can we prevent the inner div from "overflowing"?
The way to prevent the innerDiv from overflowing is to give it the attribute "overflow: auto", or "overflow-y: auto" if we just want to prevent vertical overflow.
The reason the solution is "not immediately obvious" is this: The default value of 'overflow' is NOT 'auto', but 'visible'.
One might (erroneously) assume that the default value of overflow is "auto", because then everything should be auto-matically taken care of, right? Not so fast, the default of overflow is 'visible', NOT 'auto'.
So if you remove the "overflow-y:auto" from the example above there will be no scrollbars. If you remove it but add it to the outerDiv, the outer div will have the scrollbar, which is NOT what we want. If you have it in both then only innerDiv will have it.
HTML
<div class="FixedHeightContainer">
<h2>Title</h2>
<div class="Content">
..blah blah blah...
</div>
</div>
CSS
.FixedHeightContainer
{
float:right;
height: 250px;
width:250px;
overflow-y: scroll;
}
/*SCROLLBAR MODIFICATIONS*/
.FixedHeightContainer::-webkit-scrollbar {
width: 8px;
}
.FixedHeightContainer::-webkit-scrollbar-thumb {
background: #909090;
border-radius: 8px;
}
.FixedHeightContainer::-webkit-scrollbar-track {
background: #FFFFFF;
}
1)Set the height and width of div.Content smaller or equal as per design(preferably smaller). You may use px or pcnt as unit.
2)Now bring overflow-y property and set the value auto.
CSS:
<style>
.FixedHeightContainer
{
float: right;
height: 250px;
width: 250px;
border: 1px solid red;
}
.Content
{
height: 65%;
width: 95%;
overflow-y: auto;
border: 1px solid red;
}
</style>
HTML:
<div class="FixedHeightContainer">
<h2>Title</h2>
<div class="Content">
Any length/size of content.
</div>
</div>

Resources