Can the <script> tag not be self closed? - xhtml

I had this code in my website
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"/>
<script type='text/javascript' src='/lib/player/swfobject.js'></script>
swfobject was not working (not loaded).
After altering the code to:
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
<script type='text/javascript' src='/lib/player/swfobject.js'></script>
It worked fine.
The document was parsed as HTML5.
I think it’s funny. Okay, granted a tag that is closed and a self-closing tag are not the same. So I would understand if jQuery couldn’t load (although I find it ridiciulous).
But what I do not understand is that jQuery loads but the following, correctly written tag, doesn’t?

In HTML, there are tags which are always self-closed. For example, <hr>Some content here</hr> does not make any sense. In the same way, there are tags which cannot be self-closed. <script> tag is one of them.
I am not sure about the reason of no self-closed <script> tags, but the reason might come from the fact that the tag was intended to always contain code inside. Again, I'm not sure.

Because it gets parsed as:
Line 1: Start tag for script
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"/>
Line 2: JavaScript (really broken JavaScript!) to execute if the external script mentioned on line 1 fails to load
<script type='text/javascript' src='/lib/player/swfobject.js'>
Line 3: End tag for script started on line 1
</script>
Okay, granted a tag that is closed and a self closing tag are not the same.
They are the same (if there is no content), but only in XML documents. An XHTML document served as application/xhtml+xml is an XML document. In an HTML document, thanks to a legacy of improper implementations by browsers, a self-closing tag is just a start tag (and so is only OK when the end tag is forbidden).

David Dorward's answer explains this from one angle, but there is a deeper reason why you can't do this:
A slash at the end of a tag does not make it self-closing in HTML
The self-closing syntax is part of XML. In a normal HTML document, it has no meaning.

#Joe Hopfgartner: Did you alter the code to test if
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js" />
<script type="text/javascript" src="/lib/player/swfobject.js" />
works? ;-)
Update:
Run the code and the <p> element gets hidden, so...looks like it works?
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">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>questions/4531772</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"/>
<script type="text/javascript" src="4531772.js"/>
</head>
<body>
<p class="test">Testing...</p>
</body>
</html>
JavaScript (4531772.js)
$(document).ready(function() {
$('.test').hide();
});

Related

Link stylesheet preload vs W3C validation

I'm trying to satisfy 2 checkers: W3C validator and google page insight
Google Page Insight suggested to me to load asynchronously all blocking CSS files. Well, I've rewritten the stylesheet file inclusion in preload way, as follow, and deferred from head to the end of the body:
...
<link rel="preload" href="mystyles.css" media="all" as="style"
onload="this.rel='stylesheet'"/>
</body>
Google Page Insight forced me to get it out from the head and put it at the end of the body.
Ok, I'm OK against Google Page Insight.
But W3C Validator says me now:
Error: A link element must not appear as a descendant of a body element unless the link element has an itemprop attribute or has a rel attribute whose value contains dns-prefetch, pingback, preconnect, prefetch, prerender, or stylesheet
Why "preload" is not admitted in rel attribute out of the head? I've tried to assign an itemprop, but it's not possible to have an itemprop and a rel in the same link.
Maintainer of the W3C HTML checker (validator) here. A checker bug was caused this. When I added rel=preloadsupport to the checker, I forgot to add it to the list of the rel values the checker code compares against to decide if a particular link element is allowed in the body.
I’ve now fixed it in the checker sources and pushed the fix to https://validator.w3.org/nu/.
So, the checker will no longer report an error for the code above. Thanks for catching this.
I use an example
<!DOCTYPE html>
<html lang="">
<head>
<title>Test</title>
<link rel="preload" href="style.css" as="style">
<link rel="stylesheet" href="style.css">
</head>
<body>
<p></p>
</body>
</html>
and https://validator.w3.org/nu/#textarea return success.
look in https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content

How to change doctype to standards mode without having access to the code?

