1

I'm attempting to dynamically create a list of HTMLElements with data-* attributes that correspond to different HTML Entities, to be then picked up by CSS and used as pseudo element content like so:

li:after {
  content: attr(data-code);
}

The problem with this is that for attr() to properly render the actual entity, rather than the literal code is to prefix said code with &#x - your typical \ doesn't work.

So the desired output HTML is something like so: <li data-code="&#xENTITY"></li>. When added directly to HTML, this works exactly as expected in relation to my CSS rule. The escaped entity is placed on the page in an :after psuedo element and rendered as the entity icon.

Here's where things get curious...

As stated earlier, I'm trying to create and inject these lis dynamically through JavaScript (iterating through a list), and that's where the snag happens.

  var entities = [{code: '&#x1F602'}, ...];
  for (var i = 0; i < entitites.length; i++) {
    var entity = entitites[i],
        listItem = document.createElement('li');

    listItem.setAttribute('data-code', entity.code);
    list.appendChild(listItem);
  }

The li is correctly added to the DOM with the properly formatted entity set so it gets picked up by my CSS rule. However, rather than rendering the entity icon, the code is shown!

enter image description here

Note in the image above, the first item rendered is the HTML explicitly on the page. The second item is injected via JS (using the exact same code), then given an :after element by CSS. Chrome's web inspector even renders it differently!

enter image description here

Even curiouser still is that I can edit the HTML via WebInspector and inject the escaped data-* attribute manually - Chrome STILL renders the correct icon!

enter image description here

I'm at a loss here, so any guidance would be greatly appreciated!

1 Answer 1

2

The HTML entity notation will only be parsed by an HTML parser. If your data-code attributes are "born" in JavaScript, then you need to use the JavaScript notation for getting the Unicode characters you want. Instead of &#x263A; for a smiley face, in JavaScript you use \u263A (a backslash, a lower-case "u", and four hex digits).

Whether your data-code attributes are coded directly into your HTML source (with HTML entity notation) or else created in JavaScript (with JavaScript notation), by the time the attribute value is part of the DOM, it's Unicode.

Now, things get more complicated when you have characters outside the 16-bit range, because JavaScript is kind-of terrible at dealing with that. You can look up your code point(s) at http://www.fileformat.info/info/unicode/ and that'll give you the "C/C++/Java" UTF-16 code pair you need. For example, your "tears of joy" face is the pair "\uD83D\uDE02".

Sign up to request clarification or add additional context in comments.

2 Comments

This works for a regular line smiley, but not for the extended "emoji" set documented here: apps.timwhitlock.info/unicode/inspect/hex/1F602 - Perhaps this is another issue specific to this charset?
@JordanForeman I just finished updating the question - see the edit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.