Embedding extra styles with noscript

2019-01-16 19:43发布

I have an XHTML strict page that has an invisible div that is controlled by Javascript. The div is set to transparent and visible by the script and a mouseover event to make the div opaque on hover.

When someone using a browser (or firefox with noscript) without javascript the div simply remains invisible. The problem with this is that I do not want the content to be inaccessible. I also do not want to leave the div visible then use the script to make it transparent as the div is located at the bottom of the document and it causes a noticeable flicker whenever a page loads.

I have tried using noscript tags to embed an additional style sheet that is only loaded for people without the luxury of Javascript but this fails the XHTML strict validation. Is there any other way to include extra styling information inside a noscript block that is XHTML valid?

Ed:

With a simple test case I get a validation error of: document type does not allow element "style" here. This is with an empty XHTML Strict document with a style element inside a noscript element. The noscript is inside the body.

标签: css xhtml
7条回答
何必那么认真
2楼-- · 2019-01-16 20:19

UPDATE for 2016:

From w3school:

Differences Between HTML 4.01 and HTML5

In HTML 4.01, <noscript> tag can only be used inside the <body> element.

In HTML5, the <noscript> tag can be used both inside <head> and <body>.

Differences Between HTML and XHTML

In XHTML, the <noscript> tag is not supported.

My solution for having expanded menus (lists, etc..)

I've put in the header like this

<header>
    <noscript>
        <link rel="stylesheet" href="assets/css/x_no_script.css">
    </noscript>
</header>

In the x_no_script.css I set the selectors that I wanted to

max-height: 9999px;
overflow: visible;

In this way, I have expanded menus when JavaScript is disabled or not exists.

查看更多
手持菜刀,她持情操
3楼-- · 2019-01-16 20:24

To clear up the validation issue: noscript is only allowed in the body element, style only allowed in the head. Therefore, the latter is not allowed within the former.

On the general issue: you'll want to make the div element visible by default, then hide it via CSS + javascript. This is the 'progressive enhancement' model. I notice you say you "don't want to do this because of the flicker", but I'm not sure exactly what's causing this - chances are you can fix it, so maybe you should post that as a question.

查看更多
祖国的老花朵
4楼-- · 2019-01-16 20:28

Note about my answer

I wrote this post after realizing it was dating from 2008

Since I had a similar problem, I thought continuing answering with a current answer.

My actual answer

Like Boby Jack said, style tag is not allowed in body. I myself did the exact thing as you (Joshua) about it. But Jack's "progressive enhancement" made me without non-abstract solution but then I realized a solution that I did not find answers on this thread.

It all depends of your styling structure.

My suggestion is to plainly use something like modernizr in the very begining of the head and use Paul Irish's HTML5Boilerplate recommendations.

Long story short

  1. Html tag has a class attributes with no-js
  2. Head tag includes a first modernizr javascript as the first
  3. CSS has the element (.hide-me) with display:none on its proper place
  4. Then .no-js .hide-me { display:block }

In detail

See Paul Irish's HTML5boilerplate, and adapt it to XHTML if you want :)

1. Html has a class attributes with .no-js

<!doctype html>
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
<!--[if IE 7]>    <html class="no-js ie7 oldie" lang="en"> <![endif]-->
<!--[if IE 8]>    <html class="no-js ie8 oldie" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->

quoting from html5boilerplate.com

2. Head tag includes a first modernizr javascript as the first

Modernizr execution will build html attributes with what's supported.

Will build something similar to this:

<html class=" js flexbox canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths" lang="en">

Note this is from Google Chrome modernizr tests.

The first is js but if Modernizr did not run (no javascript) the no-js would stay there.

3. CSS has the element (.hide-me) with display:none on its proper place

... you know the rest :)

查看更多
Summer. ? 凉城
5楼-- · 2019-01-16 20:38

In case XHTML is used, the trick is to use two CSS files. One global one and one js-one tweaking the global one for JavaScript-enabled browsers.

style.css:

.hidden {
  visibility:hidden;
}

style-js.css:

.hidden {
  visibility:visible;
}

test.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
  <title>Test page</title>
  <link href='css/style.css' rel='stylesheet' type='text/css' />
  <script type="text/javascript">
  //<![CDATA[
    //document.write("<link href='css/style-js.css' rel='styleSheet' type='text/css' />"); 
    //is not legal in XHTML, we do the long way:
    var l=document.createElementNS("http://www.w3.org/1999/xhtml","link");
    l.setAttribute("rel", "stylesheet");
    l.setAttribute("type", "text/css");
    l.setAttribute("href", "/css/style-js.css");
    document.getElementsByTagName("head")[0].appendChild(l);
  //]]>
  </script>
</head>
<body>
  <div class="hidden">
    <p>Only displayed at JavaScript enabled browsers</p>
  </div>
</body>
</html>

Main idea by tutorials.de. XHTML validity tip by Estelle Weyl's Blog. createElementNS tip by CodingForums.

查看更多
淡お忘
6楼-- · 2019-01-16 20:39

What validation error do you get? <noscript> should be allowed in XHTML but it's block level, so make sure it's not in a <p>, <span>, etc

查看更多
你好瞎i
7楼-- · 2019-01-16 20:40

Use a script block in the head to add a style element with document.write:

<head>
...
 <script type="text/javascript">
 //<![CDATA[
  document.write('<style type="text/css">.noscript{display:none}</style>');
 //]]>
 </script>
...
</head>
查看更多
登录 后发表回答