简体   繁体   中英

Responsive images when image width is not proportional to viewport width?

I am using Twitter Bootstrap's responsive grid , and I would like to include some images as part of my page, as follows:

<div class="row">
<div class="span3"><img src="img1.png" /></div>
<div class="span3"><img src="img2.png" /></div>
<div class="span3"><img src="img3.png" /></div>
<div class="span3"><img src="img4.png" /></div>
</div>

However, it is hard to make the images responsive, because with Bootstrap image width is not related directly to viewport width, which rules out eg the Filament approach.

In the example above, on a 1080-pixel-wide screen the images stack so each div takes up less than 25% of the viewport width, and each image only needs to be ~250px wide. However, on an 750-pixel-wide screen, the divs stack vertically to take up 100% of the viewport width, so each image needs to be ~750px wide.

I was thinking I could do something like:

  • By default, load a spacer.gif: <img src="spacer.gif" />
  • On page load, check the width of the image, and load the appropriate size

But then I realised that won't work for non-JavaScript users. I could load a small image by default, but then non-JS users get a bad experience on large screens, and some users will also have to load both the small and large images.

Any recommendations?

If your primary concern is not loading unnecessarily large images on mobile devices, and you're looking for a non-JS option, perhaps you might find something like Sencha.io Src useful. Basically, you route all your images through Sencha:

<div class="row">
  <div class="span3"><img src="http://src.sencho.io/http://yourimageserver.com/img1.png" /></div>
  <div class="span3"><img src="http://src.sencho.io/http://yourimageserver.com/img2.png" /></div>
  <div class="span3"><img src="http://src.sencho.io/http://yourimageserver.com/img3.png" /></div>
  <div class="span3"><img src="http://src.sencho.io/http://yourimageserver.com/img4.png" /></div>
</div>

The Sencha server then checks the user-agent in the HTTP Request Header, and then serves a predetermined size based on the specs they have about the browser.

If you are trying to solve this client-side, you can use PictureFill

Basically, it implements a similar solution to the proposed element in W3C . You would insert the following into your markup (from the example on the PictureFill site):

<div data-picture data-alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
    <div data-src="small.jpg"></div>
    <div data-src="medium.jpg"     data-media="(min-width: 400px)"></div>
    <div data-src="large.jpg"      data-media="(min-width: 800px)"></div>
    <div data-src="extralarge.jpg" data-media="(min-width: 1000px)"></div>

    <!-- Fallback content for non-JS browsers. Same img src as the initial, unqualified source element. -->
    <noscript>
        <img src="external/imgs/small.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
    </noscript>
</div>

The <noscript> avoids the browser having to download a spacer.gif and also serves as a fallback where there is no JS available; the user just gets the small.jpg which would be suitable for older mobiles with javascript disabled.

The (min-width: ...) media queries allow you to choose breakpoints based on device sizes, you can also use (min-device-pixel-ratio: 2.0) for HD devices like Retina displays.

For your purposes, you could set something like:

 <div data-src="image_250x250.jpg"     data-media="(min-width: 1080px)"></div>
 <div data-src="image_750x750.jpg"     data-media="(min-width: 750px)"></div>

And use media queries in your css to make sure the 250x250 images stack.

Hope that helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM