关于CSS :: first-letter和UTF-8 mb4的兼容性

Dav*_*x94 7 css unicode html5 utf-8 emoji

所以,这是我的问题:我正在创建一个网站,我有一些帖子.在那些帖子中,我把一个"::第一个字母"突出显示,使其更大,它完美地运作.

但是,当我要加载一个首字母作为UTF-8 mb4(2个Unicode字符)的Unicode表情符号的帖子时,它会失败,因为尝试加载单个字符串为2分开,所以结果是某些东西奇怪.

这是一个截图:

unicode和:: first-letter出错

你怎么看,有一个更大的字母和一个更小的未知,然后同样的表情可见,因为我创建了一个帖子与相同的表情符号写下2次.

.first_letter_post::first-letter {
  float: left;
  padding-right: 20px;
  padding-top: 0px;
  margin-bottom: -15px;
  margin-top: -10px;
  font-size: 50px;
  font-weight: bold;
  text-transform: uppercase;
}
Run Code Online (Sandbox Code Playgroud)
<p class="first_letter_post">foobar</p>
Run Code Online (Sandbox Code Playgroud)

这就是角色:我正在使用Google Chrome.

我希望有人可以帮助我.

Chr*_*oph 2

Chrome 长期以来一直存在有关 unicode [bug]的问题。这个问题是这些问题的组合:

  1. 无法正确识别超过 3 个字节的符号。
  2. 无论是字母单位还是符号样式

这会导致 Chrome 撕裂单个符号。

IE 正确识别由多个代码点组成的 unicode 符号,并应用样式,无论规范声明::first-letter应仅应用于印刷字母单位

Firefox 的行为非常严格地遵守规范,不会将样式应用于非字母单元。我无法确定字母数字补充空间是否也应该被视为字母,但 Firefox 并没有这样对待它们。

::first-letter这意味着,当您严重依赖它并且知道可能会出现这些字符时,您应该避免使用。

我能想到的一个可能的解决方案是通过 javascript 手动检测第一个字符并将其包装在标签中,然后应用样式。由于硬编码的十六进制值,我的解决方案有点混乱,但这可能就足够了。

// manually wrapping the "first character"
Array.prototype.forEach.call(document.querySelectorAll("div"),function(el){wrapFirstChar(el)});

function wrapFirstChar(div){
  let content = div.innerHTML,chars=content.charCodeAt(0) >= 55349?2:1;
  div.innerHTML = "<span>"+content.substring(0,chars)+"</span>"+content.substring(chars);
}

// this is what javascript sees at the first two positions of the string
//Array.prototype.forEach.call(document.querySelectorAll("p"),(e)=>console.log(e.innerHTML.charCodeAt(0)+"+"+e.innerHTML.charCodeAt(1)));
Run Code Online (Sandbox Code Playgroud)
p::first-letter {
  font-weight: bold;
  color:red;
}
span {
  font-weight: bold;
  color:blue;
}
p{
margin:0;
}
Run Code Online (Sandbox Code Playgroud)
<h2>using ::first-letter</h2>
<p> 4 bytes symbol</p>
<p> Enclosed Alphanumeric Supplement 1F170</p>
<p> Mathematical Alphanumeric Symbols 1D7B9</p>
<p> Arabic Mathematical Alphabetic Symbols 1EE00</p>
<p>a normal character (1 byte)</p>

<h2>manually replaced</h2>
<div> 4 bytes symbol</div>
<div> Enclosed Alphanumeric Supplement 1F170</div>
<div> Mathematical Alphanumeric Symbols 1D7B9</div>
<div> Arabic Mathematical Alphabetic Symbols 1EE00</div>
<div>a normal character (1 byte)</div>
Run Code Online (Sandbox Code Playgroud)