I'm trying to write a simple HTML page to output music chords. I display randomly generated chords to practice chord changes (like using flashcards).
When I output a chord containing a "flat" symbol, the whole chord appears to jump down -- it increases the vertical height of the enclosing <div>
and appears at the bottom. The Other chords (with a "sharp" or without) appear as expected.
JSFiddle to demonstrate: https://jsfiddle.net/blatwell9/qjfcLtdv/3/
Is there a way to prevent the shift down from happening?
Shift down example
The code to demonstrate the effect. Note the effect when the backgrounds of the <div>
and the chord <span>
are displayed:
function showChord() {
document.getElementById("chord").innerHTML = chordList[chordIndex];
document.getElementById("chordWithLineHeight").innerHTML = chordList[chordIndex];
chordIndex++;
if (chordIndex > chordList.length -1) chordIndex = 0;
setTimeout(showChord, 1500);
}
let chordIndex = 0;
let chordList = ["♯","♭"];
showChord();
* {margin: 0; padding: 0;}
body {font-family: sans-serif;}
.chord-div {font-size: 3em; background: lightgreen; margin: .1em; }
#chord {background: lightblue;
border: 1px blue solid;}
#chordWithLineHeight {background: lightblue;
border: 1px blue solid;
line-height: 1}
<h3> No line-height set </h3>
<div class="chord-div">
<span id="chord"></span>
</div>
<h3> With line-height set </h3>
<div class="chord-div">
<span id="chordWithLineHeight"></span>
</div>
Op has pointed out that there's still a misalignment after my solution. So the original code presented by OP had float: left
in which I proved to be one of the problems. In my solution I have font-family: "Opus"
because it's used specifically for sheet music. So I assumed that was fixed, unfortunately, it turns out that font-family: sans-serif
is buggy and there's a misalignment with ♭. In conclusion, do not use float
unless you intend to wrap text around an <img>
and don't use sans-serif
, use "Opus", or "Helsinki XXL", or "Segoe UI" typeface. See Example A for the float
issue and Example B for font issue.
Float
IssueInstead of wasting time explaining why not to use float see this post. The example has two <section>
s:
The first <section>
contains only inline elements (ex. <span>
, <mark>
, <strong>
, etc.). They naturally sit next to each other.
The second <section>
contains block elements (ex. <div>
, <p>
, <section>
, etc.). They naturally take up the whole line they sit in so they stack one on top off the other. float
is supposed to arrange them inline.
As you can see the floating <div>
s are cock-eyed and the ♭ symbol has nothing to do with it. Just use inline elements, flexbox or grid layouts.
@import url('https://fonts.cdnfonts.com/css/opus');
* {
margin: 0;
padding: 0;
}
:root {
3ch/1.2 "Opus" "sans-serif";
}
mark {
margin: 0.1rem;
font-size: 3rem;
background: lightgreen;
}
div {
float: left;
}
<section>
<mark>A♯</mark>
<mark>A𝄪</mark>
<mark>A♭</mark>
<mark>A𝄫</mark>
<mark>A♮</mark>
</section>
<section>
<div>
<mark>A♯</mark>
</div>
<div>
<mark>A𝄪</mark>
</div>
<div>
<mark>A♭</mark>
</div>
<div>
<mark>A𝄫</mark>
</div>
<div>
<mark>A♮</mark>
</div>
</section>
const chords = ["♭", "♯", "A♭", "A♯", "A♯A♭", "A♮A𝄫A𝄪"];
let count = cycle(chords.length);
const showChords = (array, selector) => {
const tags = document.querySelectorAll(selector);
const i = count.next().value;
if (i === 0) tags.forEach(t => t.innerHTML = "");
tags.forEach(t => t.innerHTML += `<mark>${array[i]}</mark>`);
setTimeout(() => showChords(array, selector), 1500);
};
function* cycle(N) {
let i = 0;
while (true) {
++i;
i = i > (N - 1) ? 0 : i;
yield i;
}
}
showChords(chords, "p");
:root {
font: 2ch/normal "Segoe UI"
}
p {
font-size: 3rem;
background: lightgreen;
}
mark {
padding: 0 .1em;
outline: 1px blue solid;
background: lightblue;
}
p:nth-of-type(2) {
line-height: 1;
}
p:nth-of-type(3) {
font-family: sans-serif;
}
p:nth-of-type(4) {
line-height: 1;
font-family: sans-serif;
}
<main>
<h3>line-height: 1.2 (default) font-family: "Segoe UI"</h3>
<p></p>
<h3>line-height: 1; font-family: "Segoe UI"</h3>
<p></p>
<h3>line-height: 1.2; font-family: sans-serif</h3>
<p></p>
<h3>line-height: 1; font-family: sans-serif</h3>
<p></p>
</main>