如何调整 unicode 平面符号的字距

How to adjust kerning for the unicode flat symbol

我正在尝试描述一个和弦 B♭,但它在 <option> HTML 标签中的显示很奇怪。它不是“B♭”,而是在“B”和“♭”之间出现明显的 space。

我尝试将 CSS 样式 letter-spacing 应用到 <span> 标签中的这个和弦,但显然,这不能控制字距调整。

有趣的是,当我 select 下拉菜单中的和弦时,我的 OS 正确地呈现了字距调整,但在 selected 之后,平面符号自行显示,由 space 预留,如下所示。

我要渲染的 JS 文字是,

'B\u266D'

使用文字 'B&flat;' 只会在下拉列表中呈现为 'B&flat;'

FWIW,我在 Vue3 中执行此操作,并查看 Chrome 中的输出,在 Mac.

这似乎是 Chrome 96 在 macOS(以及其他基于 Chromium 的浏览器和其他操作系统)上的渲染问题。 macOS 上的 Firefox 91 renders it correctly。该问题也只影响 flat (\u266d) 和 natural (\u266e) 符号。 升号双升号双降号符号在我的测试中不受影响。

您可以通过将 <select>letter-spacing 调整为负值(使字符靠得更近,从而缩小间隙)来解决此问题,并使用padding在右边。您只想对受影响的标志有条件地执行此操作,因此请使用 return 必要的 letter-spacingpadding:

的计算道具
  1. <select> 上使用 v-model 来捕获选定的笔记。

  2. 使用 return 调整 letter-spacingpadding 所需样式的 computed prop。 When the selected note contains the problematic signs, return the adjusted spacing/padding.

  3. 将计算样式绑定到 <select> 的样式。

<script setup>
const notes = [
  'B\u266d', // flat
  'B\u266e', // natural
  'B\u266f', // sharp
  'B\u{1D12B}', // double flat
  'B\u{1D12A}', // double sharp
]
1️⃣
let selectedNote = $ref(notes[0])

2️⃣
let styles = $computed(() => {
  if (selectedNote.includes('\u266d') || selectedNote.includes('\u266e')) {
    return {
      'letter-spacing': '-20px',
      'padding-right': '40px',
    }
  }
})
</script>

<template>
  <select 1️⃣ v-model="selectedNote" :style="styles" 3️⃣>
    <option v-for="note in notes">{{ note }}</option>
  </select>
</template>

注:上面的<script setup>使用了new/experimentalReactivity Transform,它支持全局定义的响应式API($ref, $computed, 等等) 并且不需要解包 refs.

demo

Chrome96 在 macOS 上的结果: