Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I am using an 'rtl' font (named as JNN) in horizontal menu bar, which is normal & readable at 18px where as the alternate available 'rtl' fonts (like Tahoma & Arial Unicode MS) on Windows are too much big at 18px. Due to this dissimilarity in 'font-width', If a visitor to my wordpress-site has no JNN font installed on his computer, the menu-bar will shown to him in Tahoma/'Arial Unicode MS' font and hence these fonts disturb the menu-bar-length due to high font-size.

Is there any solution through javascript to check the "font-availibility" at the user's end, and if found use "Font-Size-A" and if not then use "Font-Size-B" ?

Any help will be highly appreciated.

share|improve this question
    
I have already check this thread, but couldn't get the right solution :: stackoverflow.com/questions/1271477/… –  syed Nov 25 '10 at 0:30
    
@syed: This is not really a WordPress question (the core of your question is how to detect the availability of a font), so I voted to close it and suggest you ask it on Stack Overflow. Make sure to link to the other question, tell what you tried, and how it did not work. –  Jan Fabry Nov 26 '10 at 16:55
    
@Jan Fabry: OK. leave the javascript question (how to detect the availability of a font?) I have a font detector javascript file here : (wordpress.pastebin.com/EqGPZ8CC). My question is : Using this javascript, How can I add a code in the header.php file such that : If an specific font (named as "Andalus.ttf") is found, then use stylesheet styleA.css, otherwise use styleB.css –  syed Nov 26 '10 at 19:39
    
@syed: Interesting, because you need to execute the check on the client side and choose the style sheet there. You will probably have some redrawing as you load the extra stylesheet (the first time, then you probably can set and check a cookie). Would it be possible to create a "normal" style.css, and an extra style-with-small-font-size.css that you load too for those that don't have your fonts? This will improve the experience for the group that has the fonts. –  Jan Fabry Nov 26 '10 at 20:31
    
@Jan Fabry: In WP header.php, can we define two stylesheets at the same time? One with fontA and other with fontB ? Is it possible? If it is, then I think, theres no need to check the availibility of installed fonts! –  syed Nov 26 '10 at 21:19

3 Answers 3

Not exactly what you asked for, but you can kind of "make sure" the user has the desired font through the @font-face css3 rule.

According to caniuse.com about 95% of global users can use that css property, so it's a good trade-off.

Different browsers use different font formats however, so you'll need to use http://www.fontsquirrel.com/fontface/generator to generate all your required fonts. The site will also provide you with some extra details on how to use the fonts.

Paul Irish has a great blog post about font-face and how to use it properly here. (go to his blog and search for font-face) I would have posted the link myself but I can't post more than one link cause I'm a new user.

Hope this helps!

share|improve this answer
1  
To compliment your answer and to provide said link(s).. First article - paulirish.com/2009/bulletproof-font-face-implementation-syntax Second - paulirish.com/2010/font-face-gotchas –  t31os Nov 28 '10 at 11:09

This solution uses two stylesheets: wpse-4508-default.css and wpse-4508-small.css. We always load the default, and load the small version too if a certain font does not exist. We save the result in a cookie so the next time don't need to do the test and extra loading on the client side, resulting in a smoother experience. The code is designed to run from your theme directory, so you can add the PHP code to your functions.php. I added some var_dump() and alert() lines to help you understand what goes on. I only tested it in Safari on Mac OS X.

<?php
add_action( 'wp_head', 'wpse4508_wp_head' );
function wpse4508_wp_head()
{
    // Always display our normal stylesheet
    wp_enqueue_style( 'wpse4508_default', get_stylesheet_directory_uri() . '/wpse-4508-default.css' );
    $urlSmallStylesheet = get_stylesheet_directory_uri() . '/wpse-4508-small.css';
    if ( ! array_key_exists( 'wpse4508_hasfont', $_COOKIE ) ) {
        // We don't know anything, detect it
        var_dump( 'No cookie info, loading JS' );
        wp_enqueue_script( 'wpse4508_detector', get_stylesheet_directory_uri() . '/wpse-4508-detector.js', array(), false, true );
        // Send the style sheet URL to the front
        wp_localize_script( 'wpse4508_detector', 'WPSE4508_Detector', array( 'url' => $urlSmallStylesheet ));
    } elseif ( 'false' == $_COOKIE['wpse4508_hasfont'] ) {
        // We know we should load the small stylesheet
        var_dump( 'Cookie info, no font, extra stylesheet via PHP' );
        wp_enqueue_style( 'wpse4508_small', $urlSmallStylesheet );
    }
}

// A simple div to test this code
add_action( 'wp_footer', 'wpse4508_wp_footer' );
function wpse4508_wp_footer()
{
    echo '<div class="wpse4508_test">WPSE 4508 test</div>';
}

