Style an ordered list with Cyrillic letters - css

There are many possible values for list-style-type CSS property (e. g. decimal, lower-latin, upper-greek and so on). However there are none for the Cyrillic alphabet (which, btw, has different variations for different languages).
What is the best way to style an ordered list with Cyrillic letters?
(I'm providing a solution I ended up with despite I'm not very happy with it.)

I know nothing about Cyrillic list schemes so I’m at risk of a bit of cultural embarrassment here, but CSS3 Lists module (still in working draft) defines quite a few Cyrillic alphabetic list types: lower-belorussian, lower-bulgarian, lower-macedonian, lower-russian, lower-russian-full, lower-serbo-croatian, lower-ukrainian, lower-ukrainian-full, upper-belorussian, upper-bulgarian, upper-macedonian, upper-russian, upper-russian-full, upper-serbo-croatian, upper-ukrainian, upper-ukrainian-full. As expected, the state of support for these is deplorable currently (certainly nothing in Gecko or WebKit), but hopefully going forwards these will start to be implemented.
Update: some changes have been made – the definition of list types has been moved into the CSS3 Counter Styles module whose current draft (Feb 2015) has unfortunately lost all alphabetical Cyrillic types. This is in Candidate Recommendation stage so it’s unlikely that additions will be made at the point. Perhaps in CSS4 List Styles?

In this method I'm using CSS-generated content in before each list item.
.lower-ukrainian {
list-style-type: none;
}
.lower-ukrainian li:before {
display: inline-block;
margin-left: -1.5em;
margin-right: .55em;
text-align: right;
width: .95em;
}
.lower-ukrainian li:first-child:before {
content: "а.";
}
.lower-ukrainian li:nth-child(2):before {
content: "б.";
}
/* and so on */
Disadvantages
Hardcoded, restrict list to a certain max length.
Not pixel-perfect as compared to a regular order list

Here is another solution for Cyrillic letters with pretty clear code: jsfiddle.net
(() => {
const selector = 'ol.cyrillic',
style = document.createElement('style');
document.head.appendChild( style );
'абвгдежзиклмнопрстуфхцчшщэюя'.split('').forEach((c, i) =>
style.sheet.insertRule(
`${selector} > li:nth-child(${i+1})::before {
content: "${c})"
}`, 0)
);
})();
PS. You can convert this next-gen code to old one with Babel: babeljs.io

I'm surprised that there is no Cyrillic numbering. Here's a quick JS solution for you:
function base_convert(n, base) {
var dictionary = '0123456789abcdefghijklmnopqrstuvwxyz';
var m = n.toString(base);
var digits = [];
for (var i = 0; i < m.length; i++) {
digits.push(dictionary.indexOf(m.charAt(i)) - 1);
}
return digits;
}
var letters = {
'russian': {
'lower': 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя',
'upper': 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'
}
}
$('ul, ol').each(function() {
if (!(results = $(this).prop('class').match(/(upper|lower)-([a-z]+)/i))) return;
var characters = letters[results[2]][results[1]];
$('> li', this).each(function(index, element) {
var number = '', converted = base_convert(++index, characters.length);
for (var i = 0; i < converted.length; i++) {
number += characters.charAt(converted[i]);
}
$(this).attr('data-letter', number);
});
});​
My written Russian is admittedly bad, as you can see by my inability to count with letters, so change the letters object appropriately.
Demo: http://jsfiddle.net/JFFqn/14/

Related

Can autoprefixer solve the issue of CSS variables for Internet Explorer?

I am using css variables in my angular7 application. Everything works fine on other browsers. But IE is not supporting css variables. Is there a way to make it work on IE. Can Autoprefixer do this?
color: var(--primary, #7F583F);
According to caniuse.com, of current browsers only IE, Edge (older versions) and Opera Mini do not support CSS variables. This polyfil appears to work on all three really well.
This is an attempt at a very basic CSS variables (custom properties) polyfil. In reality this is more of a partial polyfill as it will not cover variables inside of variables, DOM scoping or anything else "fancy". Just taking variables declared anywhere in the CSS and then re-parsing the CSS for var() statements and replacing them in browsers that don't natively support CSS variables.
I try to test this polyfil in IE 11 and looks like it is working with it.
/*!
* css-var-polyfill.js - v1.0.0
*
* Copyright (c) 2018 Aaron Barker <http://aaronbarker.net>
* Released under the MIT license
*
* Date: 2018-03-09
*/
let cssVarPoly = {
init: function() {
// first lets see if the browser supports CSS variables
// No version of IE supports window.CSS.supports, so if that isn't supported in the first place we know CSS variables is not supported
// Edge supports supports, so check for actual variable support
if (window.CSS && window.CSS.supports && window.CSS.supports('(--foo: red)')) {
// this browser does support variables, abort
console.log('your browser supports CSS variables, aborting and letting the native support handle things.');
return;
} else {
// edge barfs on console statements if the console is not open... lame!
console.log('no support for you! polyfill all (some of) the things!!');
document.querySelector('body').classList.add('cssvars-polyfilled');
}
cssVarPoly.ratifiedVars = {};
cssVarPoly.varsByBlock = {};
cssVarPoly.oldCSS = {};
// start things off
cssVarPoly.findCSS();
cssVarPoly.updateCSS();
},
// find all the css blocks, save off the content, and look for variables
findCSS: function() {
let styleBlocks = document.querySelectorAll('style:not(.inserted),link[rel="stylesheet"]');
// we need to track the order of the style/link elements when we save off the CSS, set a counter
let counter = 1;
// loop through all CSS blocks looking for CSS variables being set
[].forEach.call(styleBlocks, function(block) {
// console.log(block.nodeName);
let theCSS;
if (block.nodeName === 'STYLE') {
// console.log("style");
theCSS = block.innerHTML;
cssVarPoly.findSetters(theCSS, counter);
} else if (block.nodeName === 'LINK') {
// console.log("link");
cssVarPoly.getLink(block.getAttribute('href'), counter, function(counter, request) {
cssVarPoly.findSetters(request.responseText, counter);
cssVarPoly.oldCSS[counter] = request.responseText;
cssVarPoly.updateCSS();
});
theCSS = '';
}
// save off the CSS to parse through again later. the value may be empty for links that are waiting for their ajax return, but this will maintain the order
cssVarPoly.oldCSS[counter] = theCSS;
counter++;
});
},
// find all the "--variable: value" matches in a provided block of CSS and add them to the master list
findSetters: function(theCSS, counter) {
// console.log(theCSS);
cssVarPoly.varsByBlock[counter] = theCSS.match(/(--.+:.+;)/g) || [];
},
// run through all the CSS blocks to update the variables and then inject on the page
updateCSS: function() {
// first lets loop through all the variables to make sure later vars trump earlier vars
cssVarPoly.ratifySetters(cssVarPoly.varsByBlock);
// loop through the css blocks (styles and links)
for (let curCSSID in cssVarPoly.oldCSS) {
// console.log("curCSS:",oldCSS[curCSSID]);
let newCSS = cssVarPoly.replaceGetters(cssVarPoly.oldCSS[curCSSID], cssVarPoly.ratifiedVars);
// put it back into the page
// first check to see if this block exists already
if (document.querySelector('#inserted' + curCSSID)) {
// console.log("updating")
document.querySelector('#inserted' + curCSSID).innerHTML = newCSS;
} else {
// console.log("adding");
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = newCSS;
style.classList.add('inserted');
style.id = 'inserted' + curCSSID;
document.getElementsByTagName('head')[0].appendChild(style);
}
};
},
// parse a provided block of CSS looking for a provided list of variables and replace the --var-name with the correct value
replaceGetters: function(curCSS, varList) {
// console.log(varList);
for (let theVar in varList) {
// console.log(theVar);
// match the variable with the actual variable name
let getterRegex = new RegExp('var\\(\\s*' + theVar + '\\s*\\)', 'g');
// console.log(getterRegex);
// console.log(curCSS);
curCSS = curCSS.replace(getterRegex, varList[theVar]);
// now check for any getters that are left that have fallbacks
let getterRegex2 = new RegExp('var\\(\\s*.+\\s*,\\s*(.+)\\)', 'g');
// console.log(getterRegex);
// console.log(curCSS);
let matches = curCSS.match(getterRegex2);
if (matches) {
// console.log("matches",matches);
matches.forEach(function(match) {
// console.log(match.match(/var\(.+,\s*(.+)\)/))
// find the fallback within the getter
curCSS = curCSS.replace(match, match.match(/var\(.+,\s*(.+)\)/)[1]);
});
}
// curCSS = curCSS.replace(getterRegex2,varList[theVar]);
};
// console.log(curCSS);
return curCSS;
},
// determine the css variable name value pair and track the latest
ratifySetters: function(varList) {
// console.log("varList:",varList);
// loop through each block in order, to maintain order specificity
for (let curBlock in varList) {
let curVars = varList[curBlock];
// console.log("curVars:",curVars);
// loop through each var in the block
curVars.forEach(function(theVar) {
// console.log(theVar);
// split on the name value pair separator
let matches = theVar.split(/:\s*/);
// console.log(matches);
// put it in an object based on the varName. Each time we do this it will override a previous use and so will always have the last set be the winner
// 0 = the name, 1 = the value, strip off the ; if it is there
cssVarPoly.ratifiedVars[matches[0]] = matches[1].replace(/;/, '');
});
};
// console.log(ratifiedVars);
},
// get the CSS file (same domain for now)
getLink: function(url, counter, success) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.overrideMimeType('text/css;');
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
// console.log(request.responseText);
if (typeof success === 'function') {
success(counter, request);
}
} else {
// We reached our target server, but it returned an error
console.warn('an error was returned from:', url);
}
};
request.onerror = function() {
// There was a connection error of some sort
console.warn('we could not get anything from:', url);
};
request.send();
}
};
cssVarPoly.init();
:root {
--externalcolor: red;
--samename: orange;
--samename: #0f0;
--foo: green;
--FOO: #0f0;
--halfsuccess: orange;
--success: green;
--success2: #0f0;
}
html {
font-family: var(--fontsans);
}
.success {
color: green;
}
.fail {
color: red;
}
span {
display: inline-block;
margin: 5px;
}
.samename {
color: var(--samename);
}
.demo1 {
color: #f00;
color: var(--success);
}
.demo2 {
color: #f00;
color: var( --success2);
}
.demo3 {
color: #f00;
color: var(--halfsuccess);
color: var(--success);
}
.demo4 {
color: red;
border-color: #f00;
}
.inlineoverlink {
color: #f00;
}
p {
padding: var(--spacing-l);
}
.lower {
color: var(--foo);
}
.upper {
color: var(--FOO);
}
.externalcolor {
color: var(--externalcolor);
}
.fallback {
color: #f00;
color: var(--wrongname, green);
}
// for the top documentation
.supports {
color: green;
.no {
display:none;
}
}
.showforpolyfill {
display:none;
}
.cssvars-polyfilled {
.supports {
color: red;
.no {
display:inline;
}
}
.showforpolyfill {
display:inline;
}
.hideforpolyfill {
display:none;
}
}
.hide,
.hide-the-docs .documentation {
display:none;
}
/* declare some font-family stuff at bottom of file to reflect on stuff above it*/
:root {
--fontsans: arial;
}
<!-- Copy below for codepen update -->
<h1>CSS Variables Polyfill</h1>
<p>This is now managed (and available for PRs) at https://github.com/aaronbarker/css-variables-polyfill.</p>
<p>
This is an attempt at a very basic CSS variables (custom properties) polyfil. In reality this is more of a <em>partial</em> polyfill as it will not cover variables inside of variables, DOM scoping or anything else "fancy". Just taking variables declared anywhere in the CSS and
then re-parsing the CSS for var() statements and replacing them in browsers that don't natively support CSS variables.
</p>
<p>According to caniuse.com, of current browsers only IE, Edge and Opera Mini do not support CSS variables. This polyfil appears to work on all three really well. I don't see why this wouldn't work on older browsers as well, but I haven't been able to test it on them yet.</p>
<p>As far as we can tell your browser <span class="supports">does <span class="no">not</span> support</span> native CSS variables. <span class="showforpolyfill">That means if you see green tests results below, it is thanks to the polyfill :).</span> <span class="hideforpolyfill">All the green test results below are actually native CSS Variable support. Good job using a good browser :)</span></p>
<h3>Does this work on externally CSS files?</h3>
<p>Yes!</p>
<h3>Even ones loaded from another domain?</h3>
<p>To go across domain, CSS needs to be served up with <code>Access-Control-Allow-Origin:*</code> headers.</p>
</div>
Toggle documentation (for Opera Mini vs Codepen issue)
<style>
:root {
--newcolor: #0f0;
}
.inlineoverlink {
color: var(--success2);
}
</style>
<h2>Tests</h2>
<p>On mosts tests (unless otherwise noted) success will be green text. We start with a <code>color:red;</code> and then override it with a <code>color:var(--success);</code> (or similar) which is green.</p>
<ul>
<li><span class="samename">declare same variable over and over</span></li>
<li><span class="demo1">no whitespace on var() calls</span></li>
<li><span class="demo2">whitespace on var() calls</span></li>
<li><span class="demo3">Multiple variables in same call. orange means first var worked, green var worked</span></li>
<li><span class="inlineoverlink">orange if link won, green if style after link won</span></li>
<li><span class="lower">--foo: lowercase foo</span></li>
<li><span class="upper">--FOO: uppercase FOO</span></li>
<li><span class="fallback">uses fallback <code>--var(--wrongname, green)</code></span></li>
<li><span class="demo-import">css declared in an <code>#import</code></span> - not polyfilled yet. Identfied with a suggested fix, but will require a bit of a re-write (to use document.styleSheets), so haven't done it yet.</li>
</ul>
<h2>Tests on external, cross-domain file</h2>
<div class="documentation">
<p><strong>Edge</strong> appears to be working well on Edge 13. Edge 12 was having some problems.</p>
<p><strong>Opera mini</strong> seems to work well too. This demo fails because not all the page is displayed, but I think that is a codepen issue, not a polyfill issue. When the upper documentation is removed, all tests display well.</p>
<p><strong>IE 11</strong> seems to do fine.</p>
</div>
<ul>
<li><span class="demo4">Gets stuff from external .css file. Should start red and change to green on LINK load. border proves the CSS loaded, missing colors means script didn't get parsed and reinserted</span></li>
<li><span class="externalcolor">--externalcolor: should start red and change to green on LINK load</span></li>
<li><span class="externalfallback">uses fallback. should be green</span></li>
</ul>
<p>Another set of text under the test for Opera Mini testing.</p>
<!-- Copy above for codepen update -->
Testing result:
References:
(1) Codepen example link
(2) aaronbarker/css-variables-polyfill

Can I use Chinese characters in CSS class names?

Is it possible to use Chinese class names for my CSS classes? I'm trying to get the Chinese word with jQuery and then create img elements with classes named by the Chinese words.
I have for instance a file named 2020_Cars_哈喽_1.jpg, and I created a code that takes the year, the category (Cars), and the Chinese word which is the name of the album, and creates an img element with classes according to the file name in order to filter the images later.
I have an example here where you can see the categories which translated to classes without any problem, and the %46%bd% which are Chinese words that I could not transform successfully into a class name.
Any suggestions please?
The jQuery code which takes the file name and split it into classes:
$.ajax({
url: dir,
success: function(data){
$(data).find("a:contains(.JPG)").each(function(){
// will loop through
var images = $(this).attr("href");
var splittedName = images.split('_');
var classesToAdd = 'thumbnailpic';
for(var i=0;i<3;i++){
classesToAdd+=' '+splittedName[i];
}
if(years.indexOf(splittedName[0])===-1){
years.push(splittedName[0]);
}
if(categories.indexOf(splittedName[1])===-1) {
categories.push(splittedName[1]);
}
if(albums.indexOf(splittedName[2])===-1) {
albums.push(splittedName[2]);
}
$('.gallery').append('<img class="'+classesToAdd+'" src="'+dir+'/'+images+'"'+'>');
});
for(var a=0;a<years.length;a++){
$('.years').append('<div id="filter-button" class="filter-select" >'+years[a]+'</div>');
}
for(var b=0;b<categories.length;b++){
$('.categories').append('<div id="filter-button" class="filter-select">'+categories[b]+'</div>');
}
for(var c=0;c<albums.length;c++){
$('.albums').append('<div id="filter-button" class="filter-select">'+albums[c]+'</div>');
}
hideBigPic();
$('.filters').fadeIn(1000);
$('.gallery').fadeIn(1000);
}
});
Thank you in advance!
Yes, you can use Chinese characters as class names and selectors.
div {
width: 100px;
height: 100px;
}
.tomato {
background: tomato;
}
.蓝色 {
background: navy;
}
<div class="蓝色"></div>
<div class="tomato"></div>
<br>
<button onclick="console.log(document.querySelector('.蓝色'))">Find Element</button>
But it looks like the real question here is how do you turn URL encoded characters (%46 etc) back into real characters and for that you need decodeURIComponent
console.log(decodeURIComponent('%E8%93%9D'))
Hope this answers all of your questions.

How to edit ol tags in rich text editor

I am creating and ordered list using Text Angular and able to create orderlist which starts with 1,2,3 by default. Text angular has 2 modes
1. Rich Text mode
1. HTML mode
HTML mode shows
<ol>
<li>test</li>
<li>test</li>
</ol>
Rich Text mode will show as:
test
test
If I need to start ordered list with number 5, I need to switch to HTML mode first and do the below change
<ol start="5">
<li>test</li>
<li>test</li>
</ol>
Now the Rich Text mode starts the numbering with 5
test
test
The real problem is how to change the numbering by clicking on the pseudo element generated by the < ol> tag while on the rich text editor mode. After googling and research it seems the pseudo element cannot be changed.
Stack overflow editor gives the option of changing this in Rich Text mode itself!
So while adding the below data in Rich Text mode starting with 4 for example
4. number 4
3. number 3
The preview mode ends up displaying buggy result.
number 4
number 3
if you noticed 5. number 3. this was generated from the Rich text editor.
There are JS way to replace tags in the DOM and give a simlar tag look n feel using combination of html tags etc which I am not looking for at this point.
Would there be a creative CSS way to change the number on the fly in the rich text mode (rather than doing html mode) in Text Angular.
As I understood, what you need is a feature for changing the starting number when using the ordered list which is not implemented by the text-angular editor at the moment. What text-angular provides you in such cases is easy extending of the toolbar by adding new or overriding existing functionalities.
Here is a Plunker with an example implementation of the feature you need. I have implemented it by overriding the ol button configuration like this:
app.decorator('taTools', function ($delegate, $document, taSelection) {
// NOTE: override the ol action
var olAction = $delegate.ol.action;
$delegate.ol.action = function () {
if (!this.active) {
// NOTE: replace with better way for integrating the feature
var startingNumber = $document.find('#startingNumber').val();
// do the ordering
var result = olAction.apply(this, arguments);
// change the starting number
var element = angular.element(taSelection.getSelection().start.element);
var parentOls = element.parents('ol');
if (parentOls.length > 0) {
angular.element(parentOls[0]).attr('start', startingNumber);
}
// clean up
element = null;
parentOl = null;
return result;
} else {
return olAction.apply(this, arguments);
}
};
return $delegate;
});
The way for configuring the starting number IMO is not so good, it's just for showcase because replacing it with better way takes more effort (ex. dropdown on the ol button). You can replace it with what is most convenient for you.
For more information and examples on Text-Angular editor you can check its documentation and the page for customizing the toolbar.
Edit: After the question was edited my answer no longer fits very well. Since it still received upvotes afterwards I'm going to assume that it was nonetheless helpful and just leave it here.
As has been mentioned in comments and other answers, the clicking part is not possible. It is possible to highlight the numbering.
Add a custom counter in the :before part of your <li> tags and have them react to hovering:
ol {
counter-reset: my-counter;
}
ol > li {
list-style-type:none;
}
ol > li:before {
counter-increment: my-counter;
content: counter(my-counter) '. ';
}
ol > li:hover:before {
color: red;
}
Example here: http://jsfiddle.net/u1uhr7s8/
Again, it is not possible to add anything clickable in place of the numbers because the before: bit does not truly become part of the DOM.
'selected' here could mean a number of different things. You'll need to clarify your question to get the answers you're after, but if you're looking to reference this in Javascript somewhere, you can use any of the following:
document.getElementsByTagName('ol') //Will return a list of all OLs on the page
document.querySelectorAll('ol') //Will return a list of all OLs on the page
$('ol') //Will return a list of all OLs on the page, but requires JQuery
To get the '1' or '2' li elements, you'd include the LI within the query, or select it as a child of what's returned:
var myOL = document.getElementsByTagName('ol')[0];
var myItems = myOL.children;
or with JQuery
var myItems = $('ol li');
If you're talking about targeting the OL with CSS rules, you just use the tag name, e.g.
ol {
background-color: #FF0000;
}
and again, if you're after the LIs you can either target them all:
ol li {
background-color: #FFFF00;
}
or target a specific child using nth-child:
ol li:nth-child(2) { /* second child - '2' in your case */
background-color: #FFFF00;
}
Below solution is inspired by S.Klechkovski's answer. On the editor type a number, say 5 , select the number, click on on ol tag in TextAngular, the old now starts with 5
The difference is in var startingNumber = parseInt($(taSelection.getSelectionElement()).text());
$provide.decorator('taTools', function ($delegate, $document, taSelection) {
// NOTE: override the ol action
var olAction = $delegate.ol.action;
$delegate.ol.action = function () {
if (!this.active) {
// NOTE: replace with better way for integrating the feature
var startingNumber = parseInt($(taSelection.getSelectionElement()).text());
// do the ordering
var result = olAction.apply(this, arguments);
// change the starting number
var element = angular.element(taSelection.getSelection().start.element);
var parentOls = element.parents('ol');
if (parentOls.length > 0) {
angular.element(parentOls[0]).attr('start', startingNumber);
}
// clean up
element = null;
parentOl = null;
return result;
} else {
return olAction.apply(this, arguments);
}
};
return $delegate;
});

css convert letters to their counterparts in other language

I'd like to know how can i convert a normal english text into other langugae. I didn't mean translate but just convert alphabets, usually, there are some counterparts of alphabets in other language..for example.. numbers in english like 1, 2, 3, 4 ... all can be converted to Arabic, Chinese, etc.
You can change list bullets like list-style-type: Arabic/Roman/...;
And it will change numbers accordingly.
I thought there was something but not sure and can't find. Like in Css i could declare the language.
Do you mean "transliterate"? No, you can't do that in CSS. You could look at this https://developers.google.com/transliterate/v1/getting_started.
Language support in CSS is pretty much limited to the list styles you mentioned, and the :lang pseudo-class to limit CSS rules to elements with a particular language:
<html lang="ja">
<body>
<div id='name'>Bob</div>
#name:lang(en)::before {
content: 'Hello ';
}
#name:lang(ja)::before {
content: 'こんにちは';
}
Whether or not you actually want to do that is another question. It results in another localization surface to worry about. For more details, see https://developer.mozilla.org/en-US/docs/Web/CSS/:lang.
Note: the :lang pseudo-class does not require the lang attribute to be on the particular element. It can be on any parent element (often the html element). So
:lang(en) {
is somewhat equivalent to
[lang='en'] * {
A common use of the :lang pseudo-element is to customize how quotes are presented in different languages, for instance, when using the q element:
q:lang(en) { quotes: '"' '"'; }
q:lang(ja) { quotes: '「' '」'; }
q::before { content: open-quote }
q::after { content: close-quote }
Answer: You can't convert characters with CSS alone. It's quite easy with CSS and JS, though, simply replace the character you want with a span and add content via CSS. I don't recommend it AT ALL, though.
Now, if you want a solution, I'd recommend not to re-invent the wheel and use Javascript, it's way faster, reliable and more secure. Below you have a Backbone.js solution from a relatively similar question at SO. While that question is about how to replace characters, not necessarily with CSS, it's a very good idea for you to check that page because I think you'll acknowledge it's a better method (for starters, it's POSSIBLE)
function removeDiacritics (str) {
var defaultDiacriticsRemovalMap = [
{'base':'A', 'letters':/[\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F]/g},
{'base':'AA','letters':/[\uA732]/g},
{'base':'AE','letters':/[\u00C6\u01FC\u01E2]/g},
{'base':'AO','letters':/[\uA734]/g},
{'base':'AU','letters':/[\uA736]/g},
{'base':'AV','letters':/[\uA738\uA73A]/g},
{'base':'AY','letters':/[\uA73C]/g},
{'base':'B', 'letters':/[\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181]/g},
{'base':'C', 'letters':/[\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E]/g},
{'base':'D', 'letters':/[\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779]/g},
{'base':'DZ','letters':/[\u01F1\u01C4]/g},
{'base':'Dz','letters':/[\u01F2\u01C5]/g},
{'base':'E', 'letters':/[\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E]/g},
{'base':'F', 'letters':/[\u0046\u24BB\uFF26\u1E1E\u0191\uA77B]/g},
{'base':'G', 'letters':/[\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E]/g},
{'base':'H', 'letters':/[\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D]/g},
{'base':'I', 'letters':/[\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197]/g},
{'base':'J', 'letters':/[\u004A\u24BF\uFF2A\u0134\u0248]/g},
{'base':'K', 'letters':/[\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2]/g},
{'base':'L', 'letters':/[\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780]/g},
{'base':'LJ','letters':/[\u01C7]/g},
{'base':'Lj','letters':/[\u01C8]/g},
{'base':'M', 'letters':/[\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C]/g},
{'base':'N', 'letters':/[\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4]/g},
{'base':'NJ','letters':/[\u01CA]/g},
{'base':'Nj','letters':/[\u01CB]/g},
{'base':'O', 'letters':/[\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C]/g},
{'base':'OI','letters':/[\u01A2]/g},
{'base':'OO','letters':/[\uA74E]/g},
{'base':'OU','letters':/[\u0222]/g},
{'base':'P', 'letters':/[\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754]/g},
{'base':'Q', 'letters':/[\u0051\u24C6\uFF31\uA756\uA758\u024A]/g},
{'base':'R', 'letters':/[\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782]/g},
{'base':'S', 'letters':/[\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784]/g},
{'base':'T', 'letters':/[\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786]/g},
{'base':'TZ','letters':/[\uA728]/g},
{'base':'U', 'letters':/[\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244]/g},
{'base':'V', 'letters':/[\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245]/g},
{'base':'VY','letters':/[\uA760]/g},
{'base':'W', 'letters':/[\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72]/g},
{'base':'X', 'letters':/[\u0058\u24CD\uFF38\u1E8A\u1E8C]/g},
{'base':'Y', 'letters':/[\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE]/g},
{'base':'Z', 'letters':/[\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762]/g},
{'base':'a', 'letters':/[\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250]/g},
{'base':'aa','letters':/[\uA733]/g},
{'base':'ae','letters':/[\u00E6\u01FD\u01E3]/g},
{'base':'ao','letters':/[\uA735]/g},
{'base':'au','letters':/[\uA737]/g},
{'base':'av','letters':/[\uA739\uA73B]/g},
{'base':'ay','letters':/[\uA73D]/g},
{'base':'b', 'letters':/[\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253]/g},
{'base':'c', 'letters':/[\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184]/g},
{'base':'d', 'letters':/[\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A]/g},
{'base':'dz','letters':/[\u01F3\u01C6]/g},
{'base':'e', 'letters':/[\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD]/g},
{'base':'f', 'letters':/[\u0066\u24D5\uFF46\u1E1F\u0192\uA77C]/g},
{'base':'g', 'letters':/[\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F]/g},
{'base':'h', 'letters':/[\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265]/g},
{'base':'hv','letters':/[\u0195]/g},
{'base':'i', 'letters':/[\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131]/g},
{'base':'j', 'letters':/[\u006A\u24D9\uFF4A\u0135\u01F0\u0249]/g},
{'base':'k', 'letters':/[\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3]/g},
{'base':'l', 'letters':/[\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747]/g},
{'base':'lj','letters':/[\u01C9]/g},
{'base':'m', 'letters':/[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F]/g},
{'base':'n', 'letters':/[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5]/g},
{'base':'nj','letters':/[\u01CC]/g},
{'base':'o', 'letters':/[\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275]/g},
{'base':'oi','letters':/[\u01A3]/g},
{'base':'ou','letters':/[\u0223]/g},
{'base':'oo','letters':/[\uA74F]/g},
{'base':'p','letters':/[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755]/g},
{'base':'q','letters':/[\u0071\u24E0\uFF51\u024B\uA757\uA759]/g},
{'base':'r','letters':/[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783]/g},
{'base':'s','letters':/[\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B]/g},
{'base':'t','letters':/[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787]/g},
{'base':'tz','letters':/[\uA729]/g},
{'base':'u','letters':/[\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289]/g},
{'base':'v','letters':/[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C]/g},
{'base':'vy','letters':/[\uA761]/g},
{'base':'w','letters':/[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73]/g},
{'base':'x','letters':/[\u0078\u24E7\uFF58\u1E8B\u1E8D]/g},
{'base':'y','letters':/[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF]/g},
{'base':'z','letters':/[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763]/g}
];
for(var i=0; i<defaultDiacriticsRemovalMap.length; i++) {
str = str.replace(defaultDiacriticsRemovalMap[i].letters, defaultDiacriticsRemovalMap[i].base);
}
return str;
}

Can I accomplish this with CSS?

If I've got elements like this:
A
B
A
C
I know I can use something like
body
{
counter-reset:section;
}
a:before
{
counter-increment:section;
content:counter(section)". ";
}
to get
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
ie. uniquely identify all links on a page by prefixing the text with the same number.
Note: hardcoding specific URLs isn't an option, I'm potentially dealing with hundreds of links and don't know the URLs ahead of time.
I realize this would be easy/possible with javascript, I am only interested in CSS-based solutions or an explanation of why this isn't possible with CSS.
Ok, I got 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 possibilities.
My preference would be to use a data-attribute to hold the value, for this example I chose data-counter. If you do like this, the CSS becomes trivial:
CSS
a:before
{
content:attr(data-counter)". ";
}​
And the Javascript would 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 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 version with jQuery here: http://jsfiddle.net/ramsesoriginal/CVW7Y/4
Sadly there is no CSS only way to do this (yet). I hope this helps.
​
I don't think you can get this behaviour with pure CSS, and you need Javascript. And there are always cases like this:
http://google.com/
http://google.com
google.com
google.com/
www.google.com
You get the point.
In jQuery this is quite trivial, so I'd suggest you use that.
If using jQuery is OK, this can be done by manipulating the :before pseudo element's content:
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;
}
You could use :contains but I'm not sure how supported it is so you might be better off with JavaScript.
a:contains("A") {
/* Styles here */
}
a:contains("B") {
/* Styles here */
}
EDIT:
Apparently :contains isn't supported at all. I'll leave this up here though so no one else bothers putting it.
You could use :contains in jQuery though and add a class accordingly.
$('a:contains(A)').addClass('CLASS_NAME');
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'm using jQuery, and that's how it works: http://jsfiddle.net/pDLbQ/

Resources