I am designing a site based a .NET software CMS solution that doesn't follow current best practices. It uses tables and a doctype of <!-- DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" -->. The software company doesn't let you edit .aspx files or js. They only let you edit the stylesheet and different modules, e.g. HTML module, weather module, slideshow module, etc.
Thus, IE always renders the site in quirks mode breaking the CSS. I do not have access to change the doctype or edit anything in <head></head>.
Is there a way to change the doctype without being able to access the code?
What I have to deal with:
<!--DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" -->
<html>
<head id="htmlHead"><title>
Welcome to xxx
</title>
<script type="text/javascript" language="JavaScript">
function stopError()
{
return true;
}
window.onerror = stopError;
</script>
<link href="xxx.css" rel="stylesheet" type="text/css" />
<meta name="ROBOTS" content="INDEX,NOFOLLOW" />
<link href="xxx/favicon.ico" rel="SHORTCUT ICON" />
<style id="spMenuStyle"></style>
<link id="ApplicationRoot" rel="AppRoot" href="/xxx/" /><script type="text/javascript" src="/xxx/scripts/Utility.js">
</script>
<script type="text/javascript" language="javascript" sr="cxxx/BlockIFrame.js">
</script>
<link href="/xxx/WebResource.axd?d=9IeP9KvvsN3Ik1tvDsOJspkYjKE_KnZBT8bvXX7faYYRqxbjgHhLZKgtKfFSoL4-itgpmZrgTG68lyrA-SRm95xnEdLdUHa4j1nbnB_xoc_0zNWbtGMRDJOai6Kgu4UI0Dg5lw2&t=634950712700000000" type="text/css" rel="stylesheet" class="Telerik_stylesheet" />
</head>
If you're able to inject your own JavaScript you might be able to inject the X-UA-Compatible meta tag.
This code will inject the meta tag and force IE to run in edge mode, which means IE will treat it as standards mode:
var meta = document.createElement('meta');
meta.setAttribute('http-equiv', 'x-ua-compatible');
meta.setAttribute('content', 'IE=edge');
document.getElementsByTagName('head')[0].appendChild(meta);
You can learn about the meta tag here.

how to add header and body tag to both header.asp and default.asp?

i tried to do this and i got an error.
this is the header:
<head>
<link href="styles.css" rel="stylesheet" type="text/css">
<!--#include file="functions.asp"-->
</head>
<body>
<div>etc...
this is default.asp:
<html>
<head>
<title>jh</title>
<link href="JHstyles.css" rel="stylesheet" type="text/css">
</head>
<body>
<!--#include file="/header.asp"-->
<!--#include file="header-jh.asp"-->
<table... etc
Although I am not used to classic ASP (this is different to the newer ASP.NET) it looks like you are creating a document structure error - the combined document would look like:
<html>
<head>
<title>jh</title>
<link href="JHstyles.css" rel="stylesheet" type="text/css">
</head>
<body>
<head>
<link href="styles.css" rel="stylesheet" type="text/css">
<!--#include file="functions.asp"-->
</head>
<body>
<!-- div content etc. -->
<!--#include file="header-jh.asp"-->
<!-- Table and other content -->
</body>
</html>
Note that the head and document elements appear twice, which is invalid - in any document the head and body elements should appear exactly once, with the head as the first child of the html element. See https://developer.mozilla.org/en-US/docs/HTML/Element/head and https://developer.mozilla.org/en-US/docs/HTML/Element/body
There is a new header element in HTML5 which is meant to represent the page header content within the body, as a new semantic element, but the head element should never appear as a child of body, or body as a child of head.
In PHP, the closest construct I have used to classic ASP, I would normally create a header.php file that would include the doctype, opening HTML tag, and entire head element - using variables to pass in the page title and any custom scripts/stylesheets. I don't know if this approach would work in classic ASP but conceptually there is no reason it shouldn't, you'll just need someone with more experience of classic ASP to advise you.
As it stands you'll either need to remove everything but the stylesheet(s) and functions.asp include reference from your header.asp file, and move the include up inside the head on the default.asp file, or start the head element in default.asp (to allow for the title) and finish it in header.asp (removing the closing head and opening body tags from default.asp).
With reference to the HTTP 500 error, this is a server error, and I would expect it to be a result of the server failing to locate one or more of your included files. Make sure that there are files functions.asp, header.asp and header-jh.asp in the same directory as default.asp - I'd also remove the leading / from header.asp - in other languages references to files are made relative to the directory containing the file, for example ../header.asp if the header.asp file is contained in the parent directory of default.asp, and not using HTML relative paths to the root of the website domain.
I hope this helps.

Browser displays page without styles for a short moment (visual glitch)

I have observed that, very infrequently, Internet Explorer (7 or 8, it does not matter) displays our web pages (www.epsitec.ch) a short time without applying the CSS. The layout appears completely broken, with everything displayed sequentially from top to bottom. When the page has finished loading, everything finally gets displayed properly.
Our web pages do not use any fancy scripting, just two javascript inclusions for QuantCast and Google Analytics, done at the end of the page. By the way, we already had the issue before adding the QuantCast script. The CSS gets linked in the <head> section:
<head>
<title>Crésus Comptabilité</title>
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="http://www.epsitec.ch/favicon.ico" />
<link href="../../style.css" rel="stylesheet" type="text/css" />
...
</head>
and then follows static HTML up to the final chunk which includes the JavaScript:
...
<div id="account">
<a class="deselect" href="/account/login">Identifiez-vous</a>
<script type="text/javascript">
_qoptions={qacct:"..."};
</script>
<script type="text/javascript" src="http://edge.quantserve.com/quant.js">
</script>
<noscript>
<img src="..." style="display: none;" border="0" height="1" width="1"/>
</noscript>
</div>
<div id="contact">
Contactez-nous
</div>
<div id="ending"><!-- --></div>
</div>
<script type="text/javascript">
...
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker("...");
pageTracker._initData();
pageTracker._trackPageview();
</script>
</body>
As this is a very short visual glitch, I have no idea what provokes it. Worse, I cannot reproduce it and it appears only on seldom occasions. How can I further investigate the cause of the glitch? Are there any best practices I should be aware of?
This is called a FOUC, a Flash Of Unstyled Content, and is well documented and explained here: http://www.bluerobot.com/web/css/fouc.asp/
FOUC has to do with the order of loading external assets like CSS and JS files.
Inline script snippets block downloading of subsequent assets until they are interpreted. This is one of the causes for FOUC.
A best-practice for front-end performance as well as avoiding FOUC is to have your CSS files referenced in the <head> of your document and your JavaScript right before the closing </body> tag.
This makes the browser download styles, render the page, then apply JavaScript.
I did not have the problem, usually has to do with internet connection. CSS loading slowly.
I was having this same problem. I simply switched the order in which stylesheets and javascript were getting loaded in the head of layouts/application.html.erb. So now the stylesheets get loaded first and then the javascript.
Like so:
<head>
<title><%= full_title yield(:title) %></title>
<%= stylesheet_link_tag :application, media: "all" %>
<%= javascript_include_tag :application %>
<%= csrf_meta_tags %>
</head>

Embedding extra styles with noscript

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.
noscript in head is valid HTML5. It wasn't valid before. I just tested it, it works in current Firefox, Safari, Chrome, Opera and IE.
<!doctype html>
<html>
<head>
<noscript>
<style>body{background:red}</style>
</noscript>
</head>
<body>
<p>is this red? it should <script>document.writeln("not");</script> be. <noscript>indeed.</noscript></p>
</body>
</html>
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.
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
Html tag has a class attributes with no-js
Head tag includes a first modernizr javascript as the first
CSS has the element (.hide-me) with display:none on its proper place
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 :)
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>
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.
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
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.

Resources