Forum Moderators: not2easy

Message Too Old, No Replies

Hover multiple links in same element

Work arounds for lack of parent selector

         

Skier88

10:55 pm on Dec 22, 2010 (gmt 0)

10+ Year Member



I am trying to put the content of an element (innerHTML in js) as the value for "content" in the "after" pseudo-class. So, if I wanted to put the element's title there, the code would be
.thing:after {content:attr(title);}

But I don't want the title, I want the content. attr(innerHTML) and several varieties don't work - is there a keyword I don't know, or another method, or is this just not possible? Thanks for reading.

[edited by: alt131 at 12:19 am (utc) on May 17, 2011]
[edit reason] Side Scroll [/edit]

SuzyUK

10:27 am on Dec 24, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Don't think this is possible with pure CSS Skier.

attr(innerHTML) doesn't work, because innerHTML isn't an attribute.. though I think the the jQuery (javascript) library includes it for use?

don't know what you're using to generate the HTML, nor what sort of content you're trying to duplicate - but I *think* using PHP for example you could duplicate the "content" into a custom attribute and use that?

e.g.

a[href]:after {
content: ">> " attr(myatt);
display: block;
padding: 20px;
background: #eee;
color: #000;
font: 12px/1.5 monospace;
}

<a href="http://example.com" title="Example Site for Widgets" myatt="Visit this site">Visit this site</a>


There is something in CSS3 which explains
content: contents;
but after a quick scan I'm not sure I understand the use case apart from moving content.. i.e. you can put it, the content, into a "pending" state then "insert" it somewhere else in the document, i.e. it moves it - it won't apply the content twice. This is all theory at the minute because I can't find a browser that supports it anyway so am unable to "see it" ;) - TBH can't think of a use case for duplicating content :after the content anyway.. which may not be helping my answer here.. :)

[edited by: alt131 at 12:20 am (utc) on May 17, 2011]
[edit reason] Side Scroll [/edit]

Skier88

6:21 pm on Dec 24, 2010 (gmt 0)

10+ Year Member



Huh. Well, thanks for looking into it. I am actually looking into this mostly out of curiosity, to see if I can create a simple pure CSS method of identifying identical links. eg, take the sentence "or you can <a>email me</a> at <a>contact@site.com</a>" - both links go to the same place, so it would make sense if hover effects would be applied to both if either were hovered over. If content:attr(innerHTML) worked I could do that just by surrounding the links with a classed span and messing with z-index and positioning.

So, no big deal if it doesn't work - if I need it I can use any other slightly more complicated method. Thanks for looking.

[edited by: alt131 at 12:21 am (utc) on May 17, 2011]
[edit reason] Side Scroll [/edit]

alt131

4:28 pm on Dec 28, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If this is to identify identical links then attribute selectors should work for browsers that also understand content.
<a>email me</a> at <a>contact@site.com</a>

Both these links will have an href - something like mailto:contact@site.com, which can be selected using
a[href="mailto:contact@site.com"] { ... }

You can then apply the hover styles using
a[href="mailto:contact@site.com"]:hover {... }

Or even chain the selectors and use content to insert a message (or icon) on hover as a clue for visual users such as:
a[href="mailto:contact@site.com"]:hover:after {
position:absolute;
content:"Opens your email client";
}

Skier88

5:53 pm on Dec 28, 2010 (gmt 0)

10+ Year Member



Thanks, but that's not quite what I'm trying to do. I'm trying to obtain the same effect as below, but without javascript.

<!doctype html>
<html>
<head>
<title>intelligent hover effects example</title>
<style type='text/css'>
a {color:red; text-decoration:none;}
a.hover {text-decoration:underline;}
</style>
</head>
<body>
You can <a href='mailto:me'>contact me</a>
at <a href='mailto:me'>my email</a>, not
<a href='mailto:you'>this email</a>.

<script type='text/javascript'>
var links=document.getElementsByTagName('a');
function linkhover() {
for(var i=0;i<links.length;i++)
if(links[i].href==this.href)
links[i].className='hover';
}
function clearlinkhover() {
for(var i=0;i<links.length;i++)
if(links[i].href==this.href)
links[i].className='';
}
for(var i=0;i<links.length;i++) {
links[i].onmouseover=linkhover;
links[i].onmouseout=clearlinkhover;
}
</script>
</body>
</html>

I could also do this if there were a parent selector in css (the opposite of > ), but apparently there isn't.

[edited by: alt131 at 12:21 am (utc) on May 17, 2011]
[edit reason] Side Scroll [/edit]

SuzyUK

