Issue
My headings have negative letter-spacing
but I still want the typefaces ligatures to work ("ffi", "ffl", "ffj", "fi", "fl", "fj", "ff"). I'm selecting these characters using JS, wrapping them in a span
and setting letter-spacing
to zero and hence the ligatures work. But there is a weird behaviour. The ligatures work, but if there is a mix of ligatures in the same element, some no longer work. See below. In the first example the ffi ligature doesn't work, but in the second example it does. What's going on?
UPDATE On closer look if there is more than one glyph in an element, the browser is choosing the "fi" glyph over the "ffi" glyph. Weird!
// add 'glyph' class to ligatures
let ligatures = ["ffi", "ffl", "ffj", "fi", "fl", "fj", "ff"];
// select ligatures within h1 element. Other elements can be added by seperating them with a comma
highlightLigatures(document.querySelectorAll("h1"), ligatures);
function highlightLigatures(elements, substrings) {
elements.forEach((el) => {
highlightText(el, substrings, "glyph");
});
}
function highlightText(el, substrings, classNames = "glyph") {
substrings.forEach((substring) => {
let regex = new RegExp(`(${substring})`, "gi");
el.childNodes.forEach((childNode) => {
if (childNode.nodeValue && regex.test(childNode.nodeValue)) {
childNode.parentNode.innerHTML = childNode.parentNode.innerHTML.replace(
regex,
`<span class="${classNames}">${substring}</span>`
);
}
});
});
}
h1 {
font-size: 4rem;
font-family: georgia;
font-family: 'Cormorant Garamond', serif;
font-weight: 400
margin: 0;
letter-spacing: -0.08em;
}
.glyph {
letter-spacing: 0;
color: red;
}
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond&display=swap" rel="stylesheet">
<h1>Office (the ffi ligature is not working) Often Oficial Offset</h1>
<h1>Office (the ffi ligature is working)</h1>
Solution
The code ends up wrapping ffi
as <span class="glyph">f<span class="glyph">fi</span></span>
, because it replaces the ffi
to <span class="glyph">ffi</span>
first, and then goes on to find fi
in that again later on. And apparently Safari has a problem recognizing such combinations of characters that would justify showing the ligature version, when they are distributed across multiple elements.
Trying to modify the logic to recognize that the found text is inside a .glyph
element already, would probably be a bit more complex matter - so as an easier workaround, we can replace the superfluous elements with their mere text content again, using
el.querySelectorAll('.glyph').forEach((e => e.innerHTML = e.innerText));
after the replacements are all done.
Answered By - CBroe
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.