Quand les balises <script> doivent-elles être visibles et pourquoi le peuvent-elles?

142

Un scriptélément qui a été stylé comme display:blockapparaît visible. Pourquoi est-ce possible et existe-t-il un cas d'utilisation réel où cela est souhaité?

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

wutzebaer
la source
55
J'ai vu un CSS visible <style>avec un contenu modifiable. Belle façon de voir les effets en temps réel.
John Dvorak
19
Pour votre prochain défi, imaginez un moyen de rendre les commentaires visibles.
Mr Lister
11
Je suis venu ici pour mentionner la même chose, @JanDvorak. Blew my min la première fois que je l'ai vu. J'en ai une démonstration sur codepen
Kjeld Schmidt
6
Cela me rappelle le Voyage du Passeur d' aurore quand Lucy lit un sort qui rend visible Aslan, et elle est surpris que la magie aurait une incidence sur lui , et il dit au fond, avez - vous que je désobéir à mes propres règles?
David Conrad
4
Je suis venu ici en pensant que c'était une question fondamentale et je suis parti après avoir appris quelque chose de nouveau. I <3 sof.
Jacksonkr

Réponses:

104

La spécification HTML5 définit une feuille de style que les agents utilisateurs (comme les navigateurs) sont censés utiliser. La section 10.3.1 répertorie les styles des «éléments cachés»:

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

Comme vous pouvez le voir, cela s'applique display: none;à script.

C'est la seule "barrière" entre vos utilisateurs et les scriptéléments cachés . C'est parfaitement bien et destiné à pouvoir écraser les styles des feuilles de style de l'agent utilisateur dans les feuilles de style de l'auteur (et bien sûr aussi dans les feuilles de style de l'utilisateur).

Pourquoi quelqu'un voudrait-il l'utiliser? Un cas d'utilisation est d' afficher du contenu sans avoir à échapper des caractères comme </> , similaire à l'ancien xmpélément. L' scriptélément peut être utilisé non seulement pour les scripts, mais aussi pour les blocs de données (c'est-à-dire pour tout ce qui est de type MIME).

unor
la source
Les données doivent déjà être codées dans le <script>- les blocs de données ne peuvent pas être chargés par src.
@PauliSudarshanTerho: Oui, s'il est utilisé comme bloc de données, l' srcattribut n'est pas autorisé sur l' scriptélément.
unor
71

Pourquoi les <script>balises peuvent-elles être visibles?

Parce qu'ils sont des éléments HTML comme les autres et qu'il n'y a aucune raison d'écrire des règles de cas particuliers dans la spécification HTML (ce qui ajouterait de la complexité) pour empêcher le CSS de s'y appliquer.

Tout élément peut être stylisé. Prends pour exemple:

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

Y a-t-il un cas d'utilisation où il est souhaité?

Certainement pas de règles communes, mais les règles générales ne sont pas conçues pour avoir un sens pour tout ce à quoi vous pouvez les appliquer. Ils sont conçus pour les cas courants.

Quentin
la source
9
En fait, si vous regardez une balise de script dans l'inspecteur Chrome, vous voyezuser agent stylesheet: script {display:none}
Niet the Dark Absol
8
Je ferais ça "des éléments DOM comme les autres". En fait, ce sont des balises HTML assez spéciales avec leurs règles d'analyse.
Bergi
2
Fait amusant: puisque le contenu du script est analysé comme CDATA, vous pouvez l'utiliser <script type="text/plain">comme vous le pouviez <xmp>dans le passé, mais toujours compatible avec le validateur W3C.
Mr Lister
2
pourquoi ne script {display: block !important;}fonctionne pas lorsqu'il n'y a pas de règle de cas particulier?
wutzebaer
3
@wutzebaer Cela fonctionne bien pour moi. Êtes-vous sûr de tout faire correctement? Notez que la scriptbalise doit également être dans un élément visible - elle ne vous montrera que scriptdans le corps, pas headpar exemple par défaut.
Luaan
36

Un autre cas d'utilisation (pas courant):

J'utilise parfois des <script>balises pour de brefs exemples de code HTML dans les guides de style. De cette façon, je n'ai pas à échapper aux balises HTML et aux caractères spéciaux. Et la saisie semi-automatique des balises de l'éditeur de texte et la coloration syntaxique fonctionnent toujours. Mais il n'y a pas de moyen facile d'ajouter une coloration syntaxique dans le navigateur.

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
la source
2
Pas mal, bien que je suggère d'utiliser un type MIME valide:, text/htmlet d'utiliser quelque chose comme class="codesample"pour appliquer des styles. Juste pour des raisons pédantes: D
Niet the Dark Absol
5
@NiettheDarkAbsol: Il est probablement plus sûr de ne pas utiliser un "vrai" type MIME (ou tout ce qui pourrait en devenir un dans le futur), juste au cas où un navigateur déciderait un jour d'analyser et d'exécuter des éléments de script de ce type d'une manière ou d'une autre. Cela dit, je préférerais utiliser le x-préfixe standard pour les types personnalisés, c'est-à-dire le faire text/x-example.
Ilmari Karonen
14

Cas d'utilisation possible: à des fins de débogage.

Vous pouvez appliquer une classe au niveau du document, par exemple. <body class="debugscript">, puis utilisez du 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
la source
1
Pourquoi pas <html class="debugscript">?
Bergi
@Bergi C'est également une option, même si elle ne révélera probablement pas de <head>scripts, car <head>elle - même l'a également display:none, vous devrez donc le révéler de force, ce qui pourrait entraîner d'autres complications.
Niet the Dark Absol
10
Vous voulez dire "plus de plaisir" ou "plus de potentiel de débogage" :-)
Bergi
1

Les balises de script sont masquées par défaut à l'aide de display:none;. Unor 1 explique la spécification du langage sous-jacent. Cependant, ils font toujours partie du DOM et peuvent être stylisés en conséquence.

Cela dit, il est important de garder à l'esprit exactement ce que fait une balise de script. Alors qu'il était autrefois accompagné de types et de langues, cela n'est plus nécessaire. Il est maintenant supposé que JavaScript est là, et par conséquent, les navigateurs interpréteront et exécuteront le script lorsqu'il est rencontré (ou chargé) à partir de ces balises.

Une fois le script exécuté, le contenu de la balise est uniquement du texte (souvent masqué) sur la page. Ce texte peut être révélé, mais il peut également être supprimé car il ne s'agit que de texte.

Au bas de votre page, juste avant la </html>balise de fermeture , vous pourriez très facilement supprimer ces balises avec leur texte et il n'y aurait aucune modification de la page.

Par exemple:

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

Cela ne supprimera aucune fonctionnalité, car l'état de la page a déjà été modifié et se reflète dans le contexte d'exécution global actuel. Par exemple, si la page avait chargé une bibliothèque telle que jQuery, la suppression des balises ne signifie pas que jQuery n'est plus exposé car il a déjà été ajouté à l'environnement d'exécution de la page. Cela fait essentiellement que l'outil d'inspection DOM n'affiche pas les éléments de script, mais cela met en évidence que les éléments de script une fois exécutés ne sont en réalité que du texte.

1. unor, jeu 07 juillet 2016, wutzebaer, "Quand les tags doivent-ils être visibles et pourquoi le peuvent-ils?", 1er juillet à 10h53, https://stackoverflow.com/a/38147398/1026459

Travis J
la source