简体   繁体   中英

How do I style an image with full (100%) width and unknown height so it doesn't pop

I'm building a site where most of the images go full-bleed, that is, they are width:100%. I am having a problem where the images have a height of 0 until loaded which causes the elements of site to jump around a lot.

  • I can't leave it blank because it is 0 until after loading.
  • If I set the height to a pixel value, it doesn't scale correctly.
  • I can't really set it to 100% because that uses the height of the containing element.

Is what I'm trying to do possible? I can think of ways to possibly solve this using javascript after the first image loads, but doesn't seem very elegant.

Help!

<img src="http://lorempixel.com/1280/640/cats/1" id="auto" />
<p>This text will get pushed down after load starts</p>
<img src="http://lorempixel.com/1280/640/cats/2" id="fixed" />
<p>This text will get pushed down after load starts</p>
<img src="http://lorempixel.com/1280/640/cats/3" id="percentage" />
<p>This text will get pushed down after load starts</p>

img { width:100%; }
#auto { height: auto; }
#fixed { height: 640px; }
#percentage { height: 100%; }

JSFiddle

The best you could do is have a wrapper div element which is fluid in the sense that it matches image's aspect ratio.

Like below:

HTML

<div class="image-wrapper">
<img src="http://lorempixel.com/1280/640/cats/1" />
</div>
<p>This text will get pushed down after load starts</p>
<div class="image-wrapper">
<img src="http://lorempixel.com/1280/640/cats/2" />
</div>
<p>This text will get pushed down after load starts</p>
<div class="image-wrapper">
<img src="http://lorempixel.com/1280/640/cats/3" />
</div>
<p>This text will get pushed down after load starts</p>

CSS

.image-wrapper {
    position:relative;
    height:0;
    padding-bottom:50%; /* aspect ratio of the image ( ( 640 / 1280 ) * 100% ; ) */
}
.image-wrapper > img {
    position:absolute;
    top:0;
    left:0;
    width:100%;
}

Fiddle: http://jsfiddle.net/Varinder/m8dFM/1/

If the browser hasn't downloaded the image yet, and you haven't specified the height of image in the img tag, then it has no way of knowing what height to reserve for it in the page.

The best you might be able to do is set a safe min-height on these images to at least minimise the 'pop' when they load.

There are no solutions, here.

There are potential answers, though.

If you loaded a JSON payload of information about each image, and used document.body.getBoundingClientRect().width , then you could use the body's width (or your container's), and the metadata about the image, to reserve that much height.

Of course, you'd have to load that JSON as one of the first things you did on the site (or bake it into the page, or save it as a JS object, in an included file), and you'd have to save the data for every image you intended to use...

...also, rather than showing nothing, you could then show an SVG (which could either stretch non-uniformly, or could be scaled and letterboxed), which, on-load of your intended image (which would be loaded in JS), you could then set the position of the SVG to absolute (at the same point in the page), and start fading it into the background, while crossfading in your image, which would be appended to the DOM, in the space the SVG was occupying...

Or rather than "pop" in, you could have them all slide in, or zoom in... ...or if you wanted to be really annoying, zoom-out...

It might be overkill for something you consider to be a simple problem... ...and it really probably is.

The sad truth is that there are no solutions, but the happy reality is that you can solve slightly-different problems to make the initial problem seem novel.

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