How to image swap based on screen size? - javascript

I recently started experimenting with bootstrap and scaling things to size when the screen is shrunk. If I have an image that needs to be at least 300px to be readable but the screen is only 250px wide (just for example) they would have to scroll left and right to see the whole image. On ford.com they actually swap the larger image out for a similar image that is smaller, more fit for the screen. Then as you drag the screen larger, it switches back to the larger image. Im assuming this has to do with some form of JS and screen size dimensions. Any thoughts?

Technically the feature you're describing could be achieved through either css, html or javascript.
In CSS you can use media queries to load your images through the background property,
.image {
background: url("image.jpg");
}
#media only screen and (max-width: 250px) {
.image {
background: url("alternative-image.jpg");
}
}
or, in case you had both images loaded in the html document, through the display property.
.image {
display: initial;
}
.alternative-image {
display: none;
}
#media only screen and (max-width: 250px) {
.image {
display: none;
}
.alternative-image {
display: initial;
}
}
Read more about media queries here.
In HTML you can use the picture and source elements,
<picture>
<source media="(min-width: 250px)" srcset="image.jpg" />
<img src="alternative-image.jpg" />
</picture>
or the simpler alternative, the srcset attribute.
<img src="alternative-image.jpg" srcset="image.jpg 250px" />
Read more about it here.
Finally, in JavaScript you can use the window size properties to build a function that loads the right image for each size every time the window is resized.
window.onresize = function () {
if (window.innerWidth < 250) {
image.setAttribute("src", "alternative-image.jpg");
} else {
image.setAttribute("src", "image.jpg");
}
}
Read a bit about the window size properties here.
PS. Do NOT directly use these examples, as they are incomplete and unoptimized. Their only purpose is to mock the use of the resources they reference.

this can be archive in 2 ways.
there is a class in bootstrap V3 img-responsive if you add this class in image tag then it will auto resize when viewport is smaller then image size. Reference : http://getbootstrap.com/css/#images-responsive
OR you can use srcset attribute of image tag
example:
<img src="small.jpg" srcset="medium.jpg 1000w, large.jpg 2000w" alt="yah">
in above example you can set image path in srcset in first parameter and on second is image width. in this Browser auto detect viewport width and based on that it will load image.

Related

Responsive images when image rendering size in relation to screen width is unknown

I have a CMS (TYPO3) which currently outputs plain <img> tags. To make it responsive, I want to add srcset attributes with different size versions of the image.
Which leads us to the problem: With the sizes attribute, I can tell the browser what rendering size to assume when choosing the image version. I can give the rendering size absolutely (in px, em, etc.) or as a percentage of viewport width (in vw). However I cannot tell the browser to assume the image will have its parent's width (in %).
If I knew the parent width beforehand, I could just add it to the sizes attribute, if need be with some media conditions if the parent size changes due to a responsive layout (like Bootstrap columns).
Alas, I'm extending a CMS and have no control over layout or content, like:
the page container width
the number of columns
design breakpoints
column paddings and gutter widths
any nesting of columns within columns
any other paddings
Collecting all this information - just to find out how big the image parent is going to be - is next to impossible.
Any ideas on how I can get a responsive image that delivers the ideal size even though I don't know the final image rendering width (=parent width) at server side (neither in px nor vw)?
Though I prefer static solutions, I'm also open to JavaScript based ideas, given they fallback gracefully.
Edit: My question boils down to: is there some mechanism that can replace the sizes="100%" which is not in the standard "to avoid confusion what it would be relative to"?
Edit:
My current solution is JS-based:
// this, plus some code to prevent image loading before this is executed
$('img[srcset]').each(function() {
$(this).attr('sizes', $(this).parent().width() + 'px');
})
I would like to not have to rely on JS to do this.
Two options:
Use srcset
Your use case is exactly what srcset was designed for. The <source> image sizes are known ahead of time; the container size is known at run time; you define pixel ranges exactly like CSS #media queries to tell the browser which <source> to use for a given container size.
The media query is relative to the viewport, not the container (as with CSS media queries) so you do have to do some math to decide which image you want to use for a container's expected size relative to that viewport. (I believe the reason for this complexity is so you can set images depending on screen density as well, but don't quote me on that.)
The idea is to set the size of the image externally, relative to a container, then use srcset to select an image appropriate for that container's expected size given that viewport size.
(StackOverflow's code snippet makes this difficult to see because it draws the sample inside a fixed-size frame; the most you can see is the image source not changing when you resize the div, which maybe isn't the most compelling demo ever. To try out the viewport resize you'll need to copy the code into a new window).
.container {
border: 1px solid;
width: 50%;
height: 150px;
resize: horizontal;
overflow:auto;
}
<div class="container" resizable>
<picture>
<source media="(max-width: 100px)" srcset="http://via.placeholder.com/100x150">
<source media="(max-width: 200px)" srcset="http://via.placeholder.com/200x150">
<source media="(max-width: 300px)" srcset="http://via.placeholder.com/300x150">
<source media="(max-width: 400px)" srcset="http://via.placeholder.com/400x150">
<source media="(max-width: 500px)" srcset="http://via.placeholder.com/500x150">
<source media="(max-width: 600px)" srcset="http://via.placeholder.com/600x150">
<source media="(max-width: 700px)" srcset="http://via.placeholder.com/700x150">
<source media="(max-width: 800px)" srcset="http://via.placeholder.com/800x150">
<img src="http://via.placeholder.com/10x10" width="100%">
</picture>
</div>
Browser support is currently incomplete (IE and Edge are, as usual, the culprits) but polyfills exist.
Use background-image
...which can be changed using media queries.
#media screen and (min-width: 501px) {
.container {
background-image: url('big.jpg');
}
}
#media screen and (max-width: 500px) {
.container {
background-image: url('small.jpg');
}
}
This is universally supported, but requires that your CMS be able to generate CSS rules along with the HTML.

Get maximum possible size of <img> for ideal crop

I previously posted a similar question but I don't think I illustrated it very clearly.
If I have a basic responsive image such as <img src="http://www.example.com/nicephoto.jpg">
Let's say that nicephoto.jpg is a large image (4000x5000px). I could load the whole image and let it scale or be cropped by the browser as per its own css or the css of its container - but ideally I would like to ask the server to send me a crop of the image that already fits exactly the size I need. EDIT: My question is not how to do the server side cropping - I've got that covered. My question is as follows:
How can I find out what the maximum width and height of the image is until some of the image will be either cut off or the image will be scaled down? In other words, what is the largest practical size that this image should be?
I could always load a massive grey 10000x10000px placeholder image and then use jQuery's .width() and .height() to figure out how much space it actually takes up, but that is hardly efficient or ideal. Is there some smarter way to do this?
Thanks!
EDIT: I do not have control over what methods will be employed to restrict the maximum height or width of a given image. This code will be running on different sites. One site may use css max-height on the image itself. Another may have a set height for a container. I don't know. Either way I need to figure out how big an image can be shown before it begins to be scaled or cropped.
Setting the late update aside for the moment:
It looks like you want to rescale an image on the server to the exact size needed by the client, rather than using CSS to resize the image in-browser. (Note that "crop" and "rescale" are different things; I'm assuming you actually mean "rescale".)
Here's one way to do what you're trying to do:
You do need, ultimately, to check the container's width and height on the client side -- the container size can't be known until page load, as it depends on the user's viewport size.
You can simplify communication with the server by using the image URL itself as a signal for the desired image to be generated. In this example I construct image URLs for placehold.it; you would instead substitute your own serverside script which would catch the url request, extract the desired width and height from the filename, and return the scaled image.
var reloadImage = function() {
var w = $('.container').width();
var h = $('.container').height();
$('.container img').attr("src", "http://placehold.it/"+w+"x"+h);
};
$('.container').mouseup(reloadImage);
.container {
width: 100px; height: 100px;
border: 2px solid;
resize: both; /* Note that not all browser support "resize"; it's just for demo here, not essential to the technique itself */
display: inline-block;
overflow:auto
}
.container img {width: 100%;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Resize this container:<br>
<div class="container"><img class="image" src="http://placehold.it/100x100"></div>
(Note that there is no need to create a "massive" placeholder image as you suggest -- a single pixel image, CSS scaled to 100% width and height, will do. As will no placeholder image at all, of course.)
Here's why you should not do what you're trying to do:
It will defeat browser-side cacheing of the image (since different images may be needed on each load), effectively increasing bandwidth use rather than saving it.
The time spent serverside re-scaling the image will cost more than would have been saved compared to downloading a larger-than-necessary image (or, alternatively, you'd have to cache many different-sized variations on the image serverside to be handed out as needed.)
Resizing the window after load either triggers new image generation (wasting bandwidth and server time) or leads to potentially undersized images. Upscaled too-small images look significantly worse than downscaled too-large ones.
Here's what you should do instead
Create three or four different sized images each somewhat larger than a typical use case (think desktop, tablet, mobile) and use #media queries to choose one based on the screen size. Use in-browser scaling to tweak that selected image to the exact desired size.
.foo {
background:url('foo_default.png') no-repeat 50% 50% fixed;
background-size: cover;
}
#media only screen and (max-width: 400px) {
.foo { background-image: url('foo_small.png'); }
}
#media only screen and (max-width: 800px) {
.foo { background-image: url('foo_med.png'); }
}
#media only screen and (min-width: 800px) {
.foo { background-image: url('foo_large.png'); }
}
But wait, there's an update
I do not have control over what methods will be employed to restrict the maximum height or width of a given image. This code will be running on different sites. One site may use css max-height on the image itself. Another may have a set height for a container. I don't know. Either way I need to figure out how big an image can be shown before it begins to be scaled or cropped.
This complicates things quite a bit more -- now you not only need to detect on the clientside the container width and height, but also need to parse any client CSS that may be affecting the image and altering its displayed size.
You could use window.getComputedStyle() on the image to get the list of applicable CSS rules; determining their effects would be... somewhat complicated. There is a partial implementation of this in an answer to this question, for example, though it only includes a tiny handful of the CSS rules that could affect an image or background image's size -- for a general-purpose solution you'd basically be doing the same work that the browser does to lays out the image in the first place.
It may go without saying that it'd be simpler to just have each site just request an appropriately-sized image in the first place.
You can do this by submitting an ajax request on document request, as well as on resize.
Then store this information to a session. Then return the scaled image via PHP ie:
<img src="image.php?img=someimg.jpg" />
You said you have server side covered so the javascript would look something like this:
$(function() {
function getvp() {
var vp = {
width: $(window).width(),
height: $(window).height()
}
return vp;
}
function submit_vp(vp) {
$.ajax({
method: "POST",
url: "some.php",
data: { vpwidth: vp.width, vpheight: vp.height }
})
.done(function(msg) {
//ajax is done
alert('width: ' + vp.width + ' height: ' + vp.height);
});
}
//Get initial viewport.
$(document).ready(function() {
submit_vp(getvp());
});
//Resubmit viewport on resize.
$(window).resize(function() {
submit_vp(getvp());
});
});
So if I am understanding correctly, you are looking to take an image, and have it resize based on the height and width of the window is that correct?
Check out the JSFiddle I created as an example using % for the height and width. As well as using the background-size: tag, you can select cover or content.
HTML:
<body>
<div class="box1">
<span></span>
</div>
</body>
CSS:
html, body {
height: 100%;
}
.box1 {
background: url(http://cdn.wallpapersafari.com/23/44/2mYJfU.jpg) no-repeat;
height: 100%;
width: 100%;
background-size: cover;
}
This may be a good refrence: CSS3 Background-size
If I'm understanding correctly, you want to be able to find the area for a picture, then scale it using server side (GD Library?) scripting, then display the image?
This is to save bandwidth?
I would probably just use a jquery call to find the width of the screen (or a container if you give the container padding), then with AJAX, send the width dimension to your back-end script.
The back-end script would then find out the aspect ratio of the image in question, apply the multiple of the w:h ratio to the width of the returned number and the ratio of the picture, then scale the image to that size and send it back.
html
<div class="container">
</div>
javascript
var width = $('.container').width();
$.post("back-end-script.php", {width:width}, function(data){
console.log(data); //Do something here with the returned picture
});
graphic backend script (back-end-script.php)
$width = $_POST['width'];
$img = thisimage.jpg;
//Not sure what script you're using, but this is where you'd find the
//img width and height
$img_w = /*image width*/
$img_h = /*image height*/
$img_r = $img_h / $img_w; //This will get a percentage
$new_img_w = $width;
$new_img_h = $new_img_w * $img_r; //This will make the height the right size
/* Then from here, convert your image to the right size and echo it back */
echo $new_img;
Some downfalls of doing it this way: If someone happens to resize their browser, you either have to run a delayed call to get a new image or you'll be stuck with the wrong sized image. Also, you might save more bandwidth if you just came up with 6-10 different image sizes for a responsive web:
<picture class="n-column-image-above__image tnt tnt-image">
<!--[if IE 9]>
<video style="display: none;">
<![endif]-->
<source media="(min-width: 1144px)" srcset="../img/img_retailer_icon_1077.png, ../img/img_retailer_icon_2154.png 2x"/>
<source media="(min-width: 768px)" srcset="../img/img_retailer_icon_707.png, ../img/img_retailer_icon_1414.png 2x"/>
<source media="(min-width: 375px)" srcset="../img/img_retailer_icon_340.png, ../img/img_retailer_icon_680.png 2x"/>
<source srcset="../img/img_retailer_icon_290.png, ../img/img_retailer_icon_580.png 2x"/>
<!--[if IE 9]>
</video>
<![endif]-->
<img src="../img/img_retailer_icon_1077.png" alt="REPLACE WITH IMAGE DESCRIPTION"/>
</picture>

How can I make image responsive?

am using following code to enlarge image on click...
I have tried for media in css..
http://www.frontendwebhelp.com/javascript/thumbnail-popup-to-large-image.php
But I have added one more class in # modalPopupHtml # to adjust size of large image
.imgsize{
height: 600px;
width: 800px;
}
But now I want to make that large image responsive... when I Test that code on mobile view that time it is not working properly... what should I do to make it perfect fit for mobile screen...
Add bootstrap class (class="img-responsive") to the image element
try this
Max-width:100%;
height:auto;
display:block
by define min and max width using #media in css file
#media (max-width: px)
{
.imgsize{ }
}
#meida(min-width :px)
{
.imgsize{}
}
define px size according to your size

How use jQuery to reload 'srcset' image when browser is resized?

This question is a variation of the question here: Is it possible to recalculate the `srcset` image used if browser window is resized?
Basically my site uses a dynamic slider with multiple images, I can only target the image with say a.class img rather than an ID. Further, there are multiple imgs with that a.class to be modified.
How do I use jQuery or regular javascript to get the browser to update to the new srcset when the browser window resizes? Preferably I would like this done only when the window is resized past a a few trigger points, say for example at the width point 1170px and 1000px.
To put the question another way, is there a way to use jQuery to make srcset to function like art direction? I am not able to use the <picture> element or alternatives instead.
So each image is wrapped with the following code:
<div class="carousuel-image slider-full">
<a href="/post-link">
<img srcset="http://test-site.com/wp-content/uploads/2015/12/collage_hk_day_3-216x160.jpg 216w, http://test-site.com/wp-content/uploads/2015/12/collage_hk_day_3-270x250.jpg 270w, http://test-site.com/wp-content/uploads/2015/12/collage_hk_day_3-570x350.jpg 570w, http://test-site.com/wp-content/uploads/2015/12/collage_hk_day_3-1024x1024.jpg 1024w, http://test-site.com/wp-content/uploads/2015/12/collage_hk_day_3-1170x500.jpg 1170w, http://test-site.com/wp-content/uploads/2015/12/collage_hk_day_3-1170x350.jpg 1170w, http://test-site.com/wp-content/uploads/2015/12/collage_hk_day_3-1200x500.jpg 1200w" sizes="(min-width: 1170px) 1200px, (min-width: 1170px) 1170px, (min-width: 1024px) 1170px, (min-width: 570px) 1024px, (min-width: 270px) 570px, (min-width: 216px) 270px, 216px" width="1200" height="500" class="attachment-slider-full tc-thumb-type-thumb wp-post-image wp-post-image v-centered" alt="test-site hk day 3" style="width: 1903px; height: auto; top: -146.5px; left: 0px;">
</a>
</div>
(this code is repeated for multiple sides)
Thanks for the help!
You can use this code inside your window resize event, first u have to declare a array of new image and replace all img src of your slider :
/* defien an array with new image path*/
newsrc[0] = image1 path;
newsrc[2] = image2 path;
newsrc[3] = image3 path;
newsrc[4] = image4 path;
/* find all images inside slider */
$('.carousuel-image').find('a.class').each(function(index, element) {
$(this).find('img').src('newsrc[index]') ;
});
For multiple slider you can wrap above code in slider loop.

CSS3/HTML5 Responsive images

I want to use different sized images depending on the webpage size.
For example, my images has two different sizes:
<img src="images/img1.jpg" data-big="images/img1.jpg" data-small="images/img1small.jpg" alt=""></img>
The data-small image has a width of 100px.
#media (max-width:600px) {
img[data-small] {
content: attr(data-small, url); <-- not working
/*width:10px;*/ <-- this would work
}
}
I testet it on Firefox 37.0.1, Chrome 42.0.2311.90 m and IE 11
If I resize the browser to a very small width (< 600px), the image is still the same.
content attr is used in :before and :after selectror. How ever you can use media query.
<img src="images/img1.jpg" class="big_image" alt="">
<img src="images/img1small.jpg" class="small_image" alt="">
and the css will be
#media (max-width:600px) {
.small_image{ display:block }
.big_image{ display:none }
}
#media (min-width:601px) {
.small_image{ display:none }
.big_image{ display:block }
}
Image tags work using the src attribute. In order to change the image, you need to change the src attribute, which you cannot do with CSS.
content: attr(data-small, url); does not change the src attribute. You're setting the content of the element to the data-small attribute, which does nothing on an img tag. As I mentioned, you cannot change the src attribute with CSS.
I'd advise using srcset. This will gracefully degrade in old browsers, and will work well in new browsers.
<img src="images/img1small.jpg" srcset="images/img1big.jpg 600w" alt="" />
Otherwise, user1936285's solution also works well.
Maybe you can use CSS background-image: url("image.png") instead of <img>
Something like this:
#media (max-width:600px) {
.container{ background-image: url("imagebig.png") }
}
#media (min-width:601px) {
.container{ background-image: url("imagesmall.png") }
}
WebPlatform CSS backgrounds
Use:
content: url(attr(data-small));

Categories