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

Compatibility about CSS ::first-letter and UTF-8 mb4

所以,这是我的问题:我正在创建一个网站,其中有一些 post。在那些 post 中,我放了一个“::first-letter” 突出显示以使其更大,并且效果很好。

但是,当我要加载首字母为 UTF-8 mb4(2 个 Unicode 字符)的 Unicode Emoticon 的 post 时,它失败了,方法是尝试加载单个字符因为2分开,所以结果有点奇怪。

这是截图:

你怎么看出来的,有大一小两个不认识的字母,然后就可以看到同一个表情,因为我创建了一个post,同一个表情写了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;
}
<p class="first_letter_post">foobar</p>

这是字符: ,我正在使用 Google Chrome.

我希望有人能帮助我。

Chrome 对 unicode [bug] 问题的了解由来已久。这个问题是这些问题的组合:

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

这导致 Chrome 撕裂单个符号。

IE 正确识别由多个代码点组成的 unicode 符号,并应用样式,而不管规范是否规定 ::first-letter 应仅应用于 typographic letter units

Firefox 对规范非常严格,不会将样式应用于非字母单位。我无法确定字母数字补充 Space 是否应被视为 letter as well,但 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)));
p::first-letter {
  font-weight: bold;
  color:red;
}
span {
  font-weight: bold;
  color:blue;
}
p{
margin:0;
}
<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>