CSS Positioning Absolute within table cells not wo

2019-02-21 16:32发布

I cannot figure out this positioning problem in Firefox. It doesn't seem to follow the absolute positioning rule. Is there something I'm doing that shouldn't be done, but some browesers handle it and some don't?

JS Fiddle:

Original - http://jsfiddle.net/g9qzh/

Updated - http://jsfiddle.net/g9qzh/2/

Works in IE, Chrome, Safari, Opera

Here's the actual code. Let me know if I'm not following some kind of standard I don't know about.

HTML:

<table>
    <tr>
        <td>
            <div id="three">Three</div>
            <div id="two">Two</div>
        </td>
    <tr>
    <tr>
        <td>
            <div id="three">Three</div>
            <div id="two">Two</div>
        </td>
    <tr>
</table>

CSS:

#two {
   position: absolute;
   top: 0;
}
td {
   position: relative;
}

​My only clue is that there is some other value that I should assign to td that would cause it to work. Some other stackoverflow questions have mentioned Firefox misbehaving with this, but I haven't been able to find an answer. I tried assigning both top and left values of zero, but FF won't budge. ​

7条回答
姐就是有狂的资本
2楼-- · 2019-02-21 17:21

In case you want to position stuff at the top and bottom of a cell, also in Firefox, I made it work doing the following mix of CSS and (unfortunately) jQuery.

  1. Use a wrapper div (div.inner) inside your td which has position=relative style in the td. Inside the wrapper I added 2 divs which are to be positioned at the top and bottom of the cell. enter image description here

  2. Positioning at the top (class=interval-start) is for free, via CSS positioning.

  3. Positioning the div.interval-end at the bottom is done via script, which adds the styling shown in the picture. With variable td-heights and the wrapper div being 0-height by default, you need a way to tell the element how far it should go to the bottom. The script is as follows:

            $("table .inner .interval-end").each(function () {
                $(this).css({top: ($(this).parent().parent().height() - 10) + "px"})
            }).show()
    
  4. I initially made the div.interval-end invisible, set the 'top' style, and then made it visible via jQuery show().

Hope this helps anybody trying to achieve the same. Let me know if there are better methods out there, specially if these methods do not require scripting. BTW: I tried setting the height style of the wrapper div.inner, but it messes with the table layout in Firefox.

查看更多
再贱就再见
3楼-- · 2019-02-21 17:25

There are legitimate reasons to use CSS display: table styling. It eliminates issues that display: block and display: inline-block do not address. These reasons occupy an entire chapter of a book on CSS styling so I won't go into them here. That same book also describes the problem of positioning within items with that display type. CSS 2.1 specs simply don't address the issue and Mozilla has chosen a course that ignores attempts to create a positioning context with those elements. CSS-table positioning is well established, mature methodology, and not "dodgy" - it just takes understanding of its limits - just like any other CSS element. For liquid layouts and other layouts where element size is variable or unknown it's indispensable for vertical spacing and positioning.

One suggestion in this thread has been presented - create a div within the "table-cell" element set to position: relative and use that for the positioning context. The other method is to embed another CSS table within that cell and use it to position elements within a grid. The third method is to wrap your CSS table within another item that creates a positioning context.

查看更多
太酷不给撩
4楼-- · 2019-02-21 17:29

The problem comes from how FF renders tables. If you set your TDs to display:inline-block; it should display correctly.

查看更多
叛逆
5楼-- · 2019-02-21 17:35

Change ID's to classes and also displaying it as blocks fixes it:

http://jsfiddle.net/GchWZ/

It is better and more "proper" to user an inner div though as quoted from this stack overflow post: Does Firefox support position: relative on table elements?

<td>
  <div style="position:relative">
      This will be positioned normally
      <div style="position:absolute; top:5px; left:5px;">
           This will be positioned at 5,5 relative to the cell
      </div>
  </div>
</td>
查看更多
聊天终结者
6楼-- · 2019-02-21 17:37

Aside from the duplicate ID issue noted by Brandt, assigning positioning to table cells is dodgy at best - I'm surprised it works in any browsers. If you must use a table, wrap the elements you want to position in a div and assign the wrapper div position: relative:

<table>
    <tr>
        <td>
        <div class="wrapper">
            <div id="three">Three</div>
            <div id="two">Two</div>
        </div>
        </td>
    <tr>
</table>

CSS

#two {
   position: absolute;
   top: 0;
}
.wrapper {
   position: relative;
}
查看更多
Bombasti
7楼-- · 2019-02-21 17:38

You are using IDs

IDs are unique. Use Classes if you want to reuse a style assignment.

查看更多
登录 后发表回答