Edwin ZAP
Edwin ZAP

Reputation: 463

Responsive chords above lyrics

I would like to use HTML and CSS (and if really necessary, some JS) to find a responsive way to put chords above lyrics. I already checked this post: Styling text to make it appear above the line (for chords above the lyrics) Here is what I have so far:

        body {
          padding:20px;
          font-size: 30px;
        }
        .chord{
            position    : absolute;
            top         : -50px;
            width       : 0;
            font-style  : italic;
            font-weight : bold;
            font-size: 50px;
        }

        .chord-lyrics{
            position: relative;
            display: inline-block;
            margin-top: 50px;
        }
<div class="line">
    <div class="chord-lyrics"><span class="chord">C</span> Imagine</div> there's 
    <div class="chord-lyrics"><span class="chord">Cmaj7</span>no</div>
    <div class="chord-lyrics"><span class="chord">F</span>heaven</div>
</div>

The goals:

  1. always keep the chord above the right lyrics
  2. if screen is smaller than the line, each word must overflow on the next line
  3. if the chords are larger than the text below it should create space between the lyrics EDIT:
  4. a chord can also be in the middle of a word

For now, everything works fine for 1. and 2. but not for 3. and this last one is also really important!

Thanks

Upvotes: 5

Views: 1193

Answers (5)

St3an
St3an

Reputation: 806

I'd rather do smthg like that :

div.part {
    float  : left;
    margin : .3em;
    
}
div.chord {
    font-weight : bolder;
    font-style  : italic;
}
div.lyric {
    text-align  : center;
}

            
  <div class="part">
      <div class="chord">C</div>
      <div class="lyric">Imagine</div>
  </div>
  <div class="part">
      <div class="chord">&nbsp;</div>
      <div class="lyric">there's</div>
  </div>
  <div class="part">
      <div class="chord">Cmaj7</div>
      <div class="lyric">no</div>
  </div>
  <div class="part">
      <div class="chord">F</div>
      <div class="lyric">heaven</div>
  </div>

Upvotes: 0

Edwin ZAP
Edwin ZAP

Reputation: 463

Thanks to everyone, here is what I was able to do:

body {
    padding: 20px;
    font-size: 30px;
}

.line {
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
}

.chord-letter {
    display: flex;
    flex-direction: column;
    align-items: left;
}

.no-space {
    margin-right: 0;
    border: solid 1px red;
}

.space {
    margin-right: 0.33em;
    border: solid 1px green;
}

.chord {
    color: gray;
    font-style: italic;
    font-weight: bold;
    font-size: 1.2em;
    border: solid 1px blue;
}

.no-space .chord {
    margin-right: 0.33em;
}

.word {
    display: flex;
    flex-direction: row;
    align-items: flex-end;
}
<div class="line">
   <div class="word">
      <span class="no-space">Ima</span>
      <div class="chord-letter space"><span class="chord">C</span>gine</div>
   </div>
   <span class="space">there's</span>
   <div class="chord-letter space"><span class="chord">Cmaj7</span>no</div>
   <div class="chord-letter space"><span class="chord">F</span>heaven</div>
   <div class="word">
      <span class="no-space">Ima</span>
      <div class="chord-letter space"><span class="chord">C</span>gine</div>
   </div>
</div>

It is:

  1. Fully responsive
  2. Allow chords inside a word
  3. Avoid breaking the words on wrapping

Upvotes: 0

coreuter
coreuter

Reputation: 3572

Another possibility is to use Flexbox:

body {
  padding: 20px;
  font-size: 30px;
}

.container {
  max-width: 450px;
}

.line {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
}

.chord-letter {
  display: flex;
  flex-direction: column;
  padding: 0 5px;
  align-items: center; /* center chord */
}

.chord {
  font-style: italic;
  font-weight: bold;
  font-size: 25px;
}
<div class="container">
  <div class="line">
    <div class="chord-letter"><span class="chord">C</span> Imagine</div> there's
    <div class="chord-letter"><span class="chord">Cmaj7</span>no</div>
    <div class="chord-letter"><span class="chord">F</span>heaven</div>
  </div>
