tags:

views:

14990

answers:

6

I'm a beginning rails programmer, attempting to show many images on a page. Some images are to lay on top of others. To make it simple, say I want a blue square, with a red square in the upper right corner of the blue square (but not tight in the corner). I am trying to avoid compositing (with ImageMagick and similar) due to perfomance issues.

I just want to position overlapping images relative to one another.

As a more difficult example, imagine an odometer placed inside a larger image. For six digits, I would need to composite a million different images, or do it all on the fly, where all that is needed is to place the six images on top of the other one.

+3  A: 

The easy way to do it is to use background-image then just put an <img> in that element.

The other way to do is using css layers. There is a ton a resources available to help you with this, just search for css layers.

Chris Bartow
+11  A: 

This is a barebones look at what I've done to float one image over another.

<style type="text/css"> 
.imgA1 { position:absolute; top: 25px; left: 25px; z-index: 1; } 
.imgB1 { position:absolute; top: 25px; left: 25px; z-index: 3; } 
</style>

<img class=imgA1 src="http://full.path.to/imageA.jpg"&gt;
<img class=imgB1 src="http://full.path.to/imageB.jpg"&gt;

Source

Espo
+6  A: 

Here's code that may give you ideas:

<style>
.containerdiv { float: left; position: relative; } 
.cornerimage { position: absolute; top: 0; right: 0; } 
</style>

<div class="containerdiv">
    <img border="0" src="http://stackoverflow.com/Content/Img/stackoverflow-logo-250.png" alt=""">
    <img class="cornerimage" border="0" src="http://www.gravatar.com/avatar/" alt="">
<div>

I suspect that Espo's solution may be inconvenient because it requires you to position both images absolutely. You may want the first one to position itself in the flow.

Usually, there is a natural way to do that is CSS. You put position: relative on the container element, and then absolutely position children inside it. Unfortunately, you cannot put one image inside another. That's why I needed container div. Notice that I made it a float to make it autofit to its contents. Making it display: inline-block should theoretically work as well, but browser support is poor there.

EDIT: I deleted size attributes from the images to illustrate my point better. If you want the container image to have its default sizes and you don't know the size beforehand, you cannot use the background trick. If you do, it is a better way to go.

buti-oxa
A: 

Inline CSS only for clarity here. Use a real stylesheet.

<!-- First, your background image is a DIV with a background 
     image style applied, not a IMG tag. -->
<div style="background-image:(url=YourBackgroundImage);">
    <!-- Second, create a placeholder div to assist in positioning 
         the other images. This is relative to the background div. -->
    <div style="position: relative; left: 0; top: 0;">
     <!-- Now you can place your IMG tags, and position them relative 
          To the container we just made -->  
     <img src="YourForegroundImage" style="position: relative; top: 0; left: 0;"/>
    </div>
</div>
FlySwat
A: 

@buti-oxa: Not to be pedantic, but your code is invalid. The HTML width and height attributes do not allow for units; you're likely thinking of the CSS width: and height: properties. You should also provide a content-type (text/css; see Espo's code) with the <style> tag.

<style type="text/css"> 
.containerdiv { float: left; position: relative; } 
.cornerimage { position: absolute; top: 0; right: 0; } 
</style>

<div class="containerdiv">
    <img border="0" src="http://www.gravatar.com/avatar/" alt="" width="100" height="100">
    <img class="cornerimage" border="0" src="http://www.gravatar.com/avatar/" alt="" width="40" height="40">
<div>

Leaving px; in the width and height attributes might cause a rendering engine to balk.

Sören Kuklau
Thanks, fixed.Actually, I deleted the content-type I had is my test code before posting as un unnecessary detail. Style declaration should be inside <head> anyway and so on. Maybe I should have leaved it there.
buti-oxa
+1  A: 

Ok, after some time, here's what I landed on:

<div style="position: relative; left: 0; top: 0;">
  <img src="a.jpg" style="position: relative; top: 0; left: 0;"/>
  <img src="b.jpg" style="position: absolute; top: 30; left: 70;"/>
</div>>

As the simplest solution. That is:

Create a relative div that is placed in the flow of the page; place the base image first as relative so that the div knows how big it should be; place the overlays as absolutes relative to the upper left of the first image. The trick is to get the relatives and absolutes correct.

rrichter