C. Writing CSS into the pageThe third method of CSS modification is a rather specialized one that should be used only to enhance the accessibility of a page. It works as follows: document.write('<style>element {property: value}</style>'); document.write('<link rel="stylesheet" href="specialstyles.css" />'); The purpose of this method is to define styles that should only be used when JavaScript is enabled. If JavaScript is disabled, or if the browser fails its object-detection checks, the document.write is never executed, and the styles are never applied.
Dropdown Menus uses this method: [Dropdown Menus, lines 1-4] var compatible = (document.getElementsByTagName && document.createElement); if (compatible) document.write('<link rel="stylesheet" href="navstyles.css" />') These are the first lines of the script. Note that they are not contained within any function; they are executed as soon as the browser has parsed them, and as we'll see in a moment this is a vital part of such CSS modifications. The script checks whether the browser supports the W3C DOM, as discussed in 3C. If the browser survives the check, the document.write line adds a special style sheet, navstyles.css, to the page. The reason for this special construction is accessibility. This is the most important part of that style sheet: ul.menutree ul { display: none; position: absolute; } When applied without checking the browser support, these styles are actively dangerous. display: none hides the submenus, and without JavaScript there's no way to make them visible. The menu becomes inaccessible. Even if this problem were somehow solved, noscript users would see a confused jumble of submenus, because they're all positioned absolutely in their parent <li> and overlap each other when they're all visible. Therefore, I also want to hide the position: absolute until I'm certain the browser supports the necessary JavaScript to handle the submenus properly. Figure 9.1. Even without display: none, the position: absolute makes for inaccessible and unusable dropdown menus. We have to hide this style.
Sandwich Picker does the opposite. The Sandwich Picker page contains this paragraph: <p >Unfortunately your browser doesn't support (enough) JavaScript to use the advanced form. You can always <a href="mailto:correct@address.nl">mail</a> us to order some sandwiches.</p> This provides noscript users with a way to order sandwiches. Obviously, this text should be hidden if the browser supports the script, since it'd only confuse "scripted" users. Therefore, the script adds an extra style: [Sandwich Picker, lines 4-7, condensed] if (W3CDOM) { document.write('<style>.noscript{display: none}</style>'); If the browser supports sufficient JavaScript, the noscript text is hidden. As we discussed in 2G, the usability of this solution is not all that it could have been. Nonetheless, technically it's a correct example of hiding elements from the advanced, scripted interface. Execute immediatelyWhen using this method, it's very important that you apply the special styles as soon as possible. If you don't, because you wait for the load event, your users might see an ugly flickering when elements that were visible are suddenly hidden, or vice versa. By adding the special styles up front, the styles are already there when the browser starts loading the HTML, and all elements have the right show/hide instructions at the moment they're created and rendered. That's why document.write is right at the top of the JavaScript file, outside any function. I want it executed while the browser parses the JavaScript file, and before it starts loading the HTML.
Incidentally, XMLHTTP Speed Meter does it wrong. The script should hide the form's Submit button when sufficient JavaScript is supported, but it does so only at onload, which is too late: [XMLHTTP Speed Meter, lines 19-22] window.onload = function () { var supportCheck = [check support]; if (!supportCheck) return; document.getElementById('submitImage').style.display = 'none'; If the page is slow in building, visitors will first see the submit image, but then all of a sudden it's hidden. That is confusing, and I should have used the document.write() trick here, too. Used correctly, this method is a powerful accessibility tool. Used incorrectly, it can cause serious trouble. Always think out all the scenarios before using document.write to add styles, and test your pages with JavaScript disabled. |