0

CSS:

.layers {
    position: relative;
    height: 500px;
    width: 500px;
    /* Some -webkit and -moz transformations */
}
.layers > div {
    position: absolute;
    height: 500px;
    width: 500px;
 }
.item {
    position: absolute;
    width: 5px;
    height: 5px; 
}

HTML:

<article class="someclass">
    <section class="layers">
       <div style="/* -webkit and -moz transformations */">
           <img src='image.png'>
           <div class="item" style="/* -webkit and -moz transformations */">test</div>
       </div>
    </section>
</article>

When loading this page, I get image.png with test on top of it 90% of the time.

(exact position depends on the transformations) The other 10% of the times I try loading the page, the item div is loaded as if the position is static which causes it not to be on top the the image.

My best guess is that it has something to do with what what gets loaded first, so there might not be an exact answer, but maybe there is something else I'm forgetting here.

Note: I tried this on Chrome and Safari, both the same results.

Laurent
  • 1,292
  • 4
  • 23
  • 47
  • A fiddle would help debug this. What transformations are you applying? – Kerry Liu Feb 22 '14 at 15:58
  • 1
    I've put a [start at a fiddle here](http://jsfiddle.net/rY2DF/); without the transforms I can't see why "test" would ever be on top of (i.e. overlaid on) the image -- the position is absolute, but no top/bottom/left/right is given, so the position [defaults to the static values](http://stackoverflow.com/questions/10243991/position-absolute-without-setting-top-left-bottom-right), right? But without enough code to reproduce the problem, we're just going to be guessing. – Matt Gibson Feb 22 '14 at 16:06
  • I have made a fiddle as well, same result: http://jsfiddle.net/WTnen/ Everything will load as expected but when enabling jQuery (2.x) onLoad, the label will not be on top the the images `after clicking run a few times`... – Laurent Feb 22 '14 at 16:15
  • It seems to occur when a script (Like jQuery) or a large image needs to be loaded... – Laurent Feb 22 '14 at 16:26
  • I still don't see which part of your code you're expecting to put the "test" on top of the image? Without the transforms, the text should be below the image. The transforms move it further down and left. (If I add `left: 0;` and `top: 0;` to the `.item` [as in this edited Fiddle](http://jsfiddle.net/WTnen/2/), does that do what you're expecting? (And I can't see why setting the fiddle script to run onLoad would make a difference, when there's no JavaScript in the JavaScript box...) – Matt Gibson Feb 22 '14 at 16:33
  • Enabling the script onLoad was simply to add some loading time, but it looks like I have simply forgotten the `left: 0; and top: 0;`, stupid me -_- – Laurent Feb 22 '14 at 16:40
  • 1
    I *think* the behaviour you're seeing is because the image is sometimes taking a while to load, so the default static position of the `.item` element is at the top of the div. Possibly because you're declaring it absolute, those values aren't recalculated when the image is finally loaded. Not sure I can prove that, though :) I think you might *always* see the "problem" if you add dimension attributes to the image: http://jsfiddle.net/WTnen/4/ – Matt Gibson Feb 22 '14 at 16:43
  • @MattGibson if you set a width and height to the image you'll see the items consistently below the image, regardless of how long the image takes to load. – Kerry Liu Feb 22 '14 at 16:46
  • @KerryLiu Indeed; that's what I was proving with that last fiddle. I've now answered this question with my theory as to what's going on, which I think makes sense. – Matt Gibson Feb 22 '14 at 16:52

1 Answers1

1

The inconsistent behaviour is due to two things: one, you've not set the actual position (e.g. top/left) for the .items, and two, your image has no dimensions specified, so its size won't be known by the browser until it's loaded.

Because you haven't specified a position, but have specified absolute positioning, the .item elements are defaulting to the values they would have if they were statically positioned. That is, they'll be directly below the image.

I believe that when you're seeing the .items below the image, that's because the image is in your cache, so the browser knows how big it is on its initial layout run, and sets the static position of the .items below the image.

When you're seeing the .items on top of the image, that's because the browser hasn't worked out how big the image is on its initial layout run (i.e. it's still loading) so it positions the .items as though the image has zero height. Usually, once the image was loaded, the layout would be recalculated, and the .items would move down, but because you've specified their positioning as absolute, I believe the browser is assuming it doesn't need to reposition them, as the image size shouldn't affect their positioning, because they've been taken out of the normal layout flow.

Anyway. Specify an actual position for your absolutely-positioned elements, and everything should start working.

Community
  • 1
  • 1
Matt Gibson
  • 37,886
  • 9
  • 99
  • 128