[Vuejs]-How to adjust kerning for the unicode flat symbol

0👍

This seems to be a rendering issue in Chrome 96 on macOS (and possibly other Chromium-based browsers and other operating systems). Firefox 91 on macOS renders it correctly. The problem also only affects the flat (\u266d) and natural (\u266e) signs. The sharp, double sharp, and double flat signs are unaffected in my tests.

You could workaround the issue by adjusting the <select>‘s letter-spacing with a negative value (to bring the characters closer together, thus reducing the gap), and compensating for the reduced width with padding on the right. You’d only want to do this conditionally for the affected signs, so use a computed prop that returns the necessary letter-spacing and padding:

  1. Use a v-model on the <select> to capture the selected note.

  2. Use a computed prop that returns the styles needed to adjust letter-spacing and padding. When the selected note contains the problematic signs, return the adjusted spacing/padding.

  3. Bind the computed style to the <select>‘s styles.

<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>

Note: The <script setup> above uses the new/experimental Reactivity Transform, which supports globally defined reactivity APIs ($ref, $computed, etc.) and removes the need to unwrap refs.

demo

Result on Chrome 96 on macOS:

Leave a comment