title: Semantic song markup with visual "chord stacking"
body: <p>I am looking for a HTML-based representation for song texts with chords above the syllables, in the following fashion:</p>
  <pre><code>      Am   C        D     F
  There is a house in New Orleans
  </code></pre>
  <p>Now, I don't care how exactly the HTML looks like in the end, but there is an important constraint: the purpose is not only display, but also storage in a semantically meaningful representation.  Specifically, the songs are converted from a <a href="http://songs.sourceforge.net/songsdoc/songs.html#sec5.3" rel="nofollow noreferrer">LaTeX-based</a> syntax and should be recoverable in their original form, as well as being readable in HTML and easily processable.  So no fancy structure just for the purpose of presentation, and no JavaScript (yes, I have looked at how UltimateGuitar does it, that is exactly not what I want).  I need every element to have a direct correspondence to some logical part, as in the original format.</p>
  <p>On the other hand, this gives me a hard time designing a CSS that presents the stacked chords.  The basic rule is that you have &quot;boxes&quot; consisting of a text part and a chord part, and the width of the whole box should be the maximum of either parts, which each can consist of arbitrarily long text:</p>
  <pre><code>Am         Cmaj7/G  Am G        F Am/G      E7  F#sus4 A
  longstuff  short    multichord  more   end.     e  -   ternal
  </code></pre>
  <p>The boxing structure is known in advance, so you can assume it as given:</p>
  <pre><code>((Am) (longstuff)) 
  ((Cmaj7/G) (short)) 
  ((Am G) (multichord))
  ((F Am/G) (more))
  end.
  ((E7) ())
  ((F#sus4 A) (e))ternal
  </code></pre>
  <p>Note that in the last box, the word is hyphenated to compensate for the two chords on the first syllable.  I fear this makes it very hard for CSS, so it might be represented in a slightly different way, e.g.</p>
  <pre><code>((F#sus4 A) (e) (ternal))
  </code></pre>
  <p>You can come up with alternatives, as long as they still have concise semantic meaning.  Here is what I have come up with so far:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="false" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>.verse {
      line-height: 3rem;
      font-family: serif;
  }
  
  .cbox {
      border: 1px solid;
  }
  
  .chord {
      position: absolute;
      transform: translate(0, -1.1rem);
      font-weight: bold;
      font-family: monospace;
      user-select: none;
      font-size: large;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;p class="verse"&gt;
      Test
      &lt;span class="cbox"&gt;&lt;span class="chord"&gt;Abc&lt;/span&gt;X&lt;/span&gt;
      &lt;span class="cbox"&gt;&lt;span class="chord"&gt;Abc&lt;/span&gt;Xyzwv&lt;/span&gt;
      &lt;span class="cbox"&gt;&lt;span class="chord"&gt;Abc&lt;/span&gt;Xyzw&lt;/span&gt;abc
      sd
      &lt;br/&gt;
      Test
      &lt;span class="cbox"&gt;&lt;span class="chord"&gt;Abc De&lt;/span&gt;Xy&lt;/span&gt;zwv
      sd
      &lt;br/&gt;
      &lt;span class="cbox"&gt;&lt;span class="chord"&gt;Ab&lt;/span&gt;xyz&lt;/span&gt;
      &lt;span class="cbox"&gt;&lt;span class="chord"&gt;Abc#sus4/C&lt;/span&gt;Zyzw xyz&lt;/span&gt;
      &lt;span class="cbox"&gt;&lt;span class="chord"&gt;Am&lt;/span&gt;xyzw&lt;/span&gt;
      &lt;br/&gt;
      &lt;span class="cbox"&gt;&lt;span class="chord"&gt;D&lt;/span&gt;xyz&lt;/span&gt;
      &lt;span class="cbox""&gt;&lt;span class="chord"&gt;E7&lt;/span&gt;&lt;/span&gt;
      two
      &lt;span class="cbox"&gt;&lt;span class="chord"&gt;E7&lt;/span&gt;th&lt;/span&gt;ree
  &lt;/p&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>The sizes and borders are chosen for debugging.  As you can see, the width of the top (chord) part is not taken into account (because <code>position: absolute</code> prevents that).</p>
  <p>I have tried some other variants, including this one: <code>&lt;span class=&quot;cbox&quot; data-w=&quot;2&quot; data-c=&quot;Am&quot;&gt;longstuff&lt;/span&gt;</code>, where <code>data-w</code> is the number of letters in the chord name to be used in the <code>min-width</code> of the span, and <code>data-c</code> being put into a <code>before</code> pseudo-element, but I still didn't succeed at getting the width right.</p>
  <p>For the hyphenation issue, I have no idea at all.</p>
  <p>And I will likely be using XHTML, although I guess this won't make much of a difference.</p>