Remember image maps, and how they kinda sucked?

I was thinking about images maps some time ago and how they might be useful today. Might. Kinda… Ok, not really.

Anyway, I got to thinking that it would be pretty easy to get them going in a ‘static’ size format, since you could just have a div with a background image, and then come containers inside as links for the different zones. Building it would suck hard (depending on how complex you wanted to get), but it would probably be a ton more portable that the old “cut+slice a table” in Photoshop 5.5 routine.

So… that’s not too difficult, just tedious.

But what if you wanted the linked-out image to have a variable size? You know, all responsive like? To have an image, that would scale to fill a <div>, while maintaining it and its contained links height to width ratio? That would be interesting indeed.

Let’s break it up into parts. Ok, so we can make an image (let’s say 523px by 323px) into a cleanly scaling element by doing a..

img {
width: 100%;
max-width: 523px;
}

(giving us this)

the-farm

Sho’nuff, that makes an image that will expand to fill a < div >, but won’t exceed its native pixel size. If you don’t define a height for one side of an image, then the browser will scale it proportionally by default. Sweet. But how does that help us? Are we going to chart out a bunch of mini-div’s on top of an image using fixed positioning? No, that would be quite useless.

So let’s make us a <div> that scales in much the same way. How hard can it be? All we have to do is have…

div {
width: 100%;
max-width: 523px;
height: ???
}

That’s not quite right, since if we assign a pixel value, it will be a set figure that won’t scale. We can’t do a percentage because it will measure the containing <div>. Not cool. So what can we use as a ‘local mechanic’ on the <div>? Well, we might try and use ‘padding-top’, but then again thee is no defined height…. so 50% of what?

The trick here is to use an :after psuedo-class on our div, while declaring that the <div:after> is a block element. We will declare that the < div > will be a self collapsing container, and then assign a local, relative measurement of an aspect ratio. The aspect ratio is the height of the image divided by the width. In our case, by doing 323/523=0.617591, or, 61.7591%. When we stick that 61.7591% into the :after psuedo-class’s padding-top, we get a box with the exact same ratio of height to width, because the bottom is being pushed down by the correct percentage of the width. No pixels required.

div {
width: 100%;
max-width: 523px;
position: relative;
background: #333;
}
div:after{
padding-top: 61.75%;
display: block;
content: "";
}

which gives us a div like so:

Exciting, eh? What makes it interesting is that if you adjust your browser size, the box will follow your lead, and resize appropriately while maintaining the same ratio of width v. height. Of course, seeing that this <div>’s contents happens to be padding….

We gotta get some empty space in there to fill it up. ¬†Luckily, that’s pretty damn easy. ¬†We just have to define the position of the asides of a contained div, but isn’t affected by the paddings buffer, and throw in our background image so that it covers the entire div…

section {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: url(http://www.cssjs.net/wp-content/uploads/2013/01/the-farm.jpg);
overflow:hidden;
background-size: cover;
background-repeat: no-repeat;
}

And there we go. We have a fully flexible, empty div ready to be filled up with transparent, linked content.
Like this.

Super Snazzy Fullscreen Version Here