What is the process to extract the displayed font using JavaScript?

One interesting feature of Google Chrome is that it displays the rendered font in DevTools.

For instance, when you have the CSS code:

font-family: Montserrat, Helvetica, sans-serif;

and the Montserrat font is not available or disabled, Chrome will indicate that Helvetica is actually being rendered:

https://i.sstatic.net/3zhKL.png

But here comes the question: Is there a way to retrieve the rendered font using JavaScript? (even if it only works in Chrome)


Points to consider:

  1. This potential solution proposes using getComputedStyle(...).fontFamily, however, it returns the CSS declaration
    "Montserrat, Helvetica, sans-serif"
    rather than the actual font being rendered.
  2. Another suggestion involves using puppeteer, but utilizing this tool may not be necessary if we can achieve the same result solely within DevTools (without puppeteer).

Answer №1

Currently, accessing this information from Web-APIs remains a challenge.

The Houdini group is in the midst of ongoing discussions regarding the potential inclusion of a font-metrics API. This API aims to provide detailed font usage data, but it has not yet progressed beyond the proposal stage. The path towards its implementation is expected to be complex and arduous.

Determining the specific fonts being used presents complexities due to the possibility of multiple fonts being employed at various levels within text content. In order to properly expose this information, proposed solutions suggest utilizing handles that contain comprehensive font details, including raw font data for web fonts. dbaron & eae are leading efforts in defining an appropriate API for this purpose.

An example scenario involves using one font for the glyph ̂ (U+0302), while another font may be utilized for the glyph a (U+0061), resulting in a combined glyph like requiring two distinct fonts.

Current conversations indicate the potential introduction of a Font interface, accessible through the document.measureElement and document.measureText methods. This interface would offer properties such as a DOMString name and a numeric value indicating glyphsRendered. However, these ideas are still in the discussion phase and have yet to advance to draft proposals, signifying further deliberation and refinement are necessary before any concrete steps can be taken towards implementation.


In the absence of definitive Web-API support, alternative methods exist, albeit with limitations. As numerous other Q/A threads explain, strategies involving inspecting rendering sizes or observed pixel output may provide insights into the fonts used, though these tactics are considered unreliable and may not function universally across all scenarios.
For instance, if a custom font on a user's system displays select characters from a standard font, discerning between font fallbacks and intended selections becomes problematic using existing techniques.

Ultimately, full control over font usage and fidelity can best be achieved by employing web-font solutions.

Answer №2

If nobody has suggested it yet, there is another method to determine the rendered font.

The code snippet below extracts the font-family CSS definition applied to the element and checks each font family in order to determine the first loaded font family, which is most likely the rendered font.

By using the CSS Font Loading API, this process is simplified and supported across browsers (excluding IE). https://developer.mozilla.org/en-US/docs/Web/API/CSS_Font_Loading_API

For instance, consider the following CSS example:

.body { 
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI Adjusted", "Segoe UI", "Liberation Sans", sans-serif;
}

Snippet:

const getRenderedFontFamilyName = ( element ) => {
    // Extract the font families defined in the CSS for the element
    const fontFamilies = window.getComputedStyle( element, null ).getPropertyValue( "font-family" );
    
    // Remove quotes from names and split them into an array
    const fontFamiliesArr = fontFamilies.replaceAll('"', "").split(", ");

    // Find the first loaded font from the array
    return fontFamiliesArr.find( e => document.fonts.check( `12px ${e}`) );
}

Example showcasing how to obtain the rendered font-family of the StackOverflow body:

getRenderedFontFamilyName(document.querySelector('body'));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Designing the Background with HTML and CSS

Can someone assist me with customizing the background of my website? I would like to achieve the following specifications: Implementing different gradient backgrounds on the left and right sides of the website, ensuring compatibility with all Internet Ex ...

The concept of setting a value is not defined in JavaScript when compared to

Within my primary python script, the following code snippet is present. @app.route('/accounts/test/learn/medium') def medium(): word = random.choice(os.listdir("characters/")) return render_template('accounts/test/medium.html', word=w ...

The JSON sorting functionality seems to be functioning improperly

Here is a sample of my JSON data: [ { "cash": 100, "uid": "LHy2qRGaf3nkWQgU4axO", "name": "test2" }, { "cash": 1000000, "uid": "01wFhCSlnd9vSDY4NIkx", "name": "test" }, { "cash": 500, "uid": "PBOhla0jPwI4PIeNmmPg" ...

Tips for handling uncaught exceptions in Internet Explorer

In both Chrome and Firefox, it is possible to suppress exceptions, but unfortunately, this is not the case with Internet Explorer (IE). window.addEventListener("error", function errorHandler(event) { console.log("exception should be suppressed and not ...

Acquire information asynchronously in JavaScript while inside a for loop

Recently, I've been exploring this particular function snippet: function add_cnh(arr_clelem){ var id=arr_clelem.getElementsByClassName("present")[0].id; var date=arr_clelem.getElementsByClassName("present")[0].getAttribute('date'); v ...

Organize array elements based on their values - using javascript

I am currently exploring the most effective approach to divide an array into multiple arrays based on specific operations performed on the values within the array. Imagine I have an array like this: var arr = [100, 200, 300, 500, 600, 700, 1000, 1100, 12 ...

To concatenate an array into a single line, you can use the JSON.stringify() method

Could someone help me with using JSON.stringify to keep my data on the same line in an array? I am aiming for a format like this: "alice": { "college": "Stanford", "favorite_color": "purple", "favorite_numbers": [7, 15] }, "dave": { "college": "H ...

What is the most effective method for enlarging elements using Javascript?

I have come across many different methods for expanding elements on webpages, such as using divs with javascript and jquery. I am curious to know what the most optimal and user-friendly approach is in terms of performance, among other things. For instance ...

The CSS media query is failing to function as expected

My CSS code is as follows: @media screen and (max-width :300px) { .ui-tabs .ui-tabs-nav .ui-tabs-anchor { float: left; text-decoration: none; } } This means that I intend to modify the CSS when the screen size goes below 300px. I hav ...

What is the most effective method for delivering npm packages using django?

Currently, I am utilizing django as the backend along with a few javascript packages installed via npm. To access these packages, I have configured django to serve /node_modules by including it in the STATICFILES_DIRS. While this setup has been functional, ...

"Implementing a loading function on a particular div element within a loop using

Hey everyone! I'm new to this forum and have recently made the switch from jQuery to Vue.js - what a game-changer! However, I've hit a little snag. I need to set v-loading on multiple buttons in a loop and have it start showing when clicked. Her ...

What is the best method for styling the "body" of multiple pages in a React.js application to prevent them from overlapping?

Hello everyone, After attempting different approaches in numerous ways, I have turned to the experts here who are sure to have the answer to this simple problem. The issue at hand is that when I try to apply background images and other properties to the ...

The documentation for the 4-11.4 version of Material UI cannot be found anywhere

After the release of MUI v5.0.0-rc.1, it appears that all documentation pages for version 4, except for v4.12.3, have vanished. https://mui.com/versions/ Furthermore, (currently not accessible) Is there a way to access previous versions' document ...

Issues with footers in IE 10/11 and Edge when using Grid layout

In the latest versions of Chrome, Firefox, Opera, IE 10/11 and Edge, the Grid layout below works perfectly fine. The only issue is with the Microsoft browsers where the footer fails to start scrolling when the content exceeds the screen size, leaving it fi ...

Hide programmer's comments from public view using personalized PHP scripts

When developing a HTML page, comments such as <!-- Comment 1 --> or within PHP // Comment2 can be easily viewed by right-clicking and selecting "Show code". Is there a way to prevent this from happening? ...

What is the best way to transfer a JavaScript variable through a query string from one HTML page to another?

Is there a way to pass a JavaScript variable called username from one HTML page, example1.html, to another HTML page, example2.html, using query strings? <script type="text/javascript" > $(document).ready(function() { $('#SubmitForm ...

Import .vue single file component into PHP application

I've been struggling to integrate a .vue single file component into my php app without using the inline template method. Since I don't have a node main.js file to import Vue and require the components, I'm not sure how to properly register m ...

Guide to positioning multiple <img> elements within a single <div> container

I'm having trouble aligning these 6 images inside a div using CSS. They are currently aligned vertically, but I want them to be side-by-side. div#menu-lixos img{ margin-left: auto; margin-right: auto; ...

How can I convert a JSON template to HTML using AngularJS?

As someone who is just starting out with AngularJS, I am facing an issue where the HTML tags in a JSON file are not being encoded when rendered in HTML using AngularJS. Is there a specific method in AngularJS that can help with this? This is what my HTML ...

Having trouble updating the icon on my website using FontAwsome

Just a heads up - I'm not familiar with HTML/CSS/JS. This template is pre-made, and I'm simply making some adjustments to it. Hello, I'm currently working on my portfolio website and I want to display my projects based on the programming la ...