4

Is there a way to determine when font style is being actually rendered? early stage of breakpoint

having break point on early stage (which is right after DOM is created) shows that the paragraph's font family value is font 'Montserrat-Bold' which is added via @font-face css but an actual rendered display shows as default font.

break point after some amount of time

Here, break point after some amount of time shows that the paragraph element is actually styled (using font family) as it is to be expected.

I assume there's a process where browser actually renders (or apply) font style. Is there a way to know or to detect when that happens?

Chanwoo Park
  • 216
  • 1
  • 12
  • 1
    Does this answer your question? [How to be notified once a web font has loaded](https://stackoverflow.com/questions/5680013/how-to-be-notified-once-a-web-font-has-loaded) – Dorad Nov 26 '21 at 05:47
  • @Dorad sadly no :( document.fonts way can let one's know that a font is being loaded but my question is about when it is actually being "used" ("rendered", "applied") – Chanwoo Park Nov 26 '21 at 05:49

1 Answers1

1

Unfortunately there is no direct way (e.g. via CSS Font Loading API) to get the actually rendered font-family.

Workaround

  1. Check the applied font-families via getComputedStyle(el).fontFamily
  2. Check if fonts are loaded via FontFaceSet.check()

Example:

let info = document.querySelector('.info');
let textEls = document.querySelectorAll('h1, p, pre');
// check fonts - Monserrat is not yet available
let usedFonts = checkAppliedFont(textEls);

function checkAppliedFont(textEls){
  let usedFonts = [];
  textEls.forEach(function(el,i){
    let nodeType = el.nodeName.toLowerCase();
    let fontFamily = getComputedStyle(el).fontFamily;
    let familyArr = fontFamily.split(',');
    let fontApplied = false;
    let renderedFont = '';
    for(let i=0; i<familyArr.length && !fontApplied; i++){
      let currentFamily = familyArr[i];
      fontApplied = document.fonts.check(`12px ${currentFamily}`);
      if(fontApplied){
        //font is loaded - return family name
        renderedFont = currentFamily;
      }
    }
    usedFonts.push({ type:nodeType, font: renderedFont});
  })
  info.innerText = JSON.stringify(usedFonts)
  return usedFonts;
}


let fontUrl =  "https://fonts.gstatic.com/s/montserrat/v24/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Hw5aXo.woff2";
let fontFamily = "Montserrat";
let fontOptions = {
  weight: 400,
  style: "normal"
};

let webfont = '';
async function loadFonts() {
  const font = new FontFace(fontFamily, `url(${fontUrl})`);
  font.weight = fontOptions.weight ? fontOptions.weight : 400;
  font.style = fontOptions.style ? fontOptions.style : "normal";
  // wait for font to be loaded
  await font.load();
  webfont = font;
  document.fonts.add(font);
  checkAppliedFont(textEls);
}

function unloadFonts(font) {
  document.fonts.delete(font);
  checkAppliedFont(textEls);
}
h1{
  font-family:"Montserrat", Georgia;
  font-weight:400;
}

p{
  font-family:"Montserrat", Arial
}

pre{
  font-family:"Montserrat", monospace, sans-serif;
  background:#eee;
}
<button onclick="loadFonts()" type="button">Load font</button>
<button onclick="unloadFonts(webfont)" type="button">Delete font</button>
<h1>Should be Monserrat 1234</h1>
<p>Paragraph text.</p>
<pre>Pre text.</pre>
<p class="info"></p>

The above example will loop through all font-families specified in css rules (retrieved via getComputedStyle()).
E.g font-family:"Montserrat", monospace, sans-serif
Fonts that are not available will be skipped. The first available font is probably the rendered font.

Depending on your OS or browser, this workaround might fail to get the actually applied/rendered font.

herrstrietzel
  • 11,541
  • 2
  • 12
  • 34