Skip to content

Instantly share code, notes, and snippets.

@aaronbarker
Created May 18, 2023 21:57
Show Gist options
  • Save aaronbarker/b8a31a97c438ceff340a73297a73d192 to your computer and use it in GitHub Desktop.
Save aaronbarker/b8a31a97c438ceff340a73297a73d192 to your computer and use it in GitHub Desktop.
Ensign:Serif vs Fallbacks
<link rel="stylesheet" type="text/css" href="https://foundry.churchofjesuschrist.org/Foundry/v1/Ensign:Serif:400/css" media="all" />
<link rel="stylesheet" type="text/css" href="https://foundry.churchofjesuschrist.org/Foundry/v1/Ensign:Serif:700/css" media="all" />
<link rel="stylesheet" type="text/css" href="https://foundry.churchofjesuschrist.org/Foundry/v1/Ensign:Serif:Italic:400/css" media="all" />
<link rel="stylesheet" type="text/css" href="https://foundry.churchofjesuschrist.org/Foundry/v1/Ensign:Serif:Italic:700/css" media="all" />
<p>This uses some newer features to adjust a font to be more like another font. This allows us to make a fallback font look more like a desired custom font.</p>
<p>Metrics within a font-face declaration:
ascent-override <a href="https://caniuse.com/mdn-api_fontface_ascentoverride">73.75%</a> (no safari)
descent-override <a href="https://caniuse.com/mdn-api_fontface_descentoverride">73.75%</a> (no safari)
size-adjust <a href="https://caniuse.com/mdn-css_at-rules_font-face_size-adjust">73.75%</a> (no safari)
<br /> <a href="https://bugs.webkit.org/show_bug.cgi?id=219735">Webkit has a bug for it</a> but has not officially responded or said they are doing anything with it.
</p>
<p>Below the first column is the custom font Zoram. The other two are potential fallbacks. <span class="bad">Red elements</span> mean the overall height of the element of the fallback is different than the custom font element, so there would be a shift when transitioning from fallback to custom. A <span class="good">green element</span> means the height is the same and there would be no vertical shift. Click the checkbox below to toggle the fixed fallback fonts</p>
<p>Content to use (can replace with other languages to see how they work)<br />
<textarea id="content">My dear brothers and sisters, it is a joy to be with you. During these past six months, you have been constantly on my mind and in my prayers. I pray that the Holy Ghost will communicate what the Lord wants you to hear as I speak to you now.
During my surgical internship many years ago, I assisted a surgeon who was amputating a leg filled with highly infectious gangrene. The operation was difficult. Then, to add to the tension, one of the team performed a task poorly, and the surgeon erupted in anger. In the middle of his tantrum, he threw his scalpel loaded with germs. It landed in my forearm!
Everyone in the operating room—except the out-of-control surgeon—was horrified by this dangerous breach of surgical practice. Gratefully, I did not become infected. But this experience left a lasting impression on me. In that very hour, I promised myself that whatever happened in my operating room, I would never lose control of my emotions. I also vowed that day never to throw anything in anger—whether it be scalpels or words.
Even now, decades later, I find myself wondering if the contaminated scalpel that landed in my arm was any more toxic than the venomous contention that infects our civic dialogue and too many personal relationships today. Civility and decency seem to have disappeared during this era of polarization and passionate disagreements.
Vulgarity, faultfinding, and evil speaking of others are all too common. Too many pundits, politicians, entertainers, and other influencers throw insults constantly. I am greatly concerned that so many people seem to believe that it is completely acceptable to condemn, malign, and vilify anyone who does not agree with them. Many seem eager to damage another’s reputation with pathetic and pithy barbs!
Anger never persuades. Hostility builds no one. Contention never leads to inspired solutions. Regrettably, we sometimes see contentious behavior even within our own ranks. We hear of those who belittle their spouses and children, of those who use angry outbursts to control others, and of those who punish family members with the “silent treatment.” We hear of youth and children who bully and of employees who defame their colleagues.
My dear brothers and sisters, this should not be. As disciples of Jesus Christ, we are to be examples of how to interact with others—especially when we have differences of opinion. One of the easiest ways to identify a true follower of Jesus Christ is how compassionately that person treats other people.
The Savior made this clear in His sermons to followers in both hemispheres. “Blessed are the peacemakers,” He said. “Whosoever shall smite thee on thy right cheek, turn to him the other also.” And then, of course, He gave the admonition that challenges each of us: “Love your enemies, bless them that curse you, do good to them that hate you, and pray for them which despitefully use you, and persecute you.”
Before His death, the Savior commanded His Twelve Apostles to love one another as He had loved them. And then He added, “By this shall all men know that ye are my disciples, if ye have love one to another.”
The Savior’s message is clear: His true disciples build, lift, encourage, persuade, and inspire—no matter how difficult the situation. True disciples of Jesus Christ are peacemakers.
Today is Palm Sunday. We are preparing to commemorate the most important and transcendent event ever recorded on earth, which is the Atonement and Resurrection of the Lord Jesus Christ. One of the best ways we can honor the Savior is to become a peacemaker.
The Savior’s Atonement made it possible for us to overcome all evil—including contention. Make no mistake about it: contention is evil! Jesus Christ declared that those who have “the spirit of contention” are not of Him but are “of the devil, who is the father of contention, and [the devil] stirreth up the hearts of men to contend with anger, one with another.” Those who foster contention are taking a page out of Satan’s playbook, whether they realize it or not. “No man can serve two masters.” We cannot support Satan with our verbal assaults and then think that we can still serve God.
My dear brothers and sisters, how we treat each other really matters! How we speak to and about others at home, at church, at work, and online really matters. Today, I am asking us to interact with others in a higher, holier way. Please listen carefully. “If there is anything virtuous, lovely, or of good report or praiseworthy” that we can say about another person—whether to his face or behind her back—that should be our standard of communication.
If a couple in your ward gets divorced, or a young missionary returns home early, or a teenager doubts his testimony, they do not need your judgment. They need to experience the pure love of Jesus Christ reflected in your words and actions.
If a friend on social media has strong political or social views that violate everything you believe in, an angry, cutting retort by you will not help. Building bridges of understanding will require much more of you, but that is exactly what your friend needs.
Contention drives away the Spirit—every time. Contention reinforces the false notion that confrontation is the way to resolve differences; but it never is. Contention is a choice. Peacemaking is a choice. You have your agency to choose contention or reconciliation. I urge you to choose to be a peacemaker, now and always.
Brothers and sisters, we can literally change the world—one person and one interaction at a time. How? By modeling how to manage honest differences of opinion with mutual respect and dignified dialogue.
Differences of opinion are part of life. I work every day with dedicated servants of the Lord who do not always see an issue the same way. They know I want to hear their ideas and honest feelings about everything we discuss—especially sensitive issues.
President Dallin H. Oaks and President Henry B. Eyring
My two noble counselors, President Dallin H. Oaks and President Henry B. Eyring, are exemplary in the way they express their feelings—especially when they may differ. They do so with pure love for each other. Neither suggests that he knows best and therefore must rigorously defend his position. Neither evidences the need to compete with the other. Because each is filled with charity, “the pure love of Christ,” our deliberations can be guided by the Spirit of the Lord. How I love and honor these two great men!
Charity is the antidote to contention. Charity is the spiritual gift that helps us to cast off the natural man, who is selfish, defensive, prideful, and jealous. Charity is the principal characteristic of a true follower of Jesus Christ. Charity defines a peacemaker.
When we humble ourselves before God and pray with all the energy of our hearts, God will grant us charity.
Those blessed with this supernal gift are long-suffering and kind. They do not envy others and are not caught up in their own importance. They are not easily provoked and do not think evil of others.
Brothers and sisters, the pure love of Christ is the answer to the contention that ails us today. Charity propels us “to bear one another’s burdens” rather than heap burdens upon each other. The pure love of Christ allows us “to stand as witnesses of God at all times and in all things”—especially in tense situations. Charity allows us to demonstrate how men and women of Christ speak and act—especially when under fire.
Now, I am not talking about “peace at any price.” I am talking about treating others in ways that are consistent with keeping the covenant you make when you partake of the sacrament. You covenant to always remember the Savior. In situations that are highly charged and filled with contention, I invite you to remember Jesus Christ. Pray to have the courage and wisdom to say or do what He would. As we follow the Prince of Peace, we will become His peacemakers.
At this point you may be thinking that this message would really help someone you know. Perhaps you are hoping that it will help him or her to be nicer to you. I hope it will! But I also hope that you will look deeply into your heart to see if there are shards of pride or jealousy that prevent you from becoming a peacemaker.
If you are serious about helping to gather Israel and about building relationships that will last throughout the eternities, now is the time to lay aside bitterness. Now is the time to cease insisting that it is your way or no way. Now is the time to stop doing things that make others walk on eggshells for fear of upsetting you. Now is the time to bury your weapons of war. If your verbal arsenal is filled with insults and accusations, now is the time to put them away. You will arise as a spiritually strong man or woman of Christ.
The temple can help us in our quest. There we are endowed with God’s power, giving us the ability to overcome Satan, the instigator of all contention. Cast him out of your relationships! Note that we also rebuke the adversary every time we heal a misunderstanding or refuse to take offense. Instead, we can show the tender mercy that is characteristic of true disciples of Jesus Christ. Peacemakers thwart the adversary.
Let us as a people become a true light on the hill—a light that “cannot be hid.” Let us show that there is a peaceful, respectful way to resolve complex issues and an enlightened way to work out disagreements. As you demonstrate the charity that true followers of Jesus Christ manifest, the Lord will magnify your efforts beyond your loftiest imagination.
The gospel net is the largest net in the world. God has invited all to come unto Him, “black and white, bond and free, male and female.” There is room for everyone. However, there is no room for prejudice, condemnation, or contention of any kind.
My dear brothers and sisters, the best is yet to come for those who spend their lives building up others. Today I invite you to examine your discipleship within the context of the way you treat others. I bless you to make any adjustments that may be needed so that your behavior is ennobling, respectful, and representative of a true follower of Jesus Christ.
I bless you to replace belligerence with beseeching, animosity with understanding, and contention with peace.
God lives! Jesus is the Christ. He stands at the head of this Church. We are His servants. He will help us to become His peacemakers. I so testify in the sacred name of Jesus Christ, amen.</textarea></p>
<p class="checkboxes"><label><input type="checkbox" id="useFixedFallback" /> Use fixed fallback fonts</label> | <label><input type="checkbox" id="positionFallback1" /> Put Fallback 1 on top of Ensign</label> <label><input type="checkbox" id="positionFallback2" /> Put Fallback 2 on top of Ensign</label>
|
Main content settings:
<label><input type="checkbox" id="italic"> Italic</label>
<label>
<select id="weight">
<option>300</option>
<option>400</option>
<option>600</option>
<option>700</option>
</select>
</label>
<label>Font-size:
<select id="fontsize">
<option>11</option>
<option>13</option>
<option>14</option>
<option>16</option>
<option selected>18</option>
<option>20</option>
<option>28</option>
<option>32</option>
<option>42</option>
</select>
</label>
</p>
<div class="comparison">
<div id="control" class="column">
<h2>Ensign:Sans - <span class="count"></span> elements</h2>
<div class="content">
<div class="weightStyles">
<p class="w300">300 - The Quick Brown Fox Jumped Over the Lazy Dog</p>
<p class="w300 sItalic">Italic:300 - The Quick Brown Fox Jumped Over the Lazy Dog</p>
<p class="w400">400 - The Quick Brown Fox Jumped Over the Lazy Dog</p>
<p class="w400 sItalic">Italic:400 - The Quick Brown Fox Jumped Over the Lazy Dog</p>
<p class="w600">600 - The Quick Brown Fox Jumped Over the Lazy Dog</p>
<p class="w600 sItalic">Italic:600 - The Quick Brown Fox Jumped Over the Lazy Dog</p>
<p class="w700">700 - The Quick Brown Fox Jumped Over the Lazy Dog</p>
<p class="w700 sItalic">Italic:700 - The Quick Brown Fox Jumped Over the Lazy Dog</p>
</div>
<div class="body-block">
</div>
</div>
</div>
<div id="fallback1" class="fallback1 fallback column">
<h2>Fallback 1 (Georgia) - <span class="good-count good"></span> <span class="bad-count bad"></span> <button>Hide</button></h2>
<div class="content"></div>
</div>
<div id="fallback2" class="fallback2 fallback column">
<h2>Fallback 2 (Times New Roman) - <span class="good-count good"></span> <span class="bad-count bad"></span> <button>Hide</button></h2>
<div class="content"></div>
</div>
</div>
<!--
Latin Extended
Uppercase
ÀÁÂÃÄÅÆÇÈÉ ÊËÌÍÎÏÐÑÒÓ ÔÕÖØÙÚÛÜÝÞ ĀĂĄĆĈĊČĎĐĒ ĔĖĘĚĜĞĠĢĤĦ ĨĪĬĮİIJĴĶĹĻ ĽĿŁŃŅŇŊŌŎŐ ŒŔŖŘŚŜŞŠŢŤ ŦŨŪŬŮŰŲŴŶŸ ŹŻŽǺǼǾȘȚẀẂ ẄẞỲ
Lowercase
µßàáâãäåæç èéêëìíîïðñ òóôõöøùúûü ýþÿāăąćĉċč ďđēĕėęěĝğġ ģĥħĩīĭįıijĵ ķĸĺļľŀłńņň ʼnŋōŏőœŕŗřś ŝşšţťŧũūŭů űųŵŷźżžſƒǻ ǽǿșțȷẁẃẅỳ
Greek
Uppercase
ΆΈΉΊΌΎΏΑΒΓ ΔΕΖΗΘΙΚΛΜΝ ΞΟΠΡΣΤΥΦΧΨ ΩΪΫ
Lowercase
ΐάέήίΰαβγδ εζηθικλμνξ οπρςστυφχψ ωϊϋόύώ
Cyrillic
Uppercase
ЁЂЃЄЅІЇЈЉЊ ЋЌЎЏАБВГДЕ ЖЗИЙКЛМНОП РСТУФХЦЧШЩ ЪЫЬЭЮЯҐ
Lowercase
абвгдежзий клмнопрсту фхцчшщъыьэ юяёђѓєѕіїј љњћќўџґ
/*Latin Extended-A*/
unicode-range:u+100-137,u+139-17f;
/*Latin Extended-B*/
unicode-range:u+180-181,u+186-18a,u+18e-194,u+196-19a,u+19d-1a1,u+1a4-1a5,u+1a9-1aa,u+1ac-1b7,u+1c0-1f5,u+1f8-21b,u+21e-220,u+226-233,u+237,u+23a-24f;
/*Cyrillic*/
unicode-range:u+400-45f,u+462-463,u+472-477,u+490-4c2,u+4cf-4f9;
/*Cyrillic Supplement*/
unicode-range:u+500-51f,u+524-525;
Font stacks from Eden
export const sans = `"Ensign:Sans", Arial, "noto sans" , sans-serif`;
export const serif = `"Ensign:Serif", "Georgia", "Times New Roman", serif`;
System fonts for OS that match current stack
iOS/maOS (https://developer.apple.com/fonts/system-fonts/)
- Georgia, Times New Roman
- Arial, noto sans (listed by name, not just a generic "Noto sans")
Windows 10
- Georgia, Times New Roman
- Arial
Android (https://wiki.mobileread.com/wiki/List_of_fonts_included_with_each_device#Android_Devices)
- Droid Serif
- Droid Sans
-->
const comparisonElem = document.querySelector(".comparison");
const controlContents = document.querySelector(".content");
const contentElem = document.querySelector("#content");
const elemSelector = "p";
const fallbacks = document.querySelectorAll(".fallback");
const checkElemMetrics = (elem, index, isFallback) => {
elem.classList.remove("good");
elem.classList.remove("bad");
if (elem.querySelector(".results")) elem.querySelector(".results").remove();
const controlElems = isFallback
? controlContents.querySelectorAll(elemSelector)
: "";
const controlP = isFallback
? control.querySelector(`p:nth-child(${index + 1}`)
: "";
// console.log(p, controlP)
const { y, height } = elem.getBoundingClientRect();
// console.log(p.getBoundingClientRect(), index);
const box = document.createElement("div");
box.className = "results";
let topClass, heightClass;
if (isFallback) {
const curElem = controlElems[index];
// console.log(curElem);
// compare heights
if (curElem?.offsetTop === elem.offsetTop) {
topClass = "good";
} else {
topClass = "bad";
}
if (curElem?.offsetHeight === elem.offsetHeight) {
heightClass = "good";
} else {
heightClass = "bad";
}
elem.classList.add(heightClass);
}
let theText = `
<!-- <div>Top: <span class="${topClass}">${elem.offsetTop}px</span></div> -->
<div>Height: <span class="${heightClass}">${elem.offsetHeight}px</span></div>`;
box.innerHTML = theText;
elem.appendChild(box);
};
const updateFallback = (fallback) => {
fallback.querySelectorAll(elemSelector).forEach((elem, index) => {
checkElemMetrics(elem, index, true);
});
fallback.querySelector(".good-count").innerText = fallback.querySelectorAll(`:is(${elemSelector}) .good`
).length;
fallback.querySelector(".bad-count").innerText = fallback.querySelectorAll(
`:is(${elemSelector}) .bad`
).length;
};
// update the metrics of each column
const checkAllMetrics = () => {
document.querySelectorAll(`#control :is(${elemSelector}`).forEach((elem, index) => {
checkElemMetrics(elem, index);
});
fallbacks.forEach((fallback) => updateFallback(fallback));
}
// regularly checking for any css changes that wouldn't trigger a re-check
setInterval(checkAllMetrics, 1000);
// copy content of the control column into the columns for the fallbacks
const updateContent = () => {
const theContent = contentElem.value;
// Split the text into lines
const lines = theContent.split("\n");
// Wrap each line in a paragraph tag
const paragraphs = lines.map((line) => `<p>${line}</p>`);
// Join the paragraphs together with line breaks
let htmldContent = paragraphs.join("\n");
// replace any empty p due to extra whitespace in original text
htmldContent = htmldContent.replace(/<p>\s*<\/p>/g, "");
// console.log(htmldContent);
controlContents.querySelector(".body-block").innerHTML = htmldContent;
// copy content of control into fallbacks
fallbacks.forEach((fallback) => {
fallback.querySelector(".content").innerHTML = "";
fallback.querySelector(".content").append(controlContents.cloneNode(true));
});
control.querySelector(".count").innerText = control.querySelectorAll(
elemSelector
).length;
};
// run it initially
updateContent();
// Hook up form fields
content.addEventListener("change", updateContent);
useFixedFallback.addEventListener("click", (event) => {
console.log(event);
if (event.target.checked) {
comparisonElem.classList.add("use-customizations");
} else {
comparisonElem.classList.remove("use-customizations");
}
checkAllMetrics();
});
positionFallback1.addEventListener("click", (event) => {
if (event.target.checked) {
fallback1.classList.add("position");
} else {
fallback1.classList.remove("position");
}
});
positionFallback2.addEventListener("click", (event) => {
if (event.target.checked) {
fallback2.classList.add("position");
} else {
fallback2.classList.remove("position");
}
});
italic.addEventListener("click", (event) => {
setBodyStyle();
});
fontsize.addEventListener("change", (event) => {
setBodyStyle();
});
weight.addEventListener("change", (event) => {
setBodyStyle();
});
document.querySelectorAll("button").forEach(button => {
button.addEventListener("click",(event) => {
event.target.closest('.fallback').remove();
});
});
const setBodyStyle = () => {
const newStyle = `font-weight: ${weight.value}; font-style:${italic.checked ? "italic":"normal"}; font-size: ${fontsize.value}px`;
console.log({newStyle})
document.querySelectorAll(".body-block").forEach(bb => {
bb.setAttribute("style", newStyle);
});
checkAllMetrics();
};
// From Eden font component
export const serifList = ["400", "Italic:400", "700", "Italic:700"];
export const sansList = [
"300",
"Italic:300",
"400",
"Italic:400",
"600",
"Italic:600",
"700",
"Italic:700",
];
const fontFace = ({ font, weight, fontFamily }) => {
// This currently only looks to adjust latin based languages
const UnicodeRange = "u+9-a, u+d, u+20-7e";
const [fontStyle, fontWeight] =
weight.indexOf(":") !== -1 ? weight.split(":") : ["Normal", weight];
const fontOverride = fontOverrides[font.toLowerCase()][fontFamily][weight];
if (!fontOverride) return;
return `
@font-face {
src: local(${fontOverride.localName.indexOf(" ") !== -1 ? `"${fontOverride.localName}"` : fontOverride.localName});
font-family: "${fontFamily}";
font-style: ${fontStyle};
font-weight: ${fontWeight};
// unicode-range: ${UnicodeRange};
ascent-override: ${fontOverride.ascentOverride};
descent-override: ${fontOverride.descentOverride};
size-adjust: ${fontOverride.sizeAdjust};
}
`;
};
const FallbackFixes = ({ serif, sans, rel }) => {
if (rel !== "preload") return null;
// loop through each serif and sans and create a font-face for each
let fixes = [];
serif.forEach((weight) => {
fixes.push(fontFace({ font: "serif", weight, fontFamily: "Georgia" }));
fixes.push(
fontFace({ font: "serif", weight, fontFamily: "Times New Roman" })
);
});
sans.forEach((weight) => {
// fixes.push(fontFace({ font: "sans", weight, fontFamily: "Arial" }));
// fixes.push(fontFace({ font: "sans", weight, fontFamily: "Roboto" }));
});
return `<style>${fixes.join("")}</style>`;
};
export const fontOverrides = {
serif: {
Georgia: {
400: {
localName: "Georgia",
ascentOverride: "75%",
descentOverride: "27%",
sizeAdjust: "104.9%",
},
"Italic:400": {
localName: "Georgia Italic",
ascentOverride: "75%",
descentOverride: "34%",
sizeAdjust: "92.7%",
},
700: {
localName: "Georgia Bold",
ascentOverride: "75%",
descentOverride: "27%",
sizeAdjust: "94.4%",
},
"Italic:700": {
localName: "Georgia Bold Italic",
ascentOverride: "70%",
descentOverride: "27%",
sizeAdjust: "85.8%",
},
},
"Times New Roman": {
400: {
localName: "Times New Roman",
ascentOverride: "75%",
descentOverride: "13%",
sizeAdjust: "115.3%",
},
"Italic:400": {
localName: "Times New Roman Italic",
ascentOverride: "75%",
descentOverride: "34%",
sizeAdjust: "103.5%",
},
700: {
localName: "Times New Roman Bold",
ascentOverride: "75%",
descentOverride: "27%",
sizeAdjust: "111%",
},
"Italic:700": {
localName: "Times New Roman Bold Italic",
ascentOverride: "75%",
descentOverride: "27%",
sizeAdjust: "107%",
},
},
},
sans: {
Arial: {
300: {
localName: "Arial",
ascentOverride: "100%",
descentOverride: "27%",
sizeAdjust: "100%",
},
"Italic:300": {
localName: "Arial Italic",
ascentOverride: "108%",
descentOverride: "34%",
sizeAdjust: "95%",
},
400: {
localName: "Arial",
ascentOverride: "108%",
descentOverride: "27%",
sizeAdjust: "105%",
},
"Italic:400": {
localName: "Arial Italic",
ascentOverride: "108%",
descentOverride: "34%",
sizeAdjust: "100%",
},
600: {
localName: "Arial",
ascentOverride: "108%",
descentOverride: "27%",
sizeAdjust: "109%",
},
"Italic:600": {
localName: "Arial Italic",
ascentOverride: "104%",
descentOverride: "27%",
sizeAdjust: "103%",
},
700: {
localName: "Arial Bold",
ascentOverride: "104%",
descentOverride: "27%",
sizeAdjust: "104%",
},
"Italic:700": {
localName: "Arial Bold Italic",
ascentOverride: "104%",
descentOverride: "27%",
sizeAdjust: "100%",
},
},
"Roboto": {
300: {
localName: "Roboto",
ascentOverride: "100%",
descentOverride: "27%",
sizeAdjust: "100%",
},
"Italic:300": {
localName: "Roboto Italic",
ascentOverride: "108%",
descentOverride: "34%",
sizeAdjust: "97.5%",
},
400: {
localName: "Roboto",
ascentOverride: "108%",
descentOverride: "27%",
sizeAdjust: "104%",
},
"Italic:400": {
localName: "Roboto Italic",
ascentOverride: "108%",
descentOverride: "34%",
sizeAdjust: "103.5%",
},
600: {
localName: "Roboto",
ascentOverride: "108%",
descentOverride: "27%",
sizeAdjust: "110%",
},
"Italic:600": {
localName: "Roboto Italic",
ascentOverride: "104%",
descentOverride: "27%",
sizeAdjust: "105.5%",
},
700: {
localName: "Roboto Bold",
ascentOverride: "104%",
descentOverride: "27%",
sizeAdjust: "112%",
},
"Italic:700": {
localName: "Roboto Bold Italic",
ascentOverride: "104%",
descentOverride: "27%",
sizeAdjust: "108%",
},
},
},
};
// Use the above eden stuff and make some codepen specific tweaks and insert it
const getFallbackFixes = FallbackFixes({serif:serifList, sans:sansList, rel:"preload"});
// console.log(getFallbackFixes);
document.querySelector("#theFixes")?.remove();
const newStyle = document.createElement("style");
newStyle.setAttribute("id", "theFixes");
document.querySelector("head").appendChild(newStyle);
newStyle.innerHTML = getFallbackFixes.replace("<style>","").replace("</style>","")
// Need to have a different family name for the override so we can toggle it
.replaceAll("family: \"Arial\"","family: \"ArialFixed\"")
.replaceAll("family: \"Roboto\"","family: \"RobotoFixed\"")
.replaceAll("family: \"Georgia\"","family: \"GeorgiaFixed\"")
.replaceAll("family: \"Times New Roman\"","family: \"TimesNewRomanFixed\"");
console.log(newStyle.innerHTML);
/* Font specific */
#control {
font-family: "Ensign:Serif";
}
.fallback1 {
font-family: Georgia;
}
.use-customizations .fallback1 {
font-family: GeorgiaFixed;
}
.fallback2 {
font-family: "Times New Roman";
}
.use-customizations .fallback2 {
font-family: TimesNewRomanFixed;
}
/* Tool specific */
.w300 {
font-weight: 300;
}
.w400 {
font-weight: 400;
}
.w600 {
font-weight: 600;
}
.w700 {
font-weight: 700;
}
.sItalic {
font-style: italic;
}
/* Font overrides are in JS now so we can use the same JSON that we will use internally for dynamic insertion based on what is actually used */
/* Not font specific stuff */
.position {
position:absolute;
}
.column {
max-width: 512px;
}
.content p {
line-height: 1.6;
margin-bottom: 0.889em;
/* font-size: 18px; */
margin-top: 0;
position: relative;
}
.content h1 {
/* margin: 0px; */
line-height: 1.2;
position: relative;
/* background: #f1f1f1; */
}
.headings, .weightStyles {
max-height: 280px;
overflow: auto;
}
.good {
color: green;
}
.bad {
color: red;
}
.comparison {
display: flex;
gap: 10px;
}
.results {
position: absolute;
bottom:0;
right:0;
padding:2px 5px;
background: white;
opacity: .5;
font-size: 12px;
border: 1px solid #ccc;
}
*:hover > .results {
opacity: 1;
}
h2 {
height: 30px;
}
textarea {
height: 100px;
width: 500px;
}
.checkboxes {
background: white;
position: sticky;
top: 0;
z-index: 1;
}
body {
/* font-family: courier; */
}
.weightStyles {
font-size: 26px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment