Is there a way to identify the font selected by the user's browser through Javascript?

Let's say the CSS on my web page for the body element looks like this:

font-family: verdana, 'Liberation Sans', sans-serif;

How can I determine if a user's browser is using 'Liberation Sans' font?

I attempted to do something like this:

const bodyComputedStyle = window.getComputedStyle(document.body);
const bodyFontFamily = bodyComputedStyle.fontFamily;
console.log('bodyfont: ' + bodyFontFamily);

However, the bodyFontFamily constant will return a list of all fonts provided by the server, which doesn't help me.

Answer №1

It's essential to utilize this specific function.

By utilizing canvas, we can determine if a font is supported. This involves drawing both the detected font and the default font on the canvas, then comparing their dot matrix representations for any differences.

const checkFontSupport = (fontFamily) => {
  if (typeof fontFamily != "string") {
    return false;
  }

  const defaultFontFamily = "Arial";
  if (fontFamily.toLowerCase() == defaultFontFamily.toLowerCase()) {
    return true;
  }

  const defaultLetter = "a";
  const defaultFontSize = 100;

  const width = 100,
    height = 100;
  const canvas = document.createElement("canvas");
  const context = canvas.getContext("2d", {
    willReadFrequently: true,
  });
  canvas.width = width;
  canvas.height = height;
  context.textAlign = "center";
  context.fillStyle = "black";
  context.textBaseline = "middle";
  const getFontData = function (fontFamily) {
    context.clearRect(0, 0, width, height);
    context.font =
      defaultFontSize + "px " + fontFamily + ", " + defaultFontFamily;
    context.fillText(defaultLetter, width / 2, height / 2);

    const data = context.getImageData(0, 0, width, height).data;

    return [].slice.call(data).filter(function (value) {
      return value != 0;
    });
  };

  return getFontData(defaultFontFamily).join("") !== getFontData(fontFamily).join("")
};

Moving on! Let's

const bodyComputedStyle = window.getComputedStyle(document.body);
const bodyFontFamily = bodyComputedStyle.fontFamily;
bodyFontFamily.split(', ').find(e => {
    return checkFontSupport(e)
})

There you have it! All set!

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

Each time a user inputs new data, Node continuously transmits the information back several times

Apologies for the poorly worded title. I've been racking my brain for the past 20 minutes but can't seem to find a concise way to describe the issue at hand. If you have a better suggestion, please feel free to share or edit the title if possible ...

Understanding the values of attributes when submitting a reactive form

My form is built using Angular's reactive forms and includes an input element with custom attributes: <input type="text" [attr.data-challengeId]="value.id" [formControlName]="value.label"> When I submit the form, I only receive the value of th ...

Execute an AJAX request in JavaScript without using string concatenation

On my webpage, users input code in a programming language which can be over 2000 characters long and include any characters. When they press the send button, the code is sent to a server-side script file using JavaScript AJAX. Currently, I am using the fo ...

When Socket.emit is called, it outputs <span> elements within a well-structured message

Currently working on a small chat application using Node.js, Express.js, and Socket.IO. However, I'm encountering an issue with formatting. Instead of displaying the message content within <span> tags as intended, it is printing out the actual t ...

The menu is about to receive some custom styling

I have come across a webpage where I need to make some modifications, but I am unable to locate the script responsible for applying the inline style. This issue only seems to be occurring on the mobile version with the dropdown menu. <div class="is-dri ...

Guide to storing user data retrieved from the LinkedIn API into an Angularjs controller with the help of a personalized service

Hey there, I'm currently diving into Angular and facing a challenge with saving user information from LinkedIn API to the controller's scope without directly passing it to my custom service. It seems like that might not align with the best practi ...

Execute a Loop in the Background

Currently, I have a requirement to continuously run a loop in the background of my JavaScript-based app. This loop is responsible for cycling a ScrollableView every six seconds. However, the issue arises when this loop prevents any other operations from be ...

Personalized VueJS Counter

Just started learning VueJS and I've encountered a challenge while attempting to build a custom counter. Here is the code snippet: <template v-for="(ben, i) in plan.beneficios"> <div class="w-80 w-90-480 m-auto pa-hor-5-480" :class= ...

Is it possible for an object in three.js to be both rotated and moved simultaneously?

Hello, thank you for your time. I'm trying to simultaneously move and rotate an object, but it seems to be behaving erratically. I've read that rotation can change the axis in some way. Is this true? Below is the code where I attempted to rotate ...

Running multiple instances of setTimeout() in JQuery

I'm looking for a way to delay the execution of 10 lines of independent jQuery code with 2 seconds between each line. I initially tried using setTimeout() on each line, but is there a more elegant solution for this scenario? The jQuery DELAY method do ...

A guide on effortlessly reducing a flying draggable popup using jQuery

I have created a pop-up window that appears on the viewport as you scroll, and it can also be dragged around. You can see the code snippet below: var jq = jQuery.noConflict(); var $el = jq(".Box"); var $btnmini = jq(".sessionCD #btnmin"); var isMini = ...

Implement custom material-ui styles exclusively for mobile displays

When working with Material-UI in react, I am wondering if there is a way to apply theme provider overrides only in mobile view. Specifically, I am using the <Card> component and would like to remove the boxShadow of the card when it's displayed ...

Extracting JavaScript content with Selenium using Python

I am currently facing a challenge of scraping JavaScript data from a website. Specifically, I am trying to extract the number of Followers from this particular website. Here is the code I have come up with so far: import os from selenium import webdriver ...

How to display nested arrays in AngularJs

Within my array contacts[], there are multiple contact objects. Each of these contact objects contain an array labeled hashtags[] consisting of various strings. What is the best way to display these hashtags using ng-repeat? ...

A guide to examining pixels in Three.js

I have a query about comparing two textures at a pixel level in three.js. I am unsure of how to achieve this as the documentation for Three.js does not provide clear answers, with some classes remaining undocumented. In summary, I am looking to determine ...

How to send parameters through the Google Maps API URL using Vue.js

When using $router.push(), I receive two parameters: {{ this.$route.params.lat }} and {{ this.$route.params.lng }}, which are latitude and longitude coordinates. To access a Google Maps URL, I need to include both of these parameters: https://maps.googlea ...

How can I implement a feature in React.js where clicking a button triggers a Canvas to draw something?

I am trying to implement a <button> component that will trigger a specific function to draw on my HTML5 Canvas element. This is how the project files are structured and how I have passed the necessary props -> The main drawing function is locate ...

Is there a way to design a catalog page for my website that doesn't include a shopping cart or detailed product pages?

I am looking to create a catalogue feature similar to Newegg's for my website, but with a simplified approach. I have never attempted something this advanced before and I am wondering if it is possible to achieve. My plan is to use PHP and JS for the ...

"Variables declared with const do not get hoisted when used in immediately invoked functions

Recently, I was experimenting with the new ECMASCRIPT-6 const keyword. There was one particular behavior of the keyword that left me confused. Imagine we have two functions: In the first case: (function(){ console.log(_t); const _t=10; })(); and i ...

The grpc client is not able to receive the data being streamed from the

I've been attempting to stream the output of a nodejs child process through grpc, but I consistently receive an empty result. Here is my proto file: syntax = "proto3"; package servicePackage; service Mobile { rpc sign(Empty) returns ( ...