tags:

views:

1061

answers:

8

Greetings all,

I'd like to be able to target text links in CSS with border-bottom on hover, but have all links that are images not have a border on hover. So:

<a href="#"><img src="image.png"  /></a>  ==> this should not have a bottom-border on hover
<a href="#">regular text link</a> ==> this should have a bottom-border on hover

I tried this CSS:

#sidebar a:hover {
  border-bottom: 1px dotted red;
}
#sidebar a:hover img {
  border-bottom: none;
}

But this doesn't work...the anchor has to be targeted rather than the image, I think. I've been hunting around Google and no one seems to know how to do this except by targeting the image link with a specific class or id, or using display:block.

But, I can't use these solutions since the content is in a CMS so I don't want the user to have to assign a class to each image they insert. And display:block won't work because I don't know if that would be appropriate for every image the user wants to display.

Finally, I'd like to be able to do this in plain CSS (no Javascript). Perhaps there's no way...but any help or ideas you have would be greatly appreciated!

Thanks

NorthK

A: 

This is not possible with pure CSS without adding new tags. In order to do this with pure CSS/HTML, you will need to add a tag to either the image's [a href] link.. or add a tag to the [a hrer] links that you want to display with an underline.

You could write a small piece of code in javascript that would alter the border property of an element on hover quite easily. You would just need to check if the element is an IMG.

Jon
A: 

This actually seems to be a pretty difficult problem. Do you have any ability to change the CMS's code? It becomes easy if you can do something like wrap a <span> around any text inside links (and leave images outside of those). Then all you have to do is target #sidebar a:hover span to have the border.

If you can't change the code, I'm not sure if this is possible. I sure can't come up with anything.

Chad Birch
+4  A: 

You can't target an element depending on what child elements it has, so you would have to add something to the code to target the different links.

Can't you use underline instead of a bottom border? That would work as it's applied to the text in the link rather than the link element itself.

#sidebar a:hover { text-decoration: underline; }
#sidebar a:hover img { text-decoration: none; }
Guffa
A bottom border is a bit more controllable than an underline: you can control its width, for example.
Paul D. Waite
+2  A: 

Sorry, what you'd want is some kind of :parent pseudo-class that selects the child but applies to the parent, which unfortunately does not exist (not even in CSS3).

You'd have to do a bit of Javascript, selecting all elements matching #sidebar a:hover, then applying the red bottom border on the condition that they don't have a child IMG element.

EvanK
I've always thought this was a huge oversight in the CSS spec. It seems much more likely that you'd want to style an element based on descendants than based on arbitrary attributes, in my experience.
Chuck
But, according to a post by Eric Meyer, it's considered 'too difficult to implement...without performance issues' despite this being possible with JS (http://meyerweb.com/eric/thoughts/2009/02/12/selector-blocks/). Or at least I *assume* it's possible with JS.
David Thomas
+2  A: 

This might work

a img {position:relative; top: Npx}, where N is the hover border thickness

This would make the image cover the border, although it would be displaced downwards a pixel or so permanently.

wheresrhys
A: 

All, OK I'm hearing that this isn't possible to do in plain CSS, but not hard to do with a little Javascript. Would someone be willing to share that snippet of Javascript with me? :)

Thanks,

NorthK

See above: http://stackoverflow.com/questions/794677/css-target-text-links-with-bottom-border-on-hover-but-image-links-with-no-borde/1992908#1992908
Paul D. Waite
A: 

Try this trick. It's works.

a { text-decoration:none; border-bottom:2px solid; }

a img { border:none; vertical-align:top; }

Another way - PHP:

$text = preg_replace('#<a(.*?)<img(.*?)/>(.*?)</a>#is', "<a class='imgshow' \\1 <img\\2 />\\3</a>", $text); 
entercom
+1  A: 

As far as JavaScript goes, I’d suggest using jQuery to add a class to all links that contain an image:

$('#sidebar a:has(img)').addClass('image-link');

(The :has selector is a jQuery thing; it isn’t present in CSS.)

Then adjust your stylesheet accordingly.

#sidebar a:hover {
  border-bottom: 1px dotted red;
}
#sidebar a.image-link:hover {
  border-bottom: none;
}
Paul D. Waite