Sometimes when you build a demo HTML document and you want to display the source code of the script in it. The problem is that often your script and what you show gets out of sync when you hard-code it into your docs.
One way would be to load the script via fetch()
and display it and there are myriads of packages that do that for you.
A super simple way to do the same though relies on you embedding the script inside the body of the document. Once you do that, you can use CSS to set its display
to block
and white-space
to pre
and voilà: embedded source code:
script {
display: block;
white-space: pre;
padding: 0 1em 1em 1em;
color: #fff;
background: #000;
}
Two things to remember though: script can be long and this basic CSS would also display script blocks without content that point to a file with a src
attribute.
You can fix that with a not()
selector, setting a height
and overflow:scroll
:
script:not([src]) {
display: block;
white-space: pre;
padding: 0 1em 1em 1em;
color: #fff;
background: #000;
overflow: scroll;
height: 5em;
}
You can even tell your readers what's going on here by setting the display of the script
element to relative
and use generated content with a position
of fixed
. Giving it some padding and margins to display it over the box makes it stand out.
script:not([src]) {
display: block;
white-space: pre;
padding: 0 1em 1em 1em;
color: #fff;
background: #000;
overflow: scroll;
height: 15em;
position: relative;
}
script:not([src])::before {
content: "Source code (JavaScript):";
background: orchid;
width: auto;
display: block;
position: fixed;
padding: 2px 5px;
margin: -1em 0 0 -0.5em;
}
Sweet, but what about CSS source code?
If you put the style block into the body, you can also style it. This is not where it should be, but in a tutorial, why not? All you need to do is to add style
to the script
selector.
script:not([src]),style {
display: block;
white-space: pre;
padding: 0 1em 1em 1em;
color: #fff;
background: #000;
overflow: scroll;
height: 5em;
position: relative;
}
If the style block is the first element in the document, it needs some margin. And if you don't want to use the same text to display it, it makes sense to add a different before setting:
style {
margin: 2em 0 1em 0;
}
style::before {
content: "Source code (CSS):";
background: orchid;
width: auto;
display: block;
position: fixed;
padding: 2px 5px;
margin: -1em 0 0 -0.5em;
}
Here be dragons: making things editable
OK, here is where it gets wild. If you add a contenteditable="true"
attribute to your style block, you can even allow readers to change the settings live and play with them.
Whilst this is cool and all, it is not a good idea to put out into the wild without any filtering server-side scripts, as an editable block also allows attackers to include any JavaScript to steal credentials and override other scripts on your server. I did use this in HTML slidedecks in the past with the result of getting my server hacked. So, better not to go that way…
If you want to know more about the demo page shown here, it is part of my CanvasShift.js script on GitHub and there is a detailed blog post