I was checking on my post yesterday, the one about preventing Spam comments in WordPress - and happened to use Safari instead of my normal Firefox. In general I almost always use Firefox since, as a web developer, it’s just easier to code with. It’s more forgiving in general, and more accurate in its interpretation of HTML, CSS, and JavaScript (in my experience) than Safari (and especially more accurately than IE).
When things do seem to go wrong, it is more often in the complicated pieces where I’m trying to use some neat code trick or something. Quite frequently, a trick will work just fine in Browser A but not work at all (or worse, simply work differently) in Browser B. I’m not accustomed to is seeing, however, simple plan-text vanilla-flavored HTML just not be parsed correctly in the first place.
Take, for example, this code:
<div id="quickSummaryfull"> <p class="p6"> <span>  <div class="alignleft">« <a href="http://andyhoffner.com/?p=130"> (Re)Building A Blog-based Website From (Near) Scratch – Part 2</a> </div> <div class="alignright"></div> </span> </p> </div>
This sample is taken from the little backwards/forwards links at the top of each post on this site (the ones with the dotted underline). If you looked at this site in Safari prior to this post, you’d have noticed the formatting of this was off. The links rendered below the dotted line, instead of above it. Why? Safari couldn’t parse the </span> or </p> tags correctly, so it closed the “class p6” item prematurely and threw away my spans entirely.
For the sake of conversation, I’ll simplify the problem down to this (which still causes the bug):
<div id="quickSummaryfull">
<p>
<div>Link to the older post!</div>
<div>Link to the newer post!</div>
</p>
</div>
For the layman, this structure is a “div” (just a containing element, think of it as a box of some size), a “p” (or paragraph element) which contains two more “divs”. In the DOM, it should look like this:
- div #quickSumamryFull
- p
- div – Link to the older post!
- div – Link to the newer post!
- p
This is how it renders in good ol’ Firefox! But in Safari, it renders like:
- div #quickSumamryFull
- p
- div – Link to the older post!
- div – Link to the newer post!
See how the div’s are at the same level as the p? This is why they render below the dotted line, not above it. Safari isn’t doing this without reason, however, if you use Safari’s nifty “Resources” Panel (right click on the offending item, and select “Inspect Element”, you’ll then click Resources, and then the button to Enable it) – you’ll notice two errors:
![]()
From the real code at the start (the one with the spans) it can’t seem to figure out why there is a closing span </span> or closing p </p> element in the code. But there should be – I opened a p and a span just two lines up.
Even if you delete the spans (like in the simplified example) it still can’t make heads or tails of the closing p tag. Why? No idea. It’s not logically complex code – maybe it isn’t perfectly “to spec” (it might be, the million page HTML specification document is only readable, I think, by those who posses some kind of ancient, lost cryptex) but honestly if it not valid, then it should be. There is no logical reason these simple elements should be ‘nestable’. You can nest divs in divs, why not divs in p’s? It also works just fine in Firefox. It also works fine if you change the code to simply use spans instead of divs:
<div id="quickSummaryfull"> <p> <span>Link to the older post!</span> <span>Link to the newer post!</span> </p> </div>
Now Safari can figure this code out. It’s barely different – and frankly I’m now just left unimpressed by the DOM parser built into Webkit.
I’m not the only one to notice some unexpected behavior in how browsers render DOM elements – take this post from Hixie Natural who also noticed some lovely cross-browser inconsistencies when writing the HTML 5 Specification. The conclusion – they pretty much do whatever the hell they feel like, and generally regardless of the specifications. And sometimes, they get lucky.