CSS scale and square center crop image - javascript

So I have a collection of thumbnails in my app, which is the size of 200x200. Sometimes the original image doesn't have this ratio so I am planning to crop this image to a square.
Currently it just streches the image to fit into the thumbnail, so say my original image size is 400x800, then the image looks very squished. I wanted to crop this image so it looks at the shortest width/height and then crop it to a square, so in my example above it will be cropped to a 400x400.
Is there a way to easily do this via CSS or do I have to use some sort of JS to do this?

You can do this easily in CSS if you use background-image.
.thumb {
display: inline-block;
width: 200px;
height: 200px;
margin: 5px;
border: 3px solid #c99;
background-position: center center;
background-size: cover;
}
In this fiddle, first image is 400x800, second image is 800x400:
http://jsfiddle.net/samliew/tx7sf

Updated to handle cases where image width is greater than height.
You can do this with pure CSS. Set the container element of each image to have fixed height and width and overflow: hidden. Then set the image within to have min-width: 100%, min-height: 100%. Any extra height or width will overflow the container and be hidden.
HTML
<div class="thumb">
<img src="http://lorempixel.com/400/800" alt="" />
</div>
CSS
.thumb {
display: block;
overflow: hidden;
height: 200px;
width: 200px;
}
.thumb img {
display: block; /* Otherwise it keeps some space around baseline */
min-width: 100%; /* Scale up to fill container width */
min-height: 100%; /* Scale up to fill container height */
-ms-interpolation-mode: bicubic; /* Scaled images look a bit better in IE now */
}
Have a look at http://jsfiddle.net/thefrontender/XZP9U/5/

I came up with my own solution and thought I would share it here in case anyone else found this thread. The background-size: cover solution is the easiest, but I needed something that would work in IE7 as well. Here's what I came up with using jQuery and CSS.
Note: My images were "profile" images and needed to be cropped to squares. Hence some of the function names.
jQuery:
cropProfileImage = function(pic){
var h = $(pic).height(),
w = $(pic).width();
if($(pic).parent('.profile-image-wrap').length === 0){
// wrap the image in a "cropping" div
$(pic).wrap('<div class="profile-image-wrap"></div>');
}
if(h > w ){
// pic is portrait
$(pic).addClass('portrait');
var m = -(((h/w) * 100)-100)/2; //math the negative margin
$(pic).css('margin-top', m + '%');
}else if(w > h){
// pic is landscape
$(pic).addClass('landscape');
var m = -(((w/h) * 100)-100)/2; //math the negative margin
$(pic).css('margin-left', m + '%');
}else {
// pic is square
$(pic).addClass('square');
}
}
// Call the function for the images you want to crop
cropProfileImage('img.profile-image');
CSS
.profile-image { visibility: hidden; } /* prevent a flash of giant image before the image is wrapped by jQuery */
.profile-image-wrap {
/* whatever the dimensions you want the "cropped" image to be */
height: 8em;
width: 8em;
overflow: hidden;
}
.profile-image-wrap img.square {
visibility: visible;
width: 100%;
}
.profile-image-wrap img.portrait {
visibility: visible;
width: 100%;
height: auto;
}
.profile-image-wrap img.landscape {
visibility: visible;
height: 100%;
width: auto;
}

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.

Make an image with a percentage width a perfect square using css

Hello I have an image in a container that is set to width: 100%.
I was wondering if there's any way to can have a height generated to make it a perfect square.
So say the original image is 450px wide and 300px tall.
The css gives it a width of 100% so it stretches and fills the container, but the image remains rectangular.
Is it possible to do some css or jquery trick to generate a height to make this image a perfect suqare?
I don't care if the image gets cropped or stretched out and looks funky, I just need it to be a perfect square.
Thanks!
So you are free to stretching out the image - this can be a CSS solution:
Make a square container based on the width by using padding-top: 100%
Position the image absolutely by stretching it out to the square container as desired.
See demo below:
.wrapper {
border: 1px solid red;
height: 0;
overflow: hidden;
padding-top: 100%;
box-sizing: border-box;
position: relative;
}
.wrapper img {
width: 100%;
vertical-align: top;
position: absolute;
top: 0;
left: 0;
height: 100%;
}
<div class="wrapper">
<img src="http://placehold.it/400x300" />
</div>
Using straight CSS you can set width and height to 100vw.
You could do so with the following jQuery
var img_width = $('#image').width();
$('#image').css({'height':img_width+'px'});
Hope that helps.
Since you don't care if the image is cropped or distorted, the layout is simple.
Just add overflow: hidden to the container. The image can be any size.
div {
height: 100px;
width: 100px;
border: 2px solid red;
overflow: hidden;
}
<div>
<img src="http://www.placekitten.com/450/300">
</div>

How to make two images equal height and keep it on resize

I am trying to make two images which are placed in two floated divs equal height. Both images takes 100% of the page width, but their ratio is 60/40% and I want to kept it like that on resize. So again:
2 images, different height, want to make it same height, I do not care about the width (I will hide it), and ratio stays the same on resize.
Declare the images in the CSS as background images and give them a size of cover. In the example below I used the background: shorthand.
See the example in this fiddle.
.container {
width: 100%;
height: 200px;
background-color: #eee;
}
.foo, .bar { height: 100%; float: left; }
.foo {
width: 60%;
background: url("http://url.com/image.png") no-repeat center top / cover;
}
.bar {
width: 40%;
background: url("http://url.com/image.png") no-repeat center top / cover;
}

Resize an image to stay within the viewport

How can I make an image resize and maintain aspect ratio to stay within the container if the image is larger than the container, but not resize if the image is smaller than the container.
If the width of the image is larger than the width of the container then the following code should apply.
img {
width: 100%;
height: auto;
}
If the width of the image is smaller than the width of the container then the following code should apply.
img {
width: auto;
height: 100%;
}
I tried using the following code, but some strange things happen when the image width is larger then the container's width.
img_w = parseInt($("#img").css("width"));
screen_w = parseInt($(window).width());
img_w = parseInt($("#img").css("width"));
screen_w = parseInt($(window).width());
if (img_w > screen_w) {
$("#img").css("width", screen_w + "px"); // like 100%;
$("#img").css("height", "auto");
} else {
$("#img").css("width", "auto");
$("#img").css("height", "100%");
}
Problem solved with the following CSS:
img {
max-width:100%;
max-height:100%;
width: auto;
height: auto;
}
I tried your code and you can see here the result: http://jsfiddle.net/g6rL3L5h/
I think it's now ok and working.
I just delete 'html' in your css.
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
text-align: center;
}
do you needed this?

HTML CSS JS onload change image size bad scale

I need scale image smooth, variable is image height, width is auto scaling by height size with css width: auto
css and HTML:
footer {
position: fixed;
bottom: 0;
height: 100%; /* if i change size here example: 300px get good scale */
margin-top: 15px;
}
footer img[usemap] {
border: none;
width: auto;
max-height: 100%;
height: 100%;
}
<footer>
<img src='https://burritojustice.files.wordpress.com/2011/02/img_3769.jpg' usemap="#Map" name="#Map" id="map">
</footer>
javascript:
$('footer').css('height', '300px'); //if i change size here get bad scale
/* at the result i need write with javascript how much height it's my image and get nice scale */
If i change css line: height: 100% to height: 300px it's works good width change together height by scale, but if i try to change value with javascript like this: $('footer').css('height', '300px'); it's works bad, also get 300px height but width remains the same not scaling.
https://jsfiddle.net/bddgo26o/1/
Check the v3 of the fiddle:
https://jsfiddle.net/bddgo26o/3/
Is that what you need?
footer {
position: fixed;
bottom: 0;
height: 20%; /* if i change size here example: 300px get good scale */
width:100%;
margin-top: 15px;
overflow: hidden;
border: 1px solid black;
}
footer img[usemap] {
border: none;
max-height: 100%;
min-height:100%;
}
$('footer').css('height', '50%'); //now changing gets ok
If I understand correctly, you wand to resize the height of the footer, and get the image resizing with the same proportions ?
If this is what you need, I have a solution in this JSFiddle
Basically, You are resizing the footer, so the image is resizing it height. But the original image size never change, so does the width.
I added this code to change the image height (to make it the same as the footer) :
$('footer img[usemap]').height($("footer").height());

Categories