Can I accomplish this with CSS?
If I have elements like this:
<a href="something">A</a> <a href="something_else">B</a> <a href="something">A</a> <a href="...">C</a> I know I can use something like
body { counter-reset:section; } a:before { counter-increment:section; content:counter(section)". "; } To obtain
1. A 2. B 3. A 4. C but is there a way to get the following?
1. A 2. B 1. A 3. C i.e. uniquely identify all links on the page, prefix the text with the same number.
Note: special hard-coding URLs are not an option, I potentially deal with hundreds of links and donβt know the URLs ahead of time.
I understand that this would be easy / possible with javascript, I am only interested in CSS-based solutions or an explanation of why this is not possible with CSS.
Ok, I understand what you mean with your question. Just with plain CSS it's not possible (at least not cross-platform ..)
If you can use javascript, you have several options.
My preference would be to use the data attribute to store the value, for this example I selected data-counter . If you do it like this, CSS will become trivial:
CSS
a:before { content:attr(data-counter)". "; }β And Javascript will look like this if you have jQuery:
Js with jQuery
var linkcounter = {}; var counter = 0; $("a").each(function() { if (!linkcounter.hasOwnProperty($(this).attr("href"))) { counter++; linkcounter[$(this).attr("href")] = counter; } $(this).attr("data-counter", linkcounter[$(this).attr("href")]); }); or something like this without jQuery:
vanilla js
var linkcounter = {}; var counter = 0; var anchors = document.getElementsByTagName('a'); for(var i = 0; i < anchors.length; i++) { if (!linkcounter.hasOwnProperty(anchors[i].getAttribute("href"))) { counter++; linkcounter[anchors[i].getAttribute("href")] = counter; } anchors[i].setAttribute("data-counter", linkcounter[anchors[i].getAttribute("href")]); } You can view the version without jquery here: http://jsfiddle.net/ramsesoriginal/CVW7Y/5
And the jQuery version is here: http://jsfiddle.net/ramsesoriginal/CVW7Y/4
Unfortunately, CSS does not exist just for this (for now). Hope this helps.
I donβt think you can get this behavior with pure CSS, and you need Javascript. And there are always such cases:
http://google.com/ http://google.com google.com google.com/ www.google.com Did you understand.
In jQuery, this is pretty trivial, so I suggest you use this.
You can use: contains, but I'm not sure how much this is supported, so you might be better off with JavaScript.
a:contains("A") { /* Styles here */ } a:contains("B") { /* Styles here */ } EDIT:
Apparently: contains is not supported at all. I will leave it here, although no one is worried about putting it down.
You can use: contains in jQuery though add the class accordingly.
$('a:contains(A)').addClass('CLASS_NAME'); If using jQuery is fine, this can be done by manipulating the contents of the :before pseudo-element:
Demo: http://jsfiddle.net/rwMWx/2/
Js
var labels = [ "1", "2", "1", "3" // and so on... ]; // OR maybe put in some algo for this sequence $('a').each(function(i) { $(this).attr('data-label', labels[i] + '. '); }); CSS
a:before { content: attr(data-label); color: red; text-align: left; padding-right: 10px; font-size: 11px; display: inline; } try this code:
var counter = 0, cache = {}; $('a').each(function (i, a) { a = $(a); var href = a.attr('href'); var c = cache[href]; if (!c) { counter++; c = counter; cache[href] = c; } a.text(c + '. ' + a.text()); });β I use jQuery and that it works: http://jsfiddle.net/pDLbQ/