3:01 pm on Dec 29, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I could also do this if there were a parent selector in css (the opposite of > ), but apparently there isn't.


Yep, the parent selector has been asked for many times, but I think that then would take CSS into the realm of scripting, I don't know the technical terms, but it would also have performance issues, which for a suggested enhancement style is not really the job of CSS.

In your use case I'm pretty sure the parent selector would have to be quite specific to get far enough back in the DOM to make sure it caught all the child links on the page, presuming they're not always in the same div/paragraph that is.. hence the performance issue, also I think you would then have to make sure the CSS itself included selectors for each and every different a[href="yourlink"] value in your site, i.e. no variables in pure CSS.. performance issues galore even if CSS could do this?

Snook has a non-tech explanation here [snook.ca] of why no parent selector.

what you are looking for would not be helped my first suggestion of reprogramming in a custom attribute to match the text value as the text value differs, but the href value is the same. I'm sorry, I was going off your first explanation literally

ref. your second post with script example you would still need to know the container ancestor element (parent, grandparent, great.. great.. you get the idea) of the hovered element to find all the children with the same href in the document (theoretically) - so the already existing a[href] selector would do the job, if the parent could be found..

A Script is the best option IMHO.. though I wonder if using jQuery for enhancements like this wouldn't be an easier option, no difference to what your script above does, except you can use familiar CSS syntax; Yes it's still JS but that's what I (personal opinion) love about it.. I don't have to know what it does, can't write JS anyway ;) - jQuery just does it in a logical CSS'ey kind of way, and there's loads of examples out there ;)

example:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Highlight Same Links</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">

<script src="http://code.jquery.com/jquery-1.4.4.js"></script>

<style type="text/css" media="screen">
#content a {text-decoration: none;}

#content a:hover,
#content a.hovered {/* make sure the added class name is included in the same CSS as the CSS hover */
color:red; text-decoration: underline;
}
</style>
</head>
<body>
<div id="content">
<p>You can <a href='mailto:me'>contact me here</a>, but not here <a href='mailto:you'>your email</a></p>
<p>You can't use <a href='mailto:you'>this email</a>, nor <a href='mailto:you'>that one</a>, but you could try <a href='mailto:me'>this one</a> too.</p>
</div>

<script>
$(function() {

$("#content a").hover(function() { // initiate the function when link is hovered on
var myVar = $(this).attr("href"); // put the href value into a variable
$("#content a[href="+myVar+"]").addClass("hovered"); // add the classname .hovered to all links with same href value as stored in variable
},
function () {
$("#content a").removeClass("hovered"); // remove added classes on mouse out
});

});
</script>
</body>
</html>


I expanded the code a bit to show different paragraphs and how the same as CSS selector notation can be used to narrow the scope of the script's function.

Once the jQuery Library is included in your pages it can then be used for a lot of enhancement snippets like this

hth, and I'm not holding my breath for a parent selector ;)

[edited by: alt131 at 12:22 am (utc) on May 17, 2011]
[edit reason] Side Scroll [/edit]

Skier88

8:50 pm on Dec 29, 2010 (gmt 0)

10+ Year Member



I was a little inconsistent; the script I provided as an example is quite a bit more thorough than I was hoping to achieve with CSS. My idea was to wrap identical links in a span, eg:

<span class='link'>Or you can <a 
href='mailto:trash'>send your complaints</a> to <a
href='mailto:trash'>my priority inbox</a></span>


Then, assuming I was mindful not to put other elements inside the span, I could apply the same effect to every link in the span with one parent node selector. I figure 95% of links that are identical and would benefit from being marked as such are next to each other, so while incomplete this would be worth it if it took only a line of CSS.

On the other hand, the javascript is just an example... while potentially useful, I don't want to introduce that much work for such a trivial function. As I said, this is more out of curiosity than a need to get something done.

As for the parent selector, I understand your points, but I'm not sure if that's the case. In js .parentNode is stored as a reference,
which makes me think that elements in the DOM structure are aware of
their parent node. So it should take O(1) time to find the target, after which the attribute needs to be applied and trickled down. That could take a little time, but of course that's the same thing that every rule does. The way I see it, the > selector couldn't have worse performance than any other selector.

Assuming I'm right about the above, which I'm not at all certain of, I would guess that it isn't allowed because it encourages bad practice, in the same way that applying attributes to * is bad practice. I would guess that with that selector people would be more likely to create rule sets that are less efficient than an equivalent set based on narrowing rules.

[edited by: alt131 at 12:24 am (utc) on May 17, 2011]
[edit reason] Side Scroll [/edit]