¿Cuándo deberían estar visibles las etiquetas <script> y por qué pueden hacerlo?

142

Un scriptelemento que se diseñó como display:blockaparece visible. ¿Por qué es posible y hay algún caso de uso real donde se desee?

td > * {
  display: block;
}
<table>
  <tr>
    <td>
      <script type="text/javascript">
        var test = 1;
      </script>von 1
    </td>
  </tr>
</table>

wutzebaer
fuente
55
He visto un CSS visible <style>con contenido editable. Buena manera de ver los efectos en tiempo real.
John Dvorak
19
Para su próximo desafío, idee una forma de hacer visibles los comentarios.
Sr. Lister el
11
Vine aquí para mencionar lo mismo, @ JanDvorak. Soplé mi minuto la primera vez que lo vi. Tengo una demostración de esto en codepen
Kjeld Schmidt
66
Me recuerda a La travesía del viajero del alba cuando Lucy lee un hechizo que hace visible Aslan, y se sorprende que la magia afectaría a él , y él dice básicamente, creías que iba a desobedecer mis propias reglas?
David Conrad
44
Entré aquí pensando que esta era una pregunta básica y me fui aprendiendo algo nuevo. I <3 sof.
Jacksonkr

Respuestas:

104

La especificación HTML5 define una hoja de estilo que los agentes de usuario (como los navegadores) deben usar. La Sección 10.3.1 enumera los estilos para "Elementos ocultos":

@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; }

Como puede ver, se aplica display: none;a script.

Esta es la única "barrera" entre sus usuarios y scriptelementos ocultos . Está perfectamente bien y está diseñado para poder sobrescribir estilos de hojas de estilo de agente de usuario dentro de hojas de estilo de autor (y, por supuesto, también dentro de hojas de estilo de usuario).

¿Por qué alguien podría querer usarlo? Un caso de uso es mostrar contenido sin tener que escapar caracteres como </> , similar al xmpelemento anterior. El scriptelemento puede usarse no solo para scripts, sino también para bloques de datos (es decir, para cualquier cosa con un tipo MIME).

unor
fuente
Los datos ya deben estar codificados en <script>- los bloques de datos no pueden cargarse src.
@PauliSudarshanTerho: Sí, si se usa como bloque de datos, el srcatributo no está permitido en el scriptelemento.
hasta el
71

¿Por qué pueden <script>ser visibles las etiquetas?

Debido a que son elementos HTML como cualquier otro y no hay razón para escribir reglas de casos especiales en la especificación HTML (lo que agregaría complejidad) para evitar que CSS se aplique a ellos.

Cualquier elemento puede ser estilizado. Toma por ejemplo:

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); }

¿Hay algún caso de uso donde se quiera?

Ciertamente no hay reglas comunes, pero las reglas generales no están diseñadas para tener sentido en todo lo que puede aplicar. Están diseñados para los casos comunes.

Quentin
fuente
9
De hecho, si observa una etiqueta de script en el inspector de Chrome, veráuser agent stylesheet: script {display:none}
Niet the Dark Absol el
8
Yo haría que los "elementos DOM como cualquier otro". De hecho, son etiquetas HTML bastante especiales con sus reglas de análisis.
Bergi
2
Dato curioso: dado que el contenido del script se analiza como CDATA, puede usarlo <script type="text/plain">como lo hizo <xmp>en el pasado, pero aún así es compatible con el validador W3C.
Sr. Lister el
2
¿Por qué script {display: block !important;}no funciona cuando no hay una regla de caso especial?
wutzebaer 01 de
3
@wutzebaer Funciona bien para mí. ¿Estás seguro de que estás haciendo todo bien? Tenga en cuenta que la scriptetiqueta también debe estar en un elemento visible: solo mostrará scriptsu cuerpo, no, headpor ejemplo, de forma predeterminada.
Luaan
36

Otro caso de uso (no común):

A veces uso <script>etiquetas para ejemplos breves de código HTML en guías de estilo. De esa manera no tengo que escapar de las etiquetas HTML y los caracteres especiales. Y el editor de texto etiqueta autocompletar y el resaltado de sintaxis aún funcionan. Pero no hay una manera fácil de agregar resaltado de sintaxis en el navegador.

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>

jfrej
fuente
2
No está mal, aunque sugeriría usar un tipo MIME válido: text/htmly usar algo como class="codesample"para aplicar estilos. Solo por razones pedantes: D
Niet the Dark Absol
55
@NiettheDarkAbsol: Probablemente sea más seguro no usar un tipo MIME "real" (o cualquier cosa que pueda convertirse en uno en el futuro), en caso de que algún navegador algún día decida analizar y ejecutar elementos de script de ese tipo de alguna manera. Dicho esto, preferiría usar el x-prefijo estándar para tipos personalizados, es decir, hacerlo text/x-example.
Ilmari Karonen 01 de
14

Caso de uso posible: para fines de depuración.

Puede aplicar una clase a nivel de documento, por ejemplo. <body class="debugscript">, luego usa un poco de 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);
}
Niet the Dark Absol
fuente
1
¿Por qué no <html class="debugscript">?
Bergi
@Bergi Esa también es una opción, aunque probablemente no revelará los <head>scripts porque el <head>mismo también lo tiene, display:nonepor lo que deberías revelarlo por la fuerza, lo que podría conducir a más complicaciones.
Niet the Dark Absol
10
Te refieres a "más diversión" o "mayor potencial de depuración" :-)
Bergi
1

Las etiquetas de script están ocultas de forma predeterminada al usar display:none;. Unor 1 explica la especificación del lenguaje subyacente. Sin embargo, todavía son parte del DOM y se pueden diseñar en consecuencia.

Dicho esto, es importante tener en cuenta exactamente lo que está haciendo una etiqueta de script. Si bien solía ir acompañado de tipos e idiomas, ya no es necesario. Ahora se supone que JavaScript está allí y, como resultado, los navegadores interpretarán y ejecutarán el script tal como se encuentra (o carga) desde estas etiquetas.

Una vez que se ha ejecutado el script, el contenido de la etiqueta es solo texto (a menudo oculto) en la página. Este texto se puede revelar, pero también se puede eliminar porque es solo texto.

En la parte inferior de su página, justo antes de la </html>etiqueta de cierre , puede eliminar fácilmente estas etiquetas junto con su texto y no habrá cambios en la página.

Por ejemplo:

(function(){
    var scripts = document.querySelectorAll("script");
    for(var i = 0; i < scripts.length; i++){
        scripts[i].parentNode.removeChild(scripts[i]);
    }
})()

Esto no eliminará ninguna funcionalidad, ya que el estado de la página ya ha sido alterado y se refleja en el contexto de ejecución global actual. Por ejemplo, si la página había cargado una biblioteca como jQuery, eliminar las etiquetas no significará que jQuery ya no esté expuesto porque ya se ha agregado al entorno de tiempo de ejecución de la página. Esencialmente solo hace que la herramienta de inspección DOM no muestre elementos de script, pero resalta que los elementos de script una vez ejecutados realmente son solo texto.

1. unor, jue 07 de julio de 2016, wutzebaer, "¿Cuándo deberían estar visibles las etiquetas y por qué pueden hacerlo?", 1 de julio a las 10:53, https://stackoverflow.com/a/38147398/1026459

Travis J
fuente