Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose System Fonts #837

Open
curran opened this issue Aug 12, 2024 · 2 comments
Open

Expose System Fonts #837

curran opened this issue Aug 12, 2024 · 2 comments
Assignees

Comments

@curran
Copy link
Contributor

curran commented Aug 12, 2024

image

@curran curran moved this to Backlog in VZCode Kanban Aug 12, 2024
@curran
Copy link
Contributor Author

curran commented Aug 12, 2024

Ideas from ChatGPT

Yes, it's possible to use system fonts in JavaScript and CSS. System fonts are the fonts that are installed on the user's device and can vary depending on the operating system. Here's how you can list and use them:

1. Using System Fonts in CSS

You can specify system fonts in CSS by using a generic font-family stack that includes common system fonts. Here's an example:

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

This stack includes:

  • -apple-system: The system font on Apple devices (macOS, iOS).
  • BlinkMacSystemFont: The system font on Chrome running on macOS.
  • "Segoe UI": The system font on Windows.
  • Roboto: The system font on Android.
  • "Helvetica Neue": A common sans-serif font on macOS.
  • Arial: A fallback for sans-serif fonts.
  • sans-serif: The generic sans-serif font family.

2. Listing System Fonts in JavaScript

JavaScript cannot directly list all system fonts, but you can detect which fonts are available on the user's system by trying to render text in different fonts and comparing their rendered width or height.

Here's a simple example:

function isFontAvailable(font) {
    const testString = "abcdefghijklmnopqrstuvwxyz0123456789";
    const testSize = "72px";

    // Create a span element with the test string
    const span = document.createElement("span");
    span.style.fontSize = testSize;
    span.style.visibility = "hidden";
    span.style.position = "absolute";
    span.innerHTML = testString;
    document.body.appendChild(span);

    // Default font to compare against
    const defaultFont = "monospace";
    span.style.fontFamily = defaultFont;
    const defaultWidth = span.offsetWidth;

    // Test with the desired font
    span.style.fontFamily = `${font}, ${defaultFont}`;
    const newWidth = span.offsetWidth;

    // Remove the span from the DOM
    document.body.removeChild(span);

    // If the width changed, the font is available
    return newWidth !== defaultWidth;
}

const fontsToTest = ["Arial", "Courier", "Georgia", "Tahoma", "Verdana"];
fontsToTest.forEach((font) => {
    if (isFontAvailable(font)) {
        console.log(`${font} is available`);
    } else {
        console.log(`${font} is not available`);
    }
});

This code checks if a given font is available on the user's system by comparing the width of a string rendered in that font against a default font. If the width changes, the font is considered available.

3. Using System Fonts Dynamically in JavaScript

If you want to dynamically apply a system font based on availability, you could extend the above JavaScript approach:

const preferredFonts = ["Segoe UI", "Roboto", "Arial", "Verdana", "sans-serif"];
let chosenFont = preferredFonts.find(isFontAvailable);

if (chosenFont) {
    document.body.style.fontFamily = chosenFont;
}

This script will apply the first available font from your preferred list to the body element.

4. Using CSS system-ui Value

Modern browsers support the system-ui keyword, which is a generic font-family that uses the system’s default UI font:

body {
    font-family: system-ui;
}

This approach is a convenient way to use the system font without manually specifying each possible font.

Conclusion

  • CSS: You can specify system fonts directly in a font stack, or use the system-ui keyword for simplicity.
  • JavaScript: You can detect font availability by comparing the rendering of text in different fonts, although it doesn't allow you to list all system fonts directly.

@curran
Copy link
Contributor Author

curran commented Aug 12, 2024

Yes, there are some NPM libraries that can help you work with system fonts, though the range of functionality may vary depending on what exactly you're looking to achieve. Here are a few libraries that can assist with system fonts:

1. fontfaceobserver

  • Description: This is a small library that lets you load and observe fonts. While it's not specifically about system fonts, you can use it to check if a particular font (including system fonts) is available and loaded on the user's system.

  • Usage:

    npm install fontfaceobserver
    const FontFaceObserver = require('fontfaceobserver');
    
    const font = new FontFaceObserver('Roboto');
    
    font.load().then(() => {
      console.log('Roboto is available');
    }).catch(() => {
      console.log('Roboto is not available');
    });
  • Link: fontfaceobserver on npm

2. detect-font

  • Description: This library allows you to detect whether a specific font is available on the user's system. It's useful for system fonts as it lets you check if a particular font is installed and can be used.

  • Usage:

    npm install detect-font
    const detectFont = require('detect-font');
    
    if (detectFont('Arial')) {
      console.log('Arial is available');
    } else {
      console.log('Arial is not available');
    }
  • Link: detect-font on npm

3. font-detector

  • Description: This is another library for detecting the availability of fonts on a user's system. It works similarly to detect-font but might be simpler to use depending on your needs.

  • Usage:

    npm install font-detector
    const fontDetector = require('font-detector');
    
    if (fontDetector('Comic Sans MS')) {
      console.log('Comic Sans MS is available');
    } else {
      console.log('Comic Sans MS is not available');
    }
  • Link: font-detector on npm

4. webfontloader

  • Description: Developed by Google and Typekit, webfontloader allows you to asynchronously load custom web fonts and detect when they are loaded. While it's typically used for web fonts, it can be adapted for system fonts as well.

  • Usage:

    npm install webfontloader
    const WebFont = require('webfontloader');
    
    WebFont.load({
      google: {
        families: ['Droid Sans', 'Droid Serif']
      },
      custom: {
        families: ['My Font'],
        urls: ['my-font.css']
      },
      timeout: 2000
    });
  • Link: webfontloader on npm

Conclusion

These libraries help with various aspects of working with fonts in the browser, including loading, observing, and detecting system fonts. Depending on your specific needs, one of these libraries might be a good fit for your project.

@sxkgir sxkgir self-assigned this Nov 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Backlog
Development

No branches or pull requests

2 participants