Question

I work on a 100% Javascript site that uses a CSS class on the body to explicitly hide everything (display:none), then enables blocks as needed (unusual yes, but I can't change the architecture).

I'd like to display a noscript message to users without js enabled, but we run into a CSS puzzle. noscript must exist within the body. Unlike other blocks on the page, the noscript element can't be forced to become visible, as far as I can tell. The weird thing is that when I select the noscript element with Webkit Inspector, it "claims" that the noscript element is visible. But no matter what, nothing appears on screen with js disabled.

I've done two test cases - one with standard noscript, and another with a hidden div. Either way, the hidden element remains hidden no matter what. My theory is that it's simply not possible to selectively display an element that's nested inside a hidden parent element (i.e. noscript within body).

Here's my simple test case.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <style type="text/css" media="screen">
        body{
            display:none;
        }

        body noscript  {
          display:block;
          visibility:visible;
          color:black;
        }  
    </style>
</head>

<body>
    <p>Normal text</p>

    <noscript>
        <p>This is is noscript</p>
    </noscript>
</body>
</html>

[Later: Example simplified for clarity]

Is this solvable? Thanks.

Was it helpful?

Solution

Rather than making the body hidden:

body { display: none; }

Can you make everything in the body hidden?

body * { display: none; }

Then override that for the noscript - or a div within the noscript, e.g.

body noscript #requirements { display: block; }

Edit

Revisiting this after shacker's comment and looking at my test page with Firebug, it became obvious what the problem was.

body * { display: none; } applies to everything within the body at any depth, so even if I correctly make the <noscript> display correctly, the contents inside it still don't display.

The solution is to target more specifically, using a child selector instead of a descendant selector.

Given this html, I see nothing when javascript is enabled, but I see the contents of the <noscript> block, which lists my site requirements, when javascript is disabled.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <style type="text/css" media="screen">
            body > * {
                display: none;
            }
            body > noscript {
                display: block;
            }
        </style>
    </head>

    <body>

        <p>A normal text block, within a &lt;p&gt;</p>

        <div>A standard &lt;div&gt; with only this text in it</div>

        <noscript>
            <div id="requirements">
                <p>
                This is my noscript div, that is, a &lt;div&gt;
                within the &lt;noscript&gt; tag.
                </p>
                <p>
                This site requires that javascript and cookies are enabled.
                </p>
            </div>
        </noscript>

    </body>
</html>

The rule for body > * hides all immediate children of the body, and therefore their descendants too, while the body > noscript rule reveals the content of the noscript block, and of course that block only displays if javascript is disabled.

OTHER TIPS

You're correct, since you've hidden the parent element, no matter what styling you add to its children you won't be able to see it until you unhide the body. Your best bet would be to change it so you're not hiding the body by default but instead inside your first script tag in the example add a simple

document.body.className='specialbody';

This will add the specialbody class before anything is rendered, but only if javascript is working.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top