Make two images same height without hardcoding? - javascript

Here I have two images. I have the widths of these two img elements exactly how I want it. The gutter between these two elements and their container is exactly how I want it as well.
After applying vertical-align: top, I noticed that both of these images automatically determine their own height based on the aspect ratio of the source image. As you can see this means the images end up having the same widths (which I defined explicitly) but different heights by a matter of a dozen pixels or so:
I was wondering if there is a way to give both of these images the same height without switching them to be background-image's. Also, if this image feed is 'dynamic' how could I explicitly define the height while not knowing the aspect ratio of the image in question?

So the problem is that if you set the width and height the same on two differently sized images, at least one of them will be distorted.
You could quite easily fix this, as long as the images are relatively similar in size. The idea is, you surround the image with a div and give the div the height and width instead of the image. Then give it the CSS overflow: hidden; and it will crop off the extra bit of the image. You may also need to give it display: inline-block; to get the div's next to each other.
div {
display: inline-block;
height: 200px;
width: 200px;
overflow: hidden;
}
<div>
<img src="http://via.placeholder.com/200x200">
</div>
<div>
<img src="http://via.placeholder.com/200x240">
</div>
Or if you want the image vertically centered:
div {
display: inline-block;
height: 200px;
width: 200px;
overflow: hidden;
position: relative;
}
img {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
<div>
<img src="http://via.placeholder.com/200x200">
</div>
<div>
<img src="http://via.placeholder.com/200x240">
</div>

I recommend using aspect ratios. Format your images to be the same aspect ratio at the minimum before uploading. The other option would be converting to BG images if you can't pre-format.
.container {
padding-top: 100%; /* 1:1 Aspect Ratio */
//padding-top: 75%; /* 4:3 Aspect Ratio */
//padding-top: 66.66%; /* 3:2 Aspect Ratio */
}

I think another approach would be setting image height and use actual image content as background image with background-size:contain; this way your image will not be distorted and will always fill the size.
<img src="blank.gif" style="background-image:url(myImage.jpg);background-repeat:no-repeat;background-position:center center; background-size:contain;height:300px;">

If I were you, I would utilize a CSS method of wrapping your images in a container that has overflow set to hidden which will hide the hanging off pixels.
If you feel people will miss out on part of the image, you could use a css animation like I did below when you hover over it. I use translate3d because it utilizes GPU acceleration in browsers.
main {
display: flex;
justify-content: space-between;
flex-wrap: nowrap;
width: 500px;
}
.img-wrap {
overflow:hidden;
height: 15rem;
width: 15rem;
}
.img-wrap>img {
max-width: 500px;
}
.img-wrap:hover>img {
animation: pan 5s;
}
#keyframes pan {
from {transform:translate3d(0,0,0);}
to {transform:translate3d(-100px,0,0);}
}
<main>
<div class="img-wrap">
<img src="http://lorempixel.com/city/500/600">
</div>
<div class="img-wrap">
<img src="http://lorempixel.com/people/800/700">
</div>
</main>

The easiest way to achieve this would be to set the images as the background of your divs. This will not distort the images as setting the height and width on an img element would. You can then define whether to center it or not.
.img {
width: 200px;
height: 100px;
display: inline-block;
margin-right: 10px;
background-size: cover;
background-position: center;
}
<div class="img" style="background-image: url('https://images.pexels.com/photos/23764/pexels-photo.jpg?w=1260&h=750&auto=compress&cs=tinysrgb');"></div>
<div class="img" style="background-image: url('https://images.pexels.com/photos/23388/pexels-photo.jpg?w=1260&h=750&auto=compress&cs=tinysrgb');">
</div>

I have always had this problem, the only solution I found that solves this problem effectively is
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: cover;
and have the image displayed via backend like php with inline style
<div class="image" style="background-image: url('pathToImage');"></div>

Related

Make Image Fill Entire Screen Without Bounding Box?

