Posts Tagged ‘html’

DOM You Safari!

Thursday, September 10th, 2009

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>&nbsp
               <div class="alignleft">&laquo; <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!

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:

Safari DOM 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.

-Andy

(Re)Building A Blog-based Website From (Near) Scratch – Part 1

Monday, August 24th, 2009

Part 1: We Start With The Head

When I first started testing layouts for the website – I saw a common theme to most sites. Basically, they would have a static header image, with a fixed size. It didn’t matter if you had a browser window 2000 pixels wide or 20, they usually just centered or justified the image. I wanted my site to be much more dynamic, to feel customized to users on tiny iPhone or a massive HDTV. This meant that the body would be about 80% of the screen width, no matter what the width was.

This meant the header image needed to also be scalable. I couldn’t just dump in a single image, it wouldn’t scale up (or down). So I decided the best thing was to make on with a distant left and right side, and just a centered span with a gradient and my name. This way, items would “stick” to their side, and scale with the window, but it would always appear the correct proportion.

To accomplish this, I would need to separate the header into three basic (and obvious) sections: left, right, center span. I used Photoshop to draft images for each of these elements. I then used 4 divs with the images as the background (left, right, center gradient, center logo text). If you load a page with these divs, they default to being on their own line.

You can eliminate the line breaks by adding “style=’display:inline;’” to the div elements, but that still just puts them one next to another. I needed to layer these divs, which means I need to manually adjust positioning. Absolute wasn’t an option, since I wanted the width to be a function of the containing element, not of the window at large. My first idea was to simply nest them. This works – the layers will stack up nicely – BUT the transparency channel won’t render properly. Since there were ‘partially transparent’ pieces in the headers, like the edges of the leaves, they were dependent on the dark grey background for color. When they were right up against the dark background, it properly bled through to the leaves. If it was layered on top of another transparent images, it didn’t bleed through to the dark background. The images looked lighter and pixellated when stacked in nested divs.

So nesting transparent divs isn’t an option. They would have to be placed on the same level to get the right bleed-through effect with the dark background. The trick was relative positioning. Since each image’s height is fixed, I could just use negative coordinates to move the images up on top of one another.

This let me snap the widths to the containing element and keep them on the same level in the HTML, but place them perfectly on top of one another. The result is rather crude, but effective, as you can see in the header above.

-Andy