</div>

This code is fully responsive. Each chord-text-combo will be moved to the next line if there's not enough space.

Here is a Fiddle for you to play with.

Upvotes: 3

BOZ
BOZ

Reputation: 2020

Alternatively, "flexbox" can be used.

body {
  padding: 20px;
  font-size: 30px;
}

.line {
  display: flex;
  align-items: flex-end;
  justify-content: start;
  flex-wrap: wrap;
}

.chord {
  font-style: italic;
  font-weight: bold;
  font-size: 50px;
}

.chord-lyrics {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: end;
}

.space {
  margin-right: .3em;
  margin-top: .3em;
  margin-bottom: .3em;
}
<div class="line">
  <div class="chord-lyrics space"><span class="chord">C</span> Imagine</div>
  <span class="space">there's</span>
  <div class="chord-lyrics space"><span class="chord">Cmaj7</span>no</div>
  <div class="chord-lyrics space"><span class="chord">F</span>heaven</div>
  <div class="chord-lyrics space"><span class="chord">C</span> Imagine</div>
  <span class="space">there's</span>
  <div class="chord-lyrics space"><span class="chord">Cmaj7</span>no</div>
  <div class="chord-lyrics space"><span class="chord">F</span>heaven</div>
  <div class="chord-lyrics space"><span class="chord">C</span> Imagine</div>
  <span class="space">there's</span>
  <div class="chord-lyrics space"><span class="chord">Cmaj7</span>no</div>
  <div class="chord-lyrics space"><span class="chord">F</span>heaven</div>
  <div class="chord-lyrics space"><span class="chord">F</span>heaven</div>
</div>


For your second question:

In overflows, the word and the chord behave as a whole, and the chord and word are always centered.

body {
  padding: 20px;
  font-size: 30px;
}

.line {
  display: flex;
  align-items: flex-end;
  justify-content: start;
  flex-wrap: wrap;
}

.chord {
  font-style: italic;
  font-weight: bold;
  font-size: 50px;
}

.chord-lyrics {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: end;
}

.space {
  margin-right: .3em;
  margin-top: .3em;
  margin-bottom: .3em;
}
<div class="line">
  <div class="chord-lyrics space"><span class="chord">C</span> Imagine</div>
  <span class="space">there's</span>
  <div class="chord-lyrics space"><span class="chord">Cmaj7</span>no</div>
  <div class="chord-lyrics space"><span class="chord">F</span>heaven</div>
  <div class="chord-lyrics space"><span class="chord">C</span> Imagine</div>
  <span class="space">there's</span>
  <div class="chord-lyrics space"><span class="chord">Cmaj7</span>no</div>
  <div class="chord-lyrics space"><span class="chord">F</span>heaven</div>
  <div class="chord-lyrics space"><span class="chord">C</span> Imagine</div>
  <span class="space">there's</span>
  <div class="chord-lyrics space"><span class="chord">Cmaj7</span>no</div>
  <div class="chord-lyrics space"><span class="chord">F</span>heaven</div>
  <div class="chord-lyrics space"><span class="chord">F</span>heaven</div>
</div>

Upvotes: 0

Luke
Luke

Reputation: 1181

Using position: absolute removes the elements from the flow of the page and prevents them from having an effect on the other elements.

If you change this to position: relative you can get something close to what you're looking for.

Just as a footnote, using px measurements isn't responsive. You should look to use ems, rems or even vw/vh!

        body {
          padding:20px;
          font-size: 30px;
        }
        .chord{
            position    : relative;
            top         : -50px;
            left        : 50px;
            width       : 0;
            font-style  : italic;
            font-weight : bold;
            font-size: 50px;
        }

        .chord-lyrics{
            position: relative;
            display: inline-block;
            margin-top: 50px;
        }
<div class="line">
    <div class="chord-lyrics"><span class="chord">C</span> Imagine</div> there's 
    <div class="chord-lyrics"><span class="chord">Cmaj7</span>no</div>
    <div class="chord-lyrics"><span class="chord">F</span>heaven</div>
</div>

Upvotes: 1

Related Questions