In Bug 928074 I thought Gecko had a bug with display: table-cell
elements wrapped by <a>
elements. In a nutshell, you couldnβt click or tap anywhere in the full width of Google Plus Mobileβs menuβit had to be exactly on top of the menu item text for anything to happen.
But I was wrong, turns out.
Daniel Holbert gets credit for finding the actual bug and kindly explaining it to meβIβm just writing it up so I can commit some of this to memory.
Per the CSS 2.1 spec, implementations should generate anonymous table elements around elements with CSS table model display values (if needed). In the case of the Google Plus menu, display:table-cell
elements parented by an <a>
like so:
<li> <a> <div>Home</div> </a> </li>
The <div>
requires an anonymous table-row box (βanon-trβ) parent, and finally an anonymous table box to wrap that. Thereβs two kinds of table boxes you can end up with: table and inline-table (βanon-itβ), determined by the parent of βHomeβ. In this case, βHomeββs parent is an <a>, which is by default an inline box. So you should end up with something like this:
<li> <a> ββββββββanon-itββββββββ β ββββββanon-trββββββ β β β <div>Home</div> β β β βββββββββββββββββββ β βββββββββββββββββββββββ <a> </li>
In Gecko, Presto, and IE, this is the (correct) result:
βββββββββββββββviewportβββββββββββββ β<li> β ββββββββββββββββ β ββ<a>clkbl areaβ β ββ <div></div>β β ββ</a> β β ββββββββββββββββ β β<li> β ββββββββββββββββββββββββββββββββββββ
Not very usable. In fact, the bug reporter assumed that it was broken becuase they failed to click exactly on the width of the link text.
WebKit and Blink browsers have bugs, it turns out, where they generate a table box, rather than an inline-table box so the <a>
expands to the entire width of its parent <li>
and is clickable.
βββββββββββββββββviewportβββββββββββ β<li> β ββββββββββββββββββββββββββββββββββββ ββ<a> clickable area ββ ββ <div></div> ββ ββ</a> ββ ββββββββββββββββββββββββββββββββββββ β<li> β ββββββββββββββββββββββββββββββββββββ
If you find yourself in a similar situation, the simplest fix is to add an explicit display: block
to the wrapping <a>
element and it will work as expected in all browsers.