Modernizr and WordPress – How can I add a CSS class to the html element?

The instructions for implementing Modernizr state that I should add class="no-js" to the <html> element.

Is there a way to do this in WordPress using a hook or filter? If at all possible, I’d prefer to do this without editing the theme files.

Related posts

Leave a Reply

2 comments

  1. This is not exactly the answer, but you can use a hook for language_attributes filter. This action is fired at <html> tag and what it does is simply echo the lang=en string, for ex. You can hook to that and replace the string with your CSS class, like this:

    add_filter('language_attributes', 'modernizr');
    function modernizr($output) {
        return $output . ' class="no-js"';
    }
    

    This works only when your theme follows the WordPress Theme Development Checklist. Sometimes people don’t follow this and that breaks the technique.

  2. A little late to the game here, but just to add to @Rilwis answer you could add the script to a function that checks if the no-js language attributes are added or not.

    While I don’t use Modernizr, I do use the no-js detection script from twenty-sixteen so inclusion is pretty much the same. Doing it this way, you don’t have to worry about removing the function added to wp_head or wp_enqueue_scripts since it happens automatically when you remove the filter.

    Adding Removing Filter Approach

    /** 
     * Javascript Detection Filter
     * 
     * remove_filter( 'language_attributes', 'lang_atts_js_detect' ); 
     */ 
    add_filter( 'language_attributes', 'lang_atts_js_detect' );
    function lang_atts_js_detect($output) {
        return $output . ' class="no-js"';
    }
    add_action( 'wp_head', function() {
        if ( has_filter( 'language_attributes', 'lang_atts_js_detect' ) ) {
            echo "<script>(function(html){html.className = html.className.replace(/bno-jsb/,'js')})(document.documentElement);</script>n";
        }
    }, 0);
    

    Theme Support Approach

    Another option could be to do this using current_theme_supports.

    /** 
     * Javascript Detection Theme Support
     * 
     * add_theme_support( 'js-detect' ); 
     */ 
    add_action( 'init', function() {
        if ( current_theme_supports( 'js-detect' ) && !is_admin() )
            add_filter( 'language_attributes', 'lang_atts_js_detect_class' );
            add_action( 'wp_head', 'lang_atts_js_detect_script', 0 );
    }
    function lang_atts_js_detect_class($output) {
        return $output . ' class="no-js"';
    }
    function lang_atts_js_detect_script() {
        echo "<script>(function(html){html.className = html.className.replace(/bno-jsb/,'js')})(document.documentElement);</script>n";
    }