tags:

views:

398

answers:

7

This might be a stupid question but if there's a better or proper way to do this, I'd love to learn it.

I have run across this a few times, including recently, where small spaces show up in the rendered version of my HTML page. Intuitively I think these should not be there because outside of text or entities the formatting of a page's HTML shouldn't matter but apparently it does.

What I'm referring to is this - I have some Photoshop file from the client on how they want their site to look. They want it to look basically pixel perfect to the image in this file.

One of the places in the page calls for a menu bar, where each one does the changing bit on hovering, acts like a hyperlink, etc. In the Photoshop file this is one long bar, so a cheap and easy way to do this is to just split that segment into multiple images and then place them next to each other in the file.

So instinctively I lay it out like so (there's more to it but this is the gist)

<a href="page1.html"><img src="image1.png" /></a>
<a href="page2.html"><img src="image2.png" /></a>
<a href="page3.html"><img src="image3.png" /></a>

and so forth.

The problem is the images have this tiny space between them which is unacceptable since the client wants this thing pixel-perfect (and it just plain looks bad).

One way to get it to render properly is to remove the carriage returns between the images

<a href="page1.html"><img src="image1.png" /></a><a href="page2.html"><img src="image2.png" /></a><a href="page3.html"><img src="image3.png" /></a>

Which makes the images go right up against each other (the desired effect) but it makes the line incredibly long and the code more difficult to maintain (it wraps here in SO and this is a simplified version - the real one has longer filenames and JavaScript sprinkled in to do the hovering).

It seems to me that this shouldn't happen but it looks like the carriage return in the HTML is being rendered as a small empty space. And this happens in all browsers, looks like.

Am I right or wrong for thinking the two snippets above should render the same? And is there something I'm doing wrong? Maybe saving the file with the wrong encoding? Should I make every one of these links a perfectly positioned CSS element instead?

+13  A: 

The whitespace (carriage return included) is usually rendered as space in all browsers.

You need to put the elements one after another, but you can use a trick:

<a href="page1.html"><img src="image1.png" 
/></a><a href="page2.html"><img src="image2.png" 
/></a><a href="page3.html"><img src="image3.png" 
/></a>

This also looks a little ugly, but it's still better than one single line. You might change the formatting, but the idea is to add carriage returns inside the elements and not between them.

rslite
Nice answers guys, I never thought to do this!
Chris Marasti-Georg
It is better than one single line, I should try this.
TonyOssa
+2  A: 

That's part of the HTML specification - the spaces are in the markup so they're considered part of the document.

The only other options you've got, since you dislike the formatting, is to break the html tags:

  <a href="..."><img src=".." /></a
  ><a href="..."><img src=".." /></a
  ><a href="..."><img src=".." /></a

which is undesirable in my opinion, or create the html dynamically - either via JavaScript or using a templating system and dynamic html.

Kyle Burton
Nice answers guys, I never thought to do this!
Chris Marasti-Georg
+7  A: 

I don't know if this is general enough for your page, but you could class these particular a tags and float them all left, then they'll bunch together no matter how your HTML is formatted.

<style>
    a.together {
        float:left;
    }
</style>

<a class='together' href="page1.html"><img src="image1.png" /></a>
<a class='together' href="page2.html"><img src="image2.png" /></a>
<a class='together' href="page3.html"><img src="image3.png" /></a>
Adam Bellaire
You can't float inline elements. You would have to use "display:block" as well.
Dan Udey
I accepted an answer on this but I like that there's people coming up with imaginative workarounds. Thanks!
Schnapple
@Dan: Hmm, I tested this in FF3 and it worked no problem, maybe it's a standards compliance issue with FF.
Adam Bellaire
+2  A: 

The reason is simple: In HTML white space matters, but only once. Repeated white space is ignored, only the first is shown.

The only reliable way to avoid this is, as you did, by putting no white space between elements.

When table based layout would be less out than it is currently, you could use a zero-border, zero padding table to align your elements while having them on separate lines in the source code.

Tomalak
+1  A: 

If you're going to do a tabbed interface on a website, take great pains to do it properly, and it will be worthwhile. There are many websites with great examples of CSS tab implementations. Consider using one of them.

This one has a lot of CSS+Javascript/AJAX tabs. Or see this set of simple CSS examples (some styled). Finally, check out this actually-pretty-cool tabs generator.

Dan Udey
+2  A: 

The behavior you demonstrated above is true as the browser treats carriage returns as a space. To fix it, you can style it like so with:

a { display: block; float: left; }

Please note that the above rule applies it to all links, so you might want to narrow the selector to certain elements only, ie:

#nav a { display: block; float: left; }
Kevin Chan
+2  A: 

The way I handle this is to use an unordered list, and make each image/link an item. Then use CSS to display each item inline and and float them to the left.

This will give you a lot more flexibility and make the markup very readable.

mrinject