Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Positioning problems in Firefox? position:relative for a display:table element

i'm experiencing the weirdest positioning problem that appears only in firefox.

My HTML:

<article id="one" class="layer"></article>
<article id="two" class="layer"></article>
<article id="three" class="layer">
   <div class="left"></div>
   <div class="right"></div>
</article>

My CSS:

html, body {
  margin: 0; padding: 0;
  height: 100%;
  width: 100%;
}

article.layer {
  position: relative;
  display: table;
  height: 100%;
  width: 100%;
}

article .left, article .right {
  position:absolute;
  width: 50%;
  height: 100%;
  min-height:100%;
  display:table;
}

article .left { left: 0; top: 0; }
article .right { left: 50%; top: 0; }

So each article is set to display:table and 100% width and 100% height. The body and html is also 100% wide and high. Therefore each article is exactly the size of the current browserwindow.

Notice that each article.layer is set to position:relative.

The latest article has two divs in it positioned absolute so one is positioned to the left and one to the right.

This works fine in all browsers, except in Firefox. In Firefox the div.left and div.right of the last article are shown on top and overlay the first article …

Here is a live demo: http://jsbin.com/ubulot/edit#preview Test it in Firefox and you see the problem. I have FF 9.0.1 installed on my Mac.

Any idea what I'm doing wrong here?

like image 280
matt Avatar asked Jan 21 '12 09:01

matt


2 Answers

I'm using display:table myself. It's a work-around for certain layout issues that display: block fails to sufficiently deal with. The rationale is lengthy and I'm not going into it here.

This is a consequence of the current HTML 4/5 specification not defining certain behaviors with regards to the "display: table{-x};" and positioning.

From the book "Everything You Know About CSS Is Wrong" BY Rachel Andrew & Kevin Yank:

A common practice when dealing with positioning within a block element is to create a new positioning context by setting the position property of the block element to relative. This allows us to position elements within the block, relative to its top, right, bottom, or left. However, when setting position: relative; on an element that also has a table-related display value specified, the positioning is ignored. This behavior has previously been documented by Alastair Campbell, who points out in his article that the CSS 2.1 spec is not clear on what browsers should do when an element displaying as a table element is relatively positioned:

The effect of position: relative on table-row-group, table-header-group, table-footer-group, table-row, table-columngroup, table-column, table-cell, and table-captionelements is undefined.

This behavior is, in my opinion, the biggest problem with using CSS tables for layout...

Apparently Mozilla simply ignores any attempt to establish a positioning context using CSS table elements.

The same reference continues with two suggestions:

There’s no straightforward approach to fixing this problem using CSS tables, but we can take one of two simple approaches to provide a positioning context: add a positioned child block element to the cell, or wrap the table in a positioned element.

There is no elegant solution to this one. It requires a case-by-case evaluation of the issue and a tailored workaround. :(

In your case you might as well leave off the "position: relative" out of your "Layer" class. It's meaningless to Firefox.

Since you've created the "Layer" class as a table, simple make each of the s in the last instance "display: table-cell;".

so your CSS can be done thus:

.Layer:last-of-type > div
{
display: table-cell;
/* Other formatting here. */
}
like image 50
Richard Robertson Avatar answered Sep 30 '22 11:09

Richard Robertson


If you change display:table to display:block throughout, it renders fine as you can see here. Is there a reason you're using display:table?

like image 32
magicalex Avatar answered Sep 30 '22 12:09

magicalex