using imgix with html links for retina images

588 views Asked by At

I am using imgix to server my images. They have a great library for serving jpegs at just the right size and pixel density. But it doesn't work when I need to add links to those images.

Here's the fiddle & the code: jsfiddle.net/L95suygs/1/

<style>
...
.feature-img {
    width:23%;
    margin:0 1% .5em;
    height:320px;
    float:left;
    overflow: hidden;
    text-align: center;
    overflow:hidden;
}
@media (max-width:1024px){
    .feature-img {
        width:48%;
        margin:0 1% .5em;
    }
}
@media (max-width:480px){
    .header-img{
        width:100%;
        margin:0 0 .5em 0;
    }
    .feature-img {
        width:100%;
        margin:0 0 .5em;
        height:200px;
    }
}
</style>

<div class="container" id="example1">
    <!-- Header Image -->
    <div class="header-img">
        <img class="imgix-fluid" data-src="//assets.imgix.net/examples/octopus.jpg?fit=crop&crop=faces" >
    </div>
    <div class="feature-img">
        <a href="http://google.com"><img class="imgix-fluid" data-src="//assets.imgix.net/examples/jellyfish.jpg?fit=crop&crop=faces"></a>
    </div>
    <div class="feature-img">
        <img class="imgix-fluid" data-src="//assets.imgix.net/examples/lionfish.jpg?fit=crop&crop=faces">
    </div>
    <div class="feature-img">
        <img class="imgix-fluid" data-src="//assets.imgix.net/examples/clownfish.jpg?fit=crop&crop=faces">
    </div>
    <div class="feature-img">
        <img class="imgix-fluid" data-src="//assets.imgix.net/examples/fin.jpg?fit=crop&crop=faces">
    </div>
</div>
<script type="text/javascript">
var options = {
    updateOnResizeDown : true,
    updateOnPinchZoom : true,
    fitImgTagToContainerWidth: true,
    fitImgTagToContainerHeight: true,
    pixelStep : 10,
    onChangeParamOverride: function(w, h) {
        var dpr = Math.ceil(window.devicePixelRatio*10) /10;
            return {"txt": "w:" + w + " h:" +h + " dpr:" + dpr,
            "txtalign": "center,bottom",
            "txtsize": 20,
            "txtfont":"Helvetica%20Neue,bold",
            "txtclr":"ffffffff",
            "txtpad":20,
            "txtfit":'max',
            "exp":-2
        }
    }
};
imgix.onready(function() {
    imgix.fluid(options);
});
</script>
1

There are 1 answers

0
jayeb333 On

The Short Answer

Add something like the following to your CSS:

.feature-img > a {
    display: block;
    width: 100%;
    height: 100%;
}

This gives a definite size to your <a> tag, so its child image will be sized accordingly.

-- OR --

Change your HTML from this:

<div class="feature-img">
    <a href="http://google.com"><img class="imgix-fluid" data-src="..." ></a>
</div>

to this:

<a href="http://google.com" class="feature-img">
    <img class="imgix-fluid" data-src="...">
</a>

This applies the .feature-img style that's already nicely defined to your <a> tag, rather than applying it to an unnecessary parent <div> and using the <a> tag as a child.

The Long Answer

Marking an image as imgix-fluid means it will always size itself to fit its container's width (and in this case height, since you're passing in fitImgTagToContainerHeight: true).

In your standard case (<img> tag wrapped in a <div>), this behaves exactly as expected. Your <div> tags size themselves properly thanks to your CSS, and imgix.js ensures that the images inside it are the proper size, because you've marked them as imgix-fluid.

However, when you wrap an image in an <a> tag as you've done with the second image in the example, the <img>'s parent container is no longer the handsomely-sized <div>, it's now an <a> with no styling applied to it whatsoever. And, because <a> is an inline element by default, it has no inherent sizing of its own--inline elements size themselves to fit their contents. The <a> sizes itself to fit the <img> inside of it (which has no src attribute, and therefore will be sized to something small but inconsistent from browser to browser), and imgix.js sizes the image inside it to be as small as its parent <a>. It's kind of a chicken-and-egg problem, but it ends in disappointment instead of continuing indefinitely.

As stated above, there are two solutions you could use:

  1. Simply apply some styles to your <a> tag. If you set it to display:block; and set width and height to 100%, the anchor will automatically fill the space created by its parent <div> and consequently imgix.js will size the child <img> appropriately.

  2. Ditch the parent <div> in this case and just make the <a> the container! Replacing the outer <div> with an <a> works perfectly, as long as you give the <a> the feature-img class.

For my money, the second approach seems cleaner and makes more sense.

Hope this helps!