14

I'd like to be able to show chords above the lyrics in music using CSS. This is what I'd really like it to look like:

C                                           F
This line has a C chord, and it also has an F chord

so that the chord changes are shown in the right places. In HTML it looks like this:

<span class="chord">C</span>This line has a C chord, and it also has an <span class="chord">F</span>F chord

And I managed to nearly get the effect with this styling:

.chord {
  position: relative;
  top: -1em;
}

But the problem is that it has gaps:

C                                            F
 This line has a C chord, and it also has an  F chord

If only width:0 (which I would use with overflow:visible) worked on an inline span. Does anyone have a solution?

Edit: Solved thanks to @Kyle Sevenoaks. For anyone who's interested, here's my complete CSS, which allows verses to be marked with <p>, chords to be marked with <span> and whether chords are displayed to be toggled with the show-chords class on the parent div:

p.song span {
  display: none;
}
p.song.show-chords p {
  line-height:2.3em;
  margin-bottom:2em;
}
p.song.show-chords span {
  position: relative;
  top: -1em;
  display:inline-block;
  width: 0;
  overflow:visible;
  text-shadow:#CCC -1px 1px;
  color:#00F;
  font-weight:bold;
  font-family:Arial, Helvetica, sans-serif;
}
<p class="song show-chords">
  <span class="chord">C</span>This line has a C chord, and it also has an <span class="chord">F</span>F chord
</p>
oliverpool
  • 1,624
  • 13
  • 30
Nathan MacInnes
  • 11,033
  • 4
  • 35
  • 50
  • have you ever tried adding also a left: 10px; ? or do you need a more flexible solution? –  Nov 11 '10 at 11:47
  • do you have any solution to make this stylesheet becomes mobile friendly? When i see it in my mobile phone, the chord is not at the right place – calvin sugianto Oct 10 '17 at 05:27

3 Answers3

6

Yeah, position: relative still reserves the space needed.

Here is a solution that wraps a position: absolute span around the relatively positioned one, so that the space does not get reserved any more:

 <span class="chord">
  <span class="inner">C</span>
 </span>This line has a C chord, and it also has an 
 <span class="chord">
  <span class="inner">F</span>
 </span>F chord

CSS:

.chord { position: absolute
 }

.chord .inner {  position: relative;
    top: -1em;}

The advantage over the left approach is that this will work for any chord width (think Esus or F7.

JSFiddle here. Tested in IE6,7,8, Chrome 6

Pekka
  • 442,112
  • 142
  • 972
  • 1,088
6

Here is a variant using data-* attributes and :before pseudoclass

HTML:

<span data-chord="C">T</span>his line has a C chord, and it 
also has an <span data-chord="F">F</span> chord

CSS:

span[data-chord]:before {
    position    : relative;
    top         : -1em;
    display     : inline-block;
    content     : attr(data-chord);
    width       : 0;
    font-style  : italic;
    font-weight : bold;
}

http://jsfiddle.net/fcalderan/4wKkp/

  • This is quite an interesting way of doing it. It's like attaching a chord to a character instead of inserting it in somewhere. I've still gone for my original HTML structure because I do prefer it at the moment, but I'll keep this one in mind. – Nathan MacInnes Nov 11 '10 at 12:27
  • while I wrote this example I made some thoughts about semantic of this solution. It's true that without css enabled the information about chord is not accessible at all, but other solution like that you're using make lyrics less accessible since chord information 'breaks' the text. So I think there is not a unique solution. It depends. –  Nov 11 '10 at 12:35
  • Yes, but this will be used in a controlled environment where I can be sure that features will be supported. Thanks for the help. – Nathan MacInnes Nov 11 '10 at 12:39
  • Check the jsfiddle link, I've updated the example and increased aural accessibility. =) I will update it also next days If I come to a better idea. –  Nov 11 '10 at 12:57
2

For inline elements, you can use display: inline-block; to have it accept width. But for your problem, why not simply add left: 3px; /*em or whatever*/? It will indent it.

Kyle
  • 65,599
  • 28
  • 144
  • 152