The wpse-4508-default.css file:

.wpse4508_test
{
    background-color: red;
    font-size: 20px;
    width: 100%;
    text-align: center;
    position: absolute;
    top: 0;
}

The wpse-4508-small.css, with the extra rules. I don't think !important is needed, since they load after the previous one, try this yourself.

.wpse4508_test
{
    background-color: green !important;
    font-size: 10px !important;
}

The Javascript file that detects the font and sets a cookie.

var Detector = function(){
    var h = document.getElementsByTagName("BODY")[0];
    var d = document.createElement("DIV");
    var s = document.createElement("SPAN");
    d.appendChild(s);
    d.style.fontFamily = "sans";            //font for the parent element DIV.
    s.style.fontFamily = "sans";            //serif font used as a comparator.
    s.style.fontSize   = "72px";            //we test using 72px font size, we may use any size. I guess larger the better.
    s.innerHTML        = "mmmmmmmmmmlil";       //we use m or w because these two characters take up the maximum width. And we use a L so that the same matching fonts can get separated
    h.appendChild(d);
    var defaultWidth   = s.offsetWidth;     //now we have the defaultWidth
    var defaultHeight  = s.offsetHeight;    //and the defaultHeight, we compare other fonts with these.
    h.removeChild(d);
    /* test
     * params:
     * font - name of the font you wish to detect
     * return: 
     * f[0] - Input font name.
     * f[1] - Computed width.
     * f[2] - Computed height.
     * f[3] - Detected? (true/false).
     */
    function debug(font) {
        h.appendChild(d);
        var f = [];
        f[0] = s.style.fontFamily = font;   // Name of the font
        f[1] = s.offsetWidth;               // Width
        f[2] = s.offsetHeight;              // Height
        h.removeChild(d);
        font = font.toLowerCase();
        if (font == "serif") {
            f[3] = true;    // to set arial and sans-serif true
        } else {
            f[3] = (f[1] != defaultWidth || f[2] != defaultHeight); // Detected?
        }
        return f;
    }
    function test(font){
        f = debug(font);
        return f[3];
    }
    this.detailedTest = debug;
    this.test = test;   
}

WPSE4508_Detector.loadStylesheetIfNeeded = function() {
    var hasFont = new Detector().test('Andalus');
    alert( 'Testing for font: ' + hasFont );
    document.cookie = 'wpse4508_hasfont=' + (hasFont ? 'true' : 'false'); // Maybe add expiry date?
    if (!hasFont) {
        alert( 'Loading stylesheet via JS' );
        var elHead = document.getElementsByTagName('head')[0];
        var elLink = document.createElement('link');
        elLink.rel = 'stylesheet';
        elLink.type = 'text/css';
        elLink.href = WPSE4508_Detector.url;
        elHead.appendChild(elLink);
    }
}

WPSE4508_Detector.loadStylesheetIfNeeded();
share|improve this answer
    
@Jan Fabry, your javascript file has some errors. please check. Thanks. –  syed Nov 27 '10 at 8:37
    
@Jan Fabry, please help me to show the complete method step by step. Thanks a lot. I am waiting anxiously. –  syed Nov 27 '10 at 18:56
    
@Jan Fabry, Sorry! I have only 1 reputation and the chat need atleast 20. –  syed Nov 27 '10 at 20:20
    
@Jan Fabry, its midnight here. I will explain the problem tomorrow. –  syed Nov 27 '10 at 21:49
    
@Jan Fabry - just FYI, the javascript code requires attribution, it's obvious you picked it from here: lalit.org/lab/javascript-css-font-detect –  hakre Feb 5 '11 at 21:07

Q: Is there any solution through javascript to check the "font-availibility" at the user's end, and if found use "Font-Size-A" and if not then use "Font-Size-B" ?

Yes there is. It's called JavaScript/CSS Font Detector and it can check for availability of fonts.

After checking if a specific exists, you can add or remove a class to HTML elements that offer a pre-configured fallback styling then.

share|improve this answer
    
Didn't seyd already link to that code in a pastebin? See the comments under the question. –  Jan Fabry Feb 5 '11 at 22:20
    
@Jan Fabry: As far as dynamically loading a CSS is needed, see javascriptkit.com/javatutors/loadjavascriptcss.shtml - This should be all possible in one script, no need for cookies and backend PHP, right? –  hakre Feb 5 '11 at 22:51
    
Indeed, you can add the CSS later, but that could result in a "flash of unstyled text" when it loads a bit later. –  Jan Fabry Feb 5 '11 at 23:00
    
@Jan Fabry: That's why I suggested to control via a class value first, that could trigger an already loaded CSS. done on DOM Ready should prevent flashes at least at best it could get. –  hakre Feb 5 '11 at 23:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.