I am currently using the following code to make images fill the entire screen while keeping their aspect ratio.
div {
position: fixed;
top: 0;
width: 100%;
height: 100%;
}
img {
object-fit: contain;
width: 100%;
height: 100%;
border: thin solid black;
}
<div>
<img src="https://placekitten.com/200/300" alt="">
</div>
What this does is resize images which are smaller or larger than the screen to fill the entire screen while keeping their aspect ratio. For example, when using a display in landscape orientation (width > height) an image with portrait ratio (height > width) would be as high as the screen, while there is some space on the left and right. My example should illustrate this.
In these cases, I would like to be able to detect if the user clicks on the image or outside of it. However, with this approach the bounding box of the image fills the entire div and the entire screen, even if it looks different to the user.
What I mean by this is: The div is set to have 100 percent of the width and height of its container. Since its position is set to fixed, it will have the same size as the screen. For the object-fit property to work on the image, I need to assign it a width and height too. When I set those values to 100 percent, the image's so-called bounding box will fill the entire parent/screen, and then the image will take up as much space as it can inside this box while keeping its aspect ratio (see this answer for another explanation). That means it may look like the image only has the same height, and not the same width as its parent, but in reality, it does. You can verify this using the developer tools of your browser, and I added a border to the image to visualise it. This means, however, that I cannot attach an event listener to the image and one to the div to differentiate between clicks on the image and on the blank area, since the image counts as filling the entire area.
What would be the best approach to solve this? Is there a CSS-only-way? The only thing I can come up with is using JS to size the image, which means making it bigger/smaller to fit the screen while making it keep its aspect ratio, and also doing this on every resize. This seems like a lot of work for something so simple.
Try using flex layout. If you change the height and width of div.outer or the dimensions of the image, it will remain centered in one dimension and fill the div.outer in the other. And only a click on the image itself will raise the alert.
div.outer {
height: 200px;
width: 100px;
border: solid 1px black;
display: flex;
flex-direction: column;
justify-content: center;
}
div.inner {
display: flex;
flex-direction: row;
justify-content: center;
}
div.inner,
img {
max-width: 100%;
max-height: 100%;
}
<div class="outer">
<div class="inner">
<img src="https://placekitten.com/200/300" onclick="alert('click')">
</div>
</div>
In general sense, if image covers the whole screen then we cant target the click on the parent div.
But if u go for the little space all on four corners, then we can provide the click on the parent.
Please refer to the snippet below.
Use the Flex on the div to center the img(image) tag.
I have also provided the maximum width and height so that, the img(image) tag will be in boundary of the parent.
I had even provided you on how to force stretch if needed
* { box-sizing:border-box;}
html,body {height:100%;}
body {margin:0;}
div {
position: fixed;
/*stretching the DIV*/
top: 0;
bottom:0;
right:0;
left: 0;
/*added the background-color for identification*/
background-color: #eadefe;
/*new-props*/
display: flex;
justify-content: center;
align-items: center;
}
img {
max-width: 100%; /** changed width to max-width **/
max-height: 100%; /** changed height to max-height **/
border: thin solid black;
}
/**Below is to force strech and keep image proportions**/
div.force-stretch {
padding: 10px; /*provided padding so image and div can both get clicks*/
}
div.force-stretch img {
object-fit:cover; /*added 10px gap so even if stretched there is space for parent div click*/
width: 100%;
height: 100%;
}
<div>
<img src="https://placekitten.com/200/300" alt="">
</div>
You can use the strange behavior of flex to produce the desired result.
document.querySelector('img').onclick = () => {alert('you pet the kitten.')}
body {
margin: 0;
}
.image-holder {
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
}
<div class="image-holder">
<img
src="https://images.unsplash.com/photo-1592194996308-7b43878e84a6?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=387&q=80"
alt="kitten" />
</div>
flex stretches the image's height, if you want to stretch the width use flex-direction: column.
This code solves your problem:
.img-container {
width: 100%;
height: 100vh;
text-align: center;
}
img {
object-fit: contain;
height: 100%;
max-width: 100%;
}
.some-text {
height: 1000px;
}
<div class="some-text"></div>
<div class="img-container">
<img src="https://placekitten.com/500/100" alt="">
</div>
<div class="some-text"></div>
Supposing that you have some elements before and after the image (element .some-text).
You can use the background-size property in CSS to set the size of the background image to fill the entire screen without having a bounding box. You can set the background-size property value to cover to make sure the image covers the entire screen, while maintaining its aspect ratio.
Here's an example:
body {
background-image: url('your-image-url.jpg');
background-size: cover;
background-repeat: no-repeat;
background-attachment: fixed;
}
This will set the background image to fill the entire screen, without any bounding box or stretching of the image. The background-repeat property is set to no-repeat to prevent the image from repeating and the background-attachment property is set to fixed to keep the image in a fixed position on the screen.

How can i get my image to to completely fill my div?

I'm trying to create a hero image that would fill the div to my web page. I've tried setting the width and height to 100%, but for some reason the image will only fill the div to about half way.
Here's the CSS and HTML Im trying to get the image to fill the entire screen but it wont work for me
div.hero{
width: 100%;
height: 100%;
margin:0 auto;
}
#imghero {
max-width: 100%;
max-height: 100%;
}
<main>
<div class="hero">
<img src="https://i.stack.imgur.com/4Xg4w.jpg" alt="laptop" class="imghero">
<h1>Welcome</h1>
</div>
</main>
I see others here recommend going with the background-image, but I would suggest using an actual image element instead, and scaling that with object-fit: cover. There's two reasons for that.
You get the SEO and accessibility benefit of having an actual image element
It gives you all the benefits of image elements, like using srcset to serve different sizes to various devices, using lazy loading etc...
Here's how you do it:
Html
<div class="container">
<img
src="imageurl.jpg"
srcset="*optional*"
sizes="*optional*"
alt="My image"
/>
</div>
Css
.container {
position: relative;
width: 80vw; /* Or whatever size you want */
height: 50vh; /* Or whatever size you want */
}
.container img {
position: absolute;
top: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
If you don't have a fixed with/height on the container, you can use an aspect ratio instead like this:
.container {
position: relative;
width: 100%;
height: 0;
padding-bottom: 56.25%; /* 16:9 aspect ratio */
}
You have to set Width & Height also to the image, not only max-width & max-height
div.hero{width : 100%;
height: 100%;margin:0 auto; }
.imghero{max-width: 100%;
max-height: 100%;
height: 300px;
width: 100% !important;
}
<main>
<div class="hero">
<img src="https://i.stack.imgur.com/4Xg4w.jpg" alt="laptop" class="imghero">
<h1>Welcome</h1>
</div>
</main>
Use .imghero instead of #imghero, you are declaring imghero as class
You can try setting a background image to div
.hero{
background-image: url("https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQc-z-m2WiHy9yx9AfLg_YEi6mzltIlkaY_JGrIhP8d8mh_wMpB");
background-size: cover;
background-repeat: no-repeat;
/*this is optional*/
min-height: 500px;
}
<main>
<div class="hero">
<h1>Welcome</h1>
</div>
</main>
I wouldn't put an image straight in the div, I'd add as a background image.
<main>
<div class="hero">
</div>
</main>
and for CSS
.hero {
background-image:url(image address here.);
padding-top:300px;
padding-bottom:300px;
}
The padding in the CSS adds height to the div, handy if you want to add text in there.
Or you could replace the padding with height: auto to fill the entire browser height.
Since you're using the img tag, you can't manipulate the image widths and heights, it's max-width and max-height will be that of the image.
In order for you to get it to span a full width / height, you'll need to add it as a background-image attribute. Then you can set the widths and heights on the div.
HTML (note, we don't include the image here we do it in the CSS):
<main>
<div class="hero imghero">
<h1>Welcome</h1>
</div>
</main>
CSS:
.hero {
width: 100%;
height: 100%;
margin: 0;
}
.imhero {
width: 100%;
height: 100%;
background-image: url("https://i.stack.imgur.com/4Xg4w.jpg") no-repeat;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}

Jquery - How to crop a image and scale it same size as the original image

I want to crop a image from original image by giving (xAxis, yAxis, Height, Width).
all the cropped image should just as big as the boxes belows
[2
and make the cropped part to a fix size so I can show those cropped image orderly on the web no matter the height and width given by user.
I try using jrac however it required me to save the cropped image before I show with tag. Also I tried use pure css to complete this.
.crop {
width: 200px;
height: 150px;
overflow: hidden;
}
.crop img {
width: 400px;
height: 300px;
margin: -75px 0 0 -100px;
}
However the idea of css to crop image is just to hide the other part of the image and if I resize it as the original image. The other part appear again. I'm wondering what is the good approach to do so?
CSS IMG Fill the container width/height. Recognize IMG aspect ratio.
EDIT: I had to scrap the idea of using image orientation. Aspect Ratio makes more sense.
This could work - Pictures are from wikimedia. One is vertical, second is horizontal. They are centered and fit to width/height.
I had to change $(document).ready() to $(window).on("load") - because the document ready waits only for HTML DOM to be fully loaded, but if images weren't downloaded yet, it would falsely recognize img dimensions and therefore its aspect ratio (EDIT) .
jQuery is used only to determine the Image Aspect ratio
CSS centers the images inside the container element and resizes them
according to the aspect ratio in comparison to the container.
Cropping is done simply by containers overflow:hidden
$(window).on("load",function() {//wait for images to be loaded
$(".crop img").each(function() {//loop through images to be cropped
if (($(this).width()/$(this).height()) < ($(this).parent().width()/$(this).parent().height()))//compare Aspect ratio
$(this).addClass("taller");
});
});
body{padding:0;margin:0;}
.crop {
position: relative;
display:inline-block;
width: 200px;
height: 150px;
overflow: hidden;
/*hide "crop" overflowing parts of images*/
border:1px solid #000;
}
.crop img {
position: relative;
box-sizing: border-box;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
/*center the overflowing element*/
width: auto;
height: 100%;
/*Fit to height, overflow horizontally*/
border:2px dashed red;
/*highlight img borders for demonstration*/
}
.crop img.taller{
width: 100%;
height: auto;
/*Fit to width, overflow vertically*/
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="crop">
<img src="https://upload.wikimedia.org/wikipedia/commons/8/82/Tyndall_Effect_seen_in_Nature.jpg">
</span>
<span class="crop">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/WolayerSee.jpg/800px-WolayerSee.jpg">
</span>
<span class="crop" style="height:80px;">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/WolayerSee.jpg/800px-WolayerSee.jpg">
</span>
Much cleaner solution suggested by https://stackoverflow.com/users/1034869/edmundo - https://stackoverflow.com/a/42714818/7581087
It is much cleaner and easier. On the other hand, it doesn't use <img /> - which can possibly be bothersome.
body{padding:0;margin:0;}
.crop {
display:inline-block;
width: 180px;
height: 120px;
background-position:center center;
background-size:cover;
border:1px solid #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="crop" title="1st Image" style="background-image:url(https://upload.wikimedia.org/wikipedia/commons/8/82/Tyndall_Effect_seen_in_Nature.jpg)">
</span>
<span class="crop" title="2nd Image" style="background-image:url(https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/WolayerSee.jpg/800px-WolayerSee.jpg)">
</span>
<span class="crop" title="3rd Image" style="height:80px;background-image:url(https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/WolayerSee.jpg/800px-WolayerSee.jpg)">
</span>
<span class="crop" title="4th Image" style="width:50px;background-image:url(https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/WolayerSee.jpg/800px-WolayerSee.jpg)">
</span>

If image height exceeds image width, vertically center image by cropping its top and bottom - possible with only CSS?

Given a scenario where you don't know the height and width of image elements in advance, let's say that in cases where image height is greater than image width, you'd like to vertically center the image by cropping the same amount of pixels form its top and bottom, such that the new image height matches the image width. For example, if an image has a width of 200px, and its height is 250px, crop 25px from its top and from its bottom.
Here's an example setup:
HTML:
<div class = 'cell'>
...
<div class = 'image_container'>
...
<img ...>
</div>
</div>
CSS:
.cell {
display: inline-block;
float: left;
/* width will be changed by use of '#media screen'.
Smaller browser window -> larger width */
width: 31%;
}
.image_container {
position: relative;
float: left;
width: 100%;
}
.image_container > img {
width: 100%;
}
Is it possible to accomplish the aforementioned center/crop operation using only CSS, or is it necessary to use javascript/jquery for this?
You can use the object-fit CSS attribute. It acts a lot like the background-size attribute.
.image_container > img {
object-fit: contain;
}
Note that this doesn't have full browser support as of now (October 2016) so you may want to look into setting the image as a background on a div and using background-position and background-size to deal with this instead of an <img> tag.
.image_container {
height: 300px;
background-color: cornflowerblue;
image-rendering: pixelated;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAALklEQVQoU2NkgID/UBqdYmSESoJobOA/sgKQKTCFMDaKAuqYAHMs3CqiHInXmwDZGBMDEmk6SQAAAABJRU5ErkJggg==');
background-repeat: no-repeat;
background-position: center center;
background-size: 200px;
}
<div class="image_container"></div>
.cover_image {
height: 400px;
background: url('http://lorempixel.com/g/400/200/') no-repeat scroll center center;
background-size: cover;
}
<div class="cover_image"></div>

Calculate apsect ratio width based on height

I have an inline img that is 1280(w) x 1024(h) and is contained within a div. The divs dimensions are set 100%(w/h) of the viewport with overflow hidden.
I want to use the image as a fullscreen background and require that it fills the viewport completely regardless of dimensions with no borders showing. It must keep its aspect ratio and I would also like the image to be centered at all times. I am aware that to achieve this some of the image will be cropped.
I believe if make the image height match the viewport height and calculate the width based on the images aspect ratio this will work but I am unsure how to do this. Can anyone help?
Many thanks in advance.
Use backstretch http://srobbin.com/jquery-plugins/backstretch/
$("#demo").backstretch("http://urltoimage.jpg");'
set #demo to 100/100% width and height
If you're not 100% glued to using an img tag, you can do the following:
HTML
<div id="background"></div>
CSS
#background {
background: url('path/to/img.jpg');
background-size: cover;
background-position: center center;
width: 100vw;
height: 100vh;
}
Not really an answer to your question but a potential alternative -- have you tried the min-height/min-width CSS properties?
HTML:
<div class="container">
<div class="image-wrapper">
<img src="..." />
</div>
</div>
CSS:
.container {
width: 100vw;
height: 100vh;
background-color: grey;
}
.image-wrapper {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}
.image-wrapper img {
position: absolute;
top: 50%;
left: 50%;
min-width: 100%;
min-height: 100%;
transform: translateX(-50%) translateY(-50%);
}
Fiddle: https://jsfiddle.net/mkjoyep1/
In the example, .container (your full width/height div), fills the page width vw/wh and the .image-wrapper has its width/height set to 100% which will match the parent's width and height. With overflow: hidden acting as the crop mechanism you can then stretch your image to fill it's container. I've positioned the image in the center with the method explored here.
This appears to work for me on Chrome and Firefox.
*Edited to include html/css

Categories