Mobile app version of vmapp.org
Login or Join
Michele215

: Width of unicode musical symbols vis a vis fixed width font In my experience, the musical Unicode symbols for flat (♭) and sharp (♯) are not exactly the same width as the fixed

@Michele215

Posted in: #Glyphs #Html #Symbols #Unicode

In my experience, the musical Unicode symbols for flat (♭) and sharp (♯) are not exactly the same width as the fixed width font that I am using, consequently columnar character alignment becomes slightly crooked. I am using this to depict guitar chords, and the alignment is a real nuisance.

Is there some way that I can draw strings and frets (presently using ╫, ─, ╢) together with musical symbols (presently using ♭, ♯, etc.) and Arabic numerals (1, 3, 5, 6, 7, 9, 11, 13) and retain completely fixed width spacing, such that columns spanning multiple rows will align properly? (I am presently allocating three characters between each "fret" (╫) so that I can sharpen or flatten an eleventh or thirteenth; single digit numerals receive an extra string filler character, ─.)

Here's a JSfiddle as a test case. The linked code results in this view:

10.03% popularity Vote Up Vote Down


Login to follow query

More posts by @Michele215

3 Comments

Sorted by latest first Latest Oldest Best

 

@Shelley591

Going with Cai’s idea of using a tabular structure to represent this, it occurred to me that the contents of the table could be vastly simplified by relegating the purely visual aspects (i.e., the graphical representation of the frets themselves) to table properties: borders, spacing, etc. (I think this is essentially what Chris’ comment to the question implied as well.)

That would mean you could keep the actual content (the notes you want to show) as the only real content of the table in the code, which makes the code vastly more readable and not riddled with distracting Unicode characters.

 

HTML: the table

The table itself is simple enough: just create (strings + 1) rows each with (frets + 1) cells. Put the individual notes in spans inside their respective table cell, and add a span in the last cell of each row with the letter for the corresponding string. Leave all cells in the last row empty.

This is how simple the table ends up being:

<table class="frets">
<caption>Example: 7<sup>♯9</sup></caption>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td><span>E</span></td>
</tr>

<tr>
<td></td>
<td><span>1</span></td>
<td></td>
<td><span>A</span></td>
</tr>

<tr>
<td></td>
<td></td>
<td><span>3</span></td>
<td><span>D</span></td>
</tr>

<tr>
<td></td>
<td><span>♭7</span></td>
<td></td>
<td><span>G</span></td>
</tr>

<tr>
<td><span>♯9</span></td>
<td></td>
<td></td>
<td><span>B</span></td>
</tr>

<tr>
<td></td>
<td></td>
<td></td>
<td><span>e</span></td>
</tr>

<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>


 

CSS: the styling

In your CSS, give the table a fixed layout so that cells are always the exact width you define, regardless of their content. Make horizontal borders single lines and vertical borders double lines. Remove the top, right, and bottom borders from the last cell in each row. Make the first and last rows something like one fifth the height of the other rows. And then absolutely position the spans to move them downwards enough that they overlap the bottom border of the cell, making it look like they’re actually on the line, rather than in the cell. Give the spans a solid background to knock out the border behind it.

All in all something like this:

body {
font-size: 30px;
}

caption {
font-weight: bold;
font-style: italic;
padding: 0.3em 0;
}

table {
table-layout: fixed;
border: none;
border-collapse: collapse;
}

tr:first-of-type td {
height: 0.1em;
border-top: none;
}

tr:last-of-type td {
height: 0.1em;
border-bottom: none;
}

td {
border-color: black;
border-width: 1px 5px;
border-style: solid double;
width: 3em;
height: 1em;
padding: 4px;
text-align: center;
position: relative;
}

td:last-of-type {
border-color: transparent transparent transparent black;
width: 2em;
}

td:last-of-type span {
background: none;
}

td span {
display: block;
position: absolute;
left: 50%;
bottom: calc(-0.5em - 4px);
transform: translateX(-50%);
padding: 0 0.3em;
background: #f3f5f6 ;
}


 

The result

Here is a JSFiddle showing how that ends up looking (of course, you can fiddle around with the CSS in general to get it to look exactly how you want it; I know nothing about guitars, so I have no idea if my fret width-to-height ratios are completely out of whack here, etc.):

10% popularity Vote Up Vote Down


 

@Margaret771

It boils down to: you need (to find) a monospaced font that contains musical symbols and load this as a webfont into your document.

If such a font does not exist (or you do not want to pay for it)...

...make one yourself:


Find a nice, free, open monospace font (may I recommend Hack ? )
Add the musical symbols that lack (try wikimedia) and export it again
Load your new font as a webfont into your website.


There exist several font-editing programs out there, among which Fontforge (free, open source,… but…). You can also use icomoon.io (a web-app, free) and load a SVG-font into it. (you can download a SVG version of Hack from their GitHub account)

UPDATE: The font you need is inconsolata. Available from Google fonts, so easy to use as a webfont.

10% popularity Vote Up Vote Down


 

@Nimeshi706

You could just use a table with a cell for each glyph.

So, this is how it renders with your current markup:



This is how it looks with each glyph in its own cell:



The markup for that is:

<table align="left" border="0" cellpadding="0">
<caption align="top"><b><i>Example: 7<sup>&#9839;9</sup></i></b></caption>
<tbody>
<tr>
<td>&#9579;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#9579;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#9579;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#9570;</td>
<td>E</td>
</tr>
<tr>
<td>&#9579;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#9579;</td>
<td>&#x2500;</td>
<td><b>1</b></td>
<td>&#x2500;</td>
<td>&#9579;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#9570;</td>
<td>A</td>
</tr>
<tr>
<td>&#9579;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#9579;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#9579;</td>
<td>&#x2500;</td>
<td><b>3</b></td>
<td>&#x2500;</td>
<td>&#9570;</td>
<td>D</td>
</tr>
<tr>
<td>&#9579;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#9579;</td>
<td><b>&#9837;</b></td>
<td><b>7</b></td>
<td>&#x2500;</td>
<td>&#9579;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#9570;</td>
<td>G</td>
</tr>
<tr>
<td>&#9579;</td>
<td><b>&#9839;</b></td>
<td><b>9</b></td>
<td>&#x2500;</td>
<td>&#9579;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#9579;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#9570;</td>
<td>B</td>
</tr>
<tr>
<td>&#9579;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#9579;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#9579;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#x2500;</td>
<td>&#9570;</td>
<td>e</td>
</tr>
</tbody>
</table>

10% popularity Vote Up Vote Down


Back to top | Use Dark Theme