A script
element that got styled as display:block
appears visible. Why is it possible and is there any real use case where it is desired?
td > * {
display: block;
}
<table>
<tr>
<td>
<script type="text/javascript">
var test = 1;
</script>von 1
</td>
</tr>
</table>
The HTML5 specification defines a style sheet that user agents (like browsers) are expected to use. Section 10.3.1 lists the styles for "Hidden elements":
@namespace url(http://www.w3.org/1999/xhtml);
[hidden], area, base, basefont, datalist, head, link,
meta, noembed, noframes, param, rp, script, source, style, template, track, title {
display: none;
}
embed[hidden] { display: inline; height: 0; width: 0; }
As you can see, it applies display: none;
to script
.
This is the only "barrier" between your users and hidden script
elements. It’s perfectly fine and intended to be able to overwrite styles from user-agent style sheets within author style sheets (and of course also within user style sheets).
Why someone might want to use it? One use case is displaying content without having to escape characters like <
/>
, similar to the old xmp
element. The script
element can be used not only for scripts, but also for data blocks (i.e., for anything with a MIME type).
Why can <script>
Tags be visible?
Because they are HTML elements like any other and there is no reason to write special case rules in the HTML specification (which would add complexity) to prevent CSS from applying to them.
Any element can be styled. Take, for example:
head { display: block; }
title { display: block; }
meta { display: block; }
meta[charset]:after { display: block; content: attr(charset); }
meta[content]:after { display: block; content: attr(content); }
Is there any Usecase where it is wanted?
Certainly no common ones, but general rules aren't designed to make sense for everything that you can apply them to. They are designed for the common cases.
Another (not common) use case:
I sometimes use <script>
tags for brief HTML code examples in style guides. That way I don't have to escape HTML tags and special characters. And text editor tag autocomplete and syntax highlighting still work. But there's no easy way to add syntax highlighting in the browser.
script[type="text/example"] {
background-color: #33373c;
border: 1px solid #ccc;
color: #aed9ef;
display: block;
font-family: monospace;
overflow: auto;
padding: 2px 10px 16px;
white-space: pre-wrap;
word-break: break-all;
word-wrap: break-word;
}
<p>Here comes a code example:</p>
<script type="text/example">
<div class="cool-component">
Some code example
</div>
</script>
Possible use case: for debugging purposes.
You could apply a class at the document level, eg. <body class="debugscript">
, then use some CSS:
body.debugscript script {
display: block;
background: #fcc;
border: 1px solid red;
padding: 2px;
}
body.debugscript script:before {
content: 'Script:';
display: block;
font-weight: bold;
}
body.debugscript script[src]:before {
content: 'Script: ' attr(src);
}
Script tags are hidden by default by using display:none;
. Unor1 explains the underlying language specification. However, they are still part of the DOM and can be styled accordingly.
That said, it is important to keep in mind exactly what a script tag is doing. While it used to be accompanied by types and languages, that is no longer required. It is now assumed that JavaScript is in there, and as a result browsers will interpret and execute the script as it is encountered (or loaded) from these tags.
Once the script has been executed, the content of the tag is only text (often hidden) on the page. This text can be revealed, but it can also be removed because it is just text.
At the bottom of your page, right before the closing </html>
tag, you could very easily remove these tags along with their text and there would be no changes to the page.
For example:
(function(){
var scripts = document.querySelectorAll("script");
for(var i = 0; i < scripts.length; i++){
scripts[i].parentNode.removeChild(scripts[i]);
}
})()
This will not remove any functionality, as the state of the page has already been altered and is reflected in the current global execution context. For example, if the page had loaded a library such as jQuery, removing the tags will not mean that jQuery is no longer exposed because it has already been added to the page's runtime environment. It is essentially only making the DOM inspection tool not show script elements, but it does highlight that the script elements once executed really are only text.
1. unor, Thu Jul 07 2016, wutzebaer, "When should tags be visible and why can they?", Jul 1 at 10:53, https://stackoverflow.com/a/38147398/1026459