2

Situation

html:

<div class="container">
   <div class="parent">
      <div class="child">x</div> 
   </div>
</div>

css:

.container {
   display: table;
}

.parent {
   display: table-cell;
   position: relative;
}

.child {
   position: absolute;
   right: 0;
}

What I expect:

the .child should be positioned to the right edge of .parent. Works in Chrome.

What I get in Firefox:

the .child is positioned to the right edge of the closest "non static" parent which is has not display: table-cell.

Fiddle

http://jsfiddle.net/SYG5k/2

Question

Why does display: table-cell influence the positioning of child elements, or, why is position: relative ignored on table-cell elements? Can I work around this if I rely on table-cell?

Hemerson Varela
  • 24,034
  • 16
  • 68
  • 69
Roman
  • 5,888
  • 26
  • 47
  • `position: absolute forces display: block` [related question](http://stackoverflow.com/questions/8896965/css-vertical-align-table-cell-dont-work-with-position-absolute#8897198) & [w3.org article](http://www.w3.org/TR/CSS2/visuren.html#dis-pos-flo) – Ron van der Heijden Jul 15 '13 at 15:09
  • @Bondye, but I set `position: absolute` only on the child element where `display: block` is actually what I want. – Roman Jul 15 '13 at 15:15

4 Answers4

2

Add a wrapper to your absolute element and make it relative, so you will have something like table-cell > relative wrapper > absolute element

http://jsfiddle.net/SYG5k/13/

<div class="rel">
    a 
    <div class="absolute">x</div>
</div>

.foo, .rel {
    position: relative;
}

This is a work around I can't explain why it doesn't work normally. Perhaps someone else will answer that for you

Edit : my mistake the wrapper is supposed to wrap everything in the cell, it's what I originally wanted to code, more of a typo. I updated the fiddle above

Huangism
  • 16,278
  • 7
  • 48
  • 74
  • unfortunately using a wrapper f*cks up if there is more than 1 absolute child: http://jsfiddle.net/SYG5k/6/ – Roman Jul 15 '13 at 15:18
  • what do you mean? I see the b at the top. Can you explain please, I viewed it on latest FF on mac – Huangism Jul 15 '13 at 16:00
2

You need to put position: relative; in your parent.

So in the code in your question add position: relative; to .container

Or in your jsfiddle add position: relative; to .parent

.parent {
    height: 150px;
    width: 450px;
    display: table;
    margin-top: 400px;
    background: #bbb;
    position:relative;
}

Related : Firefox ignores absolute positioning in table cells and Positioning context on table-cell element in Firefox

About your questioning 'why' : It's no more a 'block' level element. It's a table-cell so positioning will behave in a different way (in this case, with firefox).

See this to understand deeper about 'tables' behaviors

http://jsfiddle.net/SYG5k/12

Community
  • 1
  • 1
Ron van der Heijden
  • 14,803
  • 7
  • 58
  • 82
0

A work around may be to use an inner div with a width and height of 100%, and set that to position:relative;

HTML:

<div class="parent">      
<div class="cell foo">
    <div class="cellInner">
        a
        <div class="absolute">x</div>
    </div>
</div>

CSS:

.cellInner{
position:relative;
width:100%;
height:100%;
}

Updated JS Fiddle: http://jsfiddle.net/SYG5k/11/

Ben
  • 903
  • 1
  • 9
  • 13
  • I might point out that Huangism's method does not entirely solve the issue, as it displays differently to your original example.The x is now slightly below the a. The wrapper needs to wrap around all of the content inside the .parent div. – Ben Jul 15 '13 at 15:11
  • This method also has no issues with more than one absolutely positioned element. – Ben Jul 15 '13 at 15:27
0

I was adding a popup menu that appears on each row of the table as the user mouses over it when I ran into this FF problem. Based on the very useful info above, I ended up putting a div wrapper inside the table cell in each row where I wanted my absolutely positioned popover menu to located, and set its display property to relative. My JS then adds the absolutely position menu inside the div as each row is rolled - it has to be a child of the the relatively positioned div, of course. Note that the div will shrink-wrap the td's content rather than filling the td as I expected, but no matter, you then have a relative context, and you can use top and left on the absolutely positioned child element to locate it exactly where you want it with respect to the table cell.

Charles Wyke-Smith
  • 2,479
  • 3
  • 17
  • 16