JSFiddle - React, Tailwind, and code Playground

by Thomas ZILLIOX

HTML

<p class="initial" id="init">First</p>
<p class="second"> Second</p>
<p>third</p>

CSS

p.initial::first-letter { color: red; }
p.second::first-letter { color: blue; }

JavaScript

(function() {
    var firstLetterRules = [];
    
    var regex = /::?first-letter/i;
    
    //Chrome only
    var matches = document.createElement("div").webkitMatchesSelector;
    
    //1. Get a list of all CSS blocks
    var loadRules = function() {
        var stylesheets = document.styleSheets;

        for (var i = 0; i < stylesheets.length; i++) {
            var stylesheet = stylesheets[i];
            var rules = stylesheet.cssRules;
            
            for (var k = 0; k < rules.length; k++) {
                var rule = rules[k];
                
                //2. Filter out CSS blocks which do not contain `:first-letter` in the block's selector
                if (regex.test(rule.selectorText)) {
                    firstLetterRules.push(rule);
                }
            }
        }
    };
    
    window.hasFirstLetterStyle = function(element) {
        /*3. Iterate over the list of remaining CSS blocks, and run matchesSelector()with the target element as a receiver and the current CSS block's selector as the argument.*/
        for( var i = 0, len = firstLetterRules.length; i < len; ++i ) {
            var rule = firstLetterRules[i],
                text = rule.selectorText.replace( regex, "" );
            
            if( !text.trim() ) text = "*";
            
            //If `matchesSelector()` returns `true`, then the current CSS block's rules affect the target element's first letter.
            
            if( matches.call( element, text ) ) {
                return true;
            }
            
        }
        return false;
    };
    
    loadRules();
})();

$('p').each(function(){
    if( hasFirstLetterStyle( this ) ) {
      console.log( this, true );   
    }
    else {
        console.log( this, false );
    }
});