13

Take a look at the following fiddle:

http://jsfiddle.net/DNhAk/14/

When you have an image with text wrapped in an anchor/link, the whitespace between the image and the text in the code creates a underlined whitespace in the rendered page right before the text.

When there is no image, there is no underlined whitespace even though there is whitespace in the code.

The only way I can see the avoid this underlined whitespace is to eliminate the whitespace in my code. But I hate altering my coding style in order to alter the presentation of the rendered page. Anyways, altering your HTML in order to manipulate the presentation of a page is wrong anyways. It's like using line breaks (<br/>) to add space between elements instead of using CSS.

Is there a not-so-obvious-to-me CSS property that is used to fix this issue?

UPDATE For some reason people are getting hung up on the image borders and margin that I had in the code. I only put them in there to make it look nice. They have nothing to do with the problem, so I removed them and updated the fiddle just so people can understand more clearly what the problem is.

Jake Wilson
  • 88,616
  • 93
  • 252
  • 370
  • possible duplicate of [Ignore whitespace in HTML](http://stackoverflow.com/questions/2628050/ignore-whitespace-in-html) – mrtsherman Apr 17 '12 at 18:07
  • They all have underlined white space when I look at them in Chrome. – Diodeus - James MacFarlane Apr 17 '12 at 18:07
  • @Diodeus - he is specifically referring to the first example. You can see how the underline extends slightly before the `U`. I agree that this would drive me crazy because he is creating easy to read html and being punished by his layout changing on him. – mrtsherman Apr 17 '12 at 18:08
  • It's not quite a duplicate as `white-space-collapse: discard;` doesn't seem to have an effect in this situation. – Jake Wilson Apr 17 '12 at 18:56
  • @Jakobud - if you read the answers there you would see that `white-space-collapse: discard;` hasn't been implemented yet by any browsers (which is why it didn't work). The latest spec has now renamed this to `text-space-collapse:trim-inner` (still not implemented). That SO question also gets into the guts of why this happens and ways to code around it (all of which seem to suck). So I would agree that it doesn't solve your problem, but I still think it is a duplicate. – mrtsherman Apr 19 '12 at 04:10
  • Oh lol I was wondering about that. Thanks – Jake Wilson Apr 19 '12 at 15:14

8 Answers8

14

You could set the CSS for the a element like this:

a {
    display: inline-block;
}
Bart Verkoeijen
  • 16,545
  • 7
  • 52
  • 56
Rohit Azad Malik
  • 31,410
  • 17
  • 69
  • 97
7

You can emulate the effect with some CSS:

img {
    border: 1px solid #CCC;
    padding: 10px;
    vertical-align: middle;
    float:left;
}

a {
    display:block;
    height:70px;
    line-height:70px;
}

http://jsfiddle.net/DNhAk/8/

AlienWebguy
  • 76,997
  • 17
  • 122
  • 145
3

The behavior you are experiencing is part of the spec ( http://www.w3.org/TR/html401/struct/text.html ) :

For all HTML elements except PRE, sequences of white space separate "words" (we use the term "word" here to mean "sequences of non-white space characters"). When formatting text, user agents should identify these words and lay them out according to the conventions of the particular written language (script) and target medium.

This layout may involve putting space between words (called inter-word space), but conventions for inter-word space vary from script to script. For example, in Latin scripts, inter-word space is typically rendered as an ASCII space ( ), while in Thai it is a zero-width word separator (​). In Japanese and Chinese, inter-word space is not typically rendered at all.

So by adding an element (img) followed by whitespace (newline) in your markup, you instructed the agents to interpret your image as a "word", and add whitespace as appropriate to the language the agent is set in. If you would like to remove this whitespace from the result, you will need to remove it from the markup.

Alternately, you could remove the image from your markup entirely, and place it instead as a background on the anchor, thus eliminating any presentation pieces from your markup. Example here:

<a href='#' class="imglink">
There is
<em>no</em>
underlined whitespace at beginning of this text</a>

CSS:

.imglink {
min-height: 50px;
background: transparent url("http://www.cadcourse.com/winston/Images/SoccerBall.jpg") no-repeat;
background-size: 50px 50px;
display: block;
padding-left: 55px;
line-height: 50px
}

There are some weaknesses to this method of course, but it is a potential solution depending on your other constraints.

http://jsfiddle.net/hellslam/pvHK8/

Community
  • 1
  • 1
hellslam
  • 1,550
  • 11
  • 17
2

this is the expected behavior, since there are spaces after the images: You must change your html structure, use instead :

<a href='#'>
<img src='SoccerBall.jpg'/> <span>Your text</span>
</a>

CSS :

a{text-decoration:none;}
a>span{text-decoration:underline;}
amd
  • 20,637
  • 6
  • 49
  • 67
  • 1
    This is a nice solution, but OP would prefer not to change his structure, which I agree with in principle. It also doesn't remove the white space which now that I think about it, I am a little unclear as to whether he wants the whitespace there at all or not. – mrtsherman Apr 19 '12 at 04:15
0

Use two separate links for different elements, which are inside the current . I haven't seen yet a CSS fix. It is because the whole area is considered link, obviously. This workaround is working from the time being.

<a href='#'>
<img src='http://www.cadcourse.com/winston/Images/SoccerBall.jpg'
  width='50' height='50'/>
</a>
<a href='#'>
No Underlined Whitespace
</a>
Rolice
  • 3,063
  • 2
  • 24
  • 32
  • If the whole area including whitespace is considered part of the link then shouldn't you see a similar behavior from the 3rd example on the jsfiddle? – Jake Wilson Apr 17 '12 at 18:50
0

Get rid the space in the anchor between the image and the text (this is what's being underlined). In your css, give img 'margin-right:10px' (or whatever value you want). Remove the padding.

EDIT

To clarify:

Inserting a space character after the image does not fall under "coding style" - you have specifically encoded a space into the text value of the anchor.

CSS is behaving as intended in this regard: it is styling the text content of the anchor (including the space) with an underline, because you have not overridden that behavior for text content in an anchor.

By removing the space you are not altering your coding style, you are altering the content. It so happens that this will eliminate the styling issue you are facing.

I understand that you're asking if there's a way to retain the space in the anchor and also target that character with CSS - I don't think there's a way to do that.

I'm pointing out that by removing the space you are not altering the semantics of the content in any meaningful way (certainly not visually, because you want to hide it anyway, so the only possible effect it could have is for non-visual agents, most of which do not convey spacing in a meaningful way in this context anyway).

In fact, I suspect that the intent of that space character is more presentation-oriented than semantics-oriented.

Altering HTML for presentation purposes is not ideal, but generally it's not about altering your HTML per se - it's about altering the meaning which you are conveying with HTML. In this instance I believe it's entirely correct to alter your HTML to convey the same meaning.

There are times when you alter your document to suit both your semantic needs and your styling needs - as long as you're conveying the same meaning and logical flow of information, it really isn't an issue for the consumer of the content.

  • 1
    You shouldn't have to alter HTML content to affect the presentation of the rendered page. That's the whole purpose of my question. – Jake Wilson Apr 17 '12 at 18:53
  • In this case the space offers no semantic value. A space is considered the same as any other character in a hyperlink's text content; there's no way that I know of to selectively apply styling to specific characters. You could wrap the space in a span tag and style the span's content to not be underlined, but that's even more alteration to the HTML. Getting rid of the space retains the semantics of the content and allows you to style it effectively. –  Apr 17 '12 at 20:18
0

I certainly agree with your question and think it is well thought out and brings up a very good point. As referenced in this SO question, there is an experimental CSS3 property called text-space-collapse that has proposed values of discard, trim-inner, trim-before and trim-after which all could be used to resolve this problem.

I think the best solution you are going to find until text-space-collapse is implemented will be to alter your markup slightly. You can wrap the text in a span and then use display: table as one solution.

http://jsfiddle.net/CPh82/

a { display:table; }

a > * { display: table-cell; vertical-align: middle; }

<a href='#'>
    <img src='http://www.cadcourse.com/winston/Images/SoccerBall.jpg' width='50' height='50'/>
    There is underlined whitespace at beginning of this text
</a>
Community
  • 1
  • 1
mrtsherman
  • 39,342
  • 23
  • 87
  • 111
-1

instead of padding, try margin

img {
    border: 1px solid #CCC;
    margin: 10px;
    vertical-align: middle;   
}​
ramcal
  • 44
  • 5