javascripthtmlcsshta

Is it possible to pull CSS values with HTA JavaScript?


I know that it is possible to get innerText values with JavaScript in an HTA file, like in the example below:

<html>
<head>
    <style>
        .testCss::after {
            content: "I want to pull this with javascript";
        }
    </style>
    <HTA:APPLICATION 
        ID="testApp"
        BORDER="thin"
        CAPTION="yes"
        SHOWINTASKBAR="yes"
        SINGLEINSTANCE="yes"
        SCROLL="no"
    />
    <meta http-equiv="x-ua-compatible" content="IE=edge">
</head>
<body>
    <div id="example_of_id">Some inner text that will be pulled</div>
</body>
<script language="javascript">
    var test2 = document.getElementById("example_of_id").innerText;
   // what about getting a css value though?
</script>
</html>

This will successfully pull the inner text from the id specified.

I was wondering if the same can be done to pull css values like the one in the example, because until now I did not have any luck finding examples regarding this issue nor did my manual attempts lead to any luck.

P.S. I know that probably this is pointless, but I just had this idea the other day because I have never seen anything like that.


Solution

  • I was wondering if the same can be done to pull css values like the one in the example, because until now I did not have any luck finding examples regarding this issue nor did my manual attempts lead to any luck.

    Yes-and-No....

    The problem with HTAs is that if you want to use any MSHTML/Trident features added since IE7's IE9's Standards Mode or later (e.g. IE11 Standards mode, Modern CSS (e.g. grid, flex) then it will break the <HTA:APPLICATION /> integration. Or - put in reverse: if you want to use the integration features of <HTA:APPLICATION /> (such as BORDER=thin and SHOWINTASKBAR=yes) then you cannot use anything beyond Windows XP-era IE6 Windows Vista IE7/IE8 features (and maybe IE9?).

    This is because (ironically?) due to IE's backwards-compatibility: ever since IE5 came out in 1999 the IE dev team added support for new HTML/CSS/JS features only to new document-modes, so that the unholy mess of spaghetti code that makes IE4 behave the way it did could be kept as-is: in (the original) quirks-mode (and so not break any websites dependent on IE4's quirks-mode rendering); whereas if a webpage ran in IE5-mode it would lose-out on IE4-render behaviour but opt-in to bugfixed CSS layout features; and this way-of-doing-things existed in some way or form in every subsequent version of IE through to the end in IE11.

    IE6 IE9, in 2001 2011, was (to my knowledge) the last release of IE with support for HTA features (like <HTA:APPLICATION />) in its standards(-ish) mode. But even long before IE9 came out HTAs were already largely forgotten by everyone (except for nerds like me... and you) by then: so between Windows XP and Windows 8, if you were ever wanting to run a HTA then odds are almost certain that the HTA would have actually been written sometime between 1999 and 2003 and so would have targeted an IE5 or IE6 document-mode, and unless the HTA's author had a Ziltoid-like prescience to forsee changes coming in IE7/8/9 then that HTA would not need to run in IE7/8/9's Standards Mode - therefore when IE10 came out in 2012 they never brought-forward the old codebase that handled the <HTA:APPLICATION /> integration, so things like SHOWINTASKBAR="yes" et cetera simply wouldn't work anymore.

    I do remember idly messing-around with HTAs in IE10 and IE11 just to see how badly things had gotten - and to compare them to the then-nascent (2013-ish) WebView-based platforms like Cordova/PhoneGap/Ripple - and I was susprised that I could get a HTA to work at all using IE11 in Windows 8/8.1 in Standards Mode, but all the shell and Windows integration features were broken, and I didn't put any more effort in.


    That said, simply getting the innerText or innerHTML of a <style> element doesn't require IE7+ features, so let's give it a try... (note this does mean you can't use querySelector, querySelectorAll, matches(), etc, as that was all added in IE8).

    I was wondering if the same can be done to pull css values like the one in the example

    If you want to be period-correct and write HTML+CSS+JS like it's 1998-2001 then you need to restrict yourself to only APIs in DOM Level 1 and maybe IE's DOM extensions too (c.f. MSHTML docs).

    BTW, when I was rediscovering HTAs to write this answer I realized that the <meta http-equiv="x-ua-compatible" content="IE=edge"> from the OP's post was forcing Trident into some modern rendering (IE11? IE=Edge?) Standards Mode which broke <HTA:APPLICATION /> - so I had to remove it from the HTML - I also found having a <!DOCTYPE> also put it in a modern (IE11-era) standards mode when what I wanted was an IE6/IE7-era modew, I found I had to remove both of those to get anywhere - but if you're (unironically) writing a HTA today then you should follow @LesFerch's advice and add the necessary <meta/> and other elements to force it into IE9 mode, which looks like the best overall mode for HTAs. I strongly recommend everyone read their answer because they got it right the first time (whereas I've had to edit my answer 3 or 4 times now, ugh).

    Like so....

    With <HTA:APPLICATION /> integration working like it's in IE 5 (for period-correct HTAs when the real IE5 is unavailable):

    <html>
    <head>
        <HTA:APPLICATION 
            ID="testApp"
            BORDER="thin"
            CAPTION="yes"
            SHOWINTASKBAR="yes"
            SINGLEINSTANCE="yes"
            SCROLL="no"
        />
        <style>
            .testCss::after {
                content: "I want to pull this with javascript";
            }
        </style>
    </head>
    <body>
    </body>
    <script language="javascript">
    
    window.onload = function() {
        
        var headStyleEl = document.getElementsByTagName( 'style' )[0];
        window.alert( headStyleEl.innerText + "\r\n\r\nAlso: document.documentMode == " + document.documentMode + "\r\n\r\nAlso: document.compatMode == " + document.compatMode );
    }
    
    </script>
    </html>
    

    Screenshot proof:

    enter image description here

    Without <HTA:APPLICATION /> integration, but with IE11 Standards Mode support:

    <!DOCTYPE html>
    <html>
    <head>
        <style>
            .testCss::after {
                content: "I want to pull this with javascript";
            }
        </style>
        <HTA:APPLICATION 
            ID="testApp"
            BORDER="thin"
            CAPTION="yes"
            SHOWINTASKBAR="yes"
            SINGLEINSTANCE="yes"
            SCROLL="no"
        />
        <meta http-equiv="x-ua-compatible" content="IE=edge">
    </head>
    <body>
    </body>
    <script language="javascript">
    
    window.onload = function() {
        
        var headStyleEl = document.getElementsByTagName( 'style' )[0];
        window.alert( headStyleEl.innerText + "\r\n\r\nAlso: document.documentMode == " + document.documentMode + "\r\n\r\nAlso: document.compatMode == " + document.compatMode );
    }
    
    </script>
    </html>
    

    Screenshot proof:

    enter image description here