HTML preprocessors can make writing HTML more powerful or convenient. For instance, Markdown is designed to be easier to write and read for text documents and you could write a loop in Pug.
In CodePen, whatever you write in the HTML editor is what goes within the <body>
tags in a basic HTML5 template. So you don't have access to higher-up elements like the <html>
tag. If you want to add classes there that can affect the whole document, this is the place to do it.
In CodePen, whatever you write in the HTML editor is what goes within the <body>
tags in a basic HTML5 template. If you need things in the <head>
of the document, put that code here.
The resource you are linking to is using the 'http' protocol, which may not work when the browser is using https.
CSS preprocessors help make authoring CSS easier. All of them offer things like variables and mixins to provide convenient abstractions.
It's a common practice to apply CSS to a page that styles elements such that they are consistent across all browsers. We offer two of the most popular choices: normalize.css and a reset. Or, choose Neither and nothing will be applied.
To get the best cross-browser support, it is a common practice to apply vendor prefixes to CSS properties and values that require them to work. For instance -webkit-
or -moz-
.
We offer two popular choices: Autoprefixer (which processes your CSS server-side) and -prefix-free (which applies prefixes via a script, client-side).
Any URLs added here will be added as <link>
s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.
You can apply CSS to your Pen from any stylesheet on the web. Just put a URL to it here and we'll apply it, in the order you have them, before the CSS in the Pen itself.
You can also link to another Pen here (use the .css
URL Extension) and we'll pull the CSS from that Pen and include it. If it's using a matching preprocessor, use the appropriate URL Extension and we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.
JavaScript preprocessors can help make authoring JavaScript easier and more convenient.
Babel includes JSX processing.
Any URL's added here will be added as <script>
s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.
You can apply a script from anywhere on the web to your Pen. Just put a URL to it here and we'll add it, in the order you have them, before the JavaScript in the Pen itself.
If the script you link to has the file extension of a preprocessor, we'll attempt to process it before applying.
You can also link to another Pen here, and we'll pull the JavaScript from that Pen and include it. If it's using a matching preprocessor, we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.
Search for and use JavaScript packages from npm here. By selecting a package, an import
statement will be added to the top of the JavaScript editor for this package.
Using packages here is powered by esm.sh, which makes packages from npm not only available on a CDN, but prepares them for native JavaScript ESM usage.
All packages are different, so refer to their docs for how they work.
If you're using React / ReactDOM, make sure to turn on Babel for the JSX processing.
If active, Pens will autosave every 30 seconds after being saved once.
If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.
If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.
Visit your global Editor Settings.
<body>
<h1>Code highlighting with Prism.js</h1>
<p>A pen to highlight embedded code examples using Prism.js with a dark or light mode theme.</p>
<p>Reference the CSS and JavaScript of this pen, as external resources, to highlight code samples in other pens or projects. Alternatively, copy the <a href="#minified">Minified CSS & JS</a> into your own pages.</p>
<p>Supports light and dark mode switching via the OS setting, or <a target=_blank title="[new window]" href="https://codepen.io/2kool2/pen/abzgPzJ">Light & dark mode, with user-switch button</a> which, if used, would require importing separately.</p>
<p>Only <code class="language-css">pre[class*="language-"]{}</code> and <code class=language-css>code[class*="language-"]{}</code> are stylised where:</p>
<ul>
<li><code class=language-html><code class=language-html></code> – HTML (or XML)</li>
<li><code class=language-html><code class=language-css></code> – CSS</li>
<li><code class=language-html><code class=language-js></code> – JavaScript</li>
<li><code class=language-html><code class=language-clike></code> – PHP</li>
</ul>
<h2>The HTML code</h2>
<figure>
<figcaption>HTML <small>(semantic layout for a code block)</small></figcaption>
<pre><code class=language-html spellcheck=false contenteditable><figure>
<figcaption>Code title</figcaption>
<pre><code class=language-html contenteditable spellcheck=false>
… Code example here (Escaped HTML symbols/entities) …
</code></pre>
</figure></code></pre>
</figure>
<p>Ensure the code example has its HTML symbols escaped. That is, as a minimum, replace:</p>
<ul>
<li> < with &lt;</li>
<li> > with &gt;</li>
<li> & with &amp;</li>
</ul>
<p>To simplify the process I use the online tool: <a target=_blank title="[new window]" href="https://websemantics.uk/tools/escaping-html/">Escaping HTML symbols/entities</a></p>
<p>Both the <code class=language-html><figure></code> and <code class=language-html><figcaption></code> elements are unopinionated when importing the CSS from this pen.</p>
<p>The <code class=language-html>contenteditable</code> attribute makes the code block extremely keyboard friendly. Very usefully allowing:</p>
<ul>
<li>Arrow key navigation</li>
<li>Word, or line, selection (double, or triple, tap or click)</li>
<li>Jump to the end, or start, of a line or block, (cmd arrows)</li>
<li>Select all (cmd a, or ctrl a on a PC)</li>
<li>Copy (cmd c, or ctrl c on a PC)</li>
<li>Even allows custom editing prior to copying.</li>
</ul>
<style>
/* Page styles here so the CSS is unpolluted for use in other pens */
h2 {
font-weight: 100;
}
/* Grid spacing */
[class^="grid_parent"] {
--spacing: 1rem;
--bgGridItem: hsla(214, 100%, 90%, 0.1);
--borderGridItem: #ccc;
margin: 0;
}
@media (min-width: 48em) { /* 768px */
[class^="grid_parent"] {
--spacing: 1rem;
}
}
[data-lightMode="dark"] [class^="grid_parent"] {
--bgGridItem: hsla(214, 0%, 0%, 0.2);
--borderGridItem: #333;
}
/* The grid */
[class^="grid-"] {
--columns: 1;
display: grid;
grid-gap: var(--spacing);
grid-template-columns: var(--columns);
}
@media (min-width: 40em) { /* 640px */
[class^="grid-2"] {
--columns: 1fr 1fr;
}
}
@media (min-width: 60em) { /* 960px */
[class^="grid-3"],
[class^="grid-2_3"] {
--columns: 1fr 1fr 1fr;
}
}
@media (min-width: 80em) { /* 1280px */
[class^="grid-2_4"],
[class^="grid-2_3_4"] {
--columns: 1fr 1fr 1fr 1fr;
}
}
@media (min-width: 120em) { /* 1920px */
[class^="grid-2_3_6"],
[class^="grid-2_3_4_6"] {
--columns: 1fr 1fr 1fr 1fr 1fr 1fr;
}
}
/* Grid item */
[class^="grid_item"] {
/* Required, but may be changed */
min-width: calc(20rem - var(--spacing) * 3 - 2px);
padding: calc(var(--spacing) / 2);
margin: 0;
}
/* Jus' colourin' */
[class^="grid_item"] {
border: 1px solid var(--borderGridItem);
background-color: var(--bgGridItem);
transition:
border-color .3s ease-out,
background-color .3s ease-out;
}
</style>
<section class=grid_parent>
<h2>Test cases</h2>
<div class=grid-2_3>
<figure class=grid_item>
<figcaption>code <small>(unopinionated)</small></figcaption>
<code>p { color: red; }</code>
</figure>
<figure class=grid_item>
<figcaption>pre > code <small>(unopinionated)</small></figcaption>
<pre><code>p { color: red; }</code></pre>
</figure>
<figure class=grid_item>
<figcaption>code.language-css <small>(inline use)</small></figcaption>
<code class=language-css>p { color: red; }</code>
</figure>
<figure class=grid_item>
<figcaption>pre.language-css > code</figcaption>
<pre class=language-css><code>p { color: red; }</code></pre>
</figure>
<figure class=grid_item>
<figcaption>pre > code.language-css</figcaption>
<pre><code class=language-css>p { color: red; }</code></pre>
</figure>
<figure class=grid_item>
<figcaption>pre > code.language-css[contenteditable] <small>(recommended)</small></figcaption>
<pre><code class=language-css spellcheck=false contenteditable>p { color: red; }</code></pre>
</figure>
</div>
</section>
<h2>The stylesheet</h2>
<figure>
<figcaption>Common CSS for both modes <small>(generated at <a href="http://prismjs.com/">prismjs.com</a> then extended)</small></figcaption>
<pre><code class=language-css contenteditable spellcheck=false>[class*="language-"] ::selection {
color: #000;
background: hsl(214, 100%, 85%);
text-shadow: none;
}
pre[class*="language-"] {
overflow: auto;
margin: 0;
background-color: transparent;
/* Allow space for an overflow ellipsis */
padding-right: 0.5rem;
/* Allow space for SVG "tear off strip" */
background-origin: border-box;
border-left: 2.5rem solid transparent;
background-size: 120rem 4rem;
/* Single line does not sit on stripes */
background-position: top -1.2rem left 0;
/* Allow horizontal resizing - could be adjusted to allow vertical resizing too */
position: relative;
resize: horizontal;
min-width: calc(100% - 3rem);
transition: box-shadow .3s ease-out;
}
code[class*="language-"] {
font-family: monospace, monospace;
letter-spacing: 0.01em;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 2;
tab-size: 2;
hyphens: none;
}
pre > code[class*="language-"],
pre[class*="language-"] > code {
display: block;
padding: 0.75rem 0;
/* Use an ellipsis to indicate code is wider than the display area */
text-overflow: ellipsis;
overflow-x: scroll;
}
pre:hover > code[class*="language-"],
pre:focus-within > code[class*="language-"] {
outline: none;
text-overflow: inherit;
}
/* Inline code only */
:not(pre) > code[class*="language-"] {
font-size: inherit;
background-position: top right;
background-size: auto 4rem;
padding: 0.125em 0.25em;
white-space: normal;
word-wrap: nowrap;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
.namespace {
opacity: 0.7;
}</code></pre>
</figure>
<h2>Colours used</h2>
<p>Custom properties (CSS variables) are extensively used to define the highlight colours and the background image.</p>
<p>Colour contrast, in both modes, has been checked against WCAG 2 guidelines using <a target=_blank title="[new window]" href="https://websemantics.uk/tools/wcag-colour-contrast-checker/">WCAG colour contrast checker</a> and pass, at the least, to AA.</p>
<p>The design allows text zoom to 200%, and beyond, scaling the background accordingly and fully meeting WCAG requirements.</p>
<figure>
<figcaption>CSS default colours <small>(light-mode)</small></figcaption>
<pre><code class=language-css contenteditable spellcheck=false>:not(pre) > code[class*="language-"],
pre[class*="language-"] {
--color: #000;
--textShadow: #fff;
--comment: #6e6e6e;
--punctuation: #4e4e4e;
--property: #905;
--operator: #70b;
--selector: #487b00;
--url: #8d6640;
--urlBg: hsla(0, 0%, 100%, .5);
--boolean: #905;
--atrule: #0075a8;
--keyword: #0075a8;
--function: #c93654;
--regex: #860;
--boxShadow: hsla(0,0%,0%,.3);
--focusOutline: hsla(214, 100%, 85%, 1);
--codeBgImg: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1920 64'%3E%3Ccircle stroke='rgba(0,64,0,.3)' stroke-width='2' fill='none' cx='20' cy='49' r='12'/%3E%3Cpath fill='%23fcfcfa' fill-rule='evenodd' d='M1920 64H0V0h1920v64zM20 36a11 11 0 110 22 11 11 0 010-22z'/%3E%3Cpath stroke='%23edf3ed' stroke-width='2' d='M0 1h1920M0 5h1920M0 9h1920M0 13h1920M0 17h1920M0 21h1920M0 25h1920M0 29h1920'/%3E%3Cpath stroke='%23e4ede4' stroke-dasharray='2 6 2 6' stroke-width='2' d='M40 2v60'/%3E%3C/svg%3E");
}</code></pre>
</figure>
<figure>
<figcaption>CSS dark-mode colours <small>(media query)</small></figcaption>
<pre><code class=language-css contenteditable spellcheck=false>@media (prefers-color-scheme: dark) {
body:not([data-lightMode="light"]) code[class*="language-"]:not([contenteditable]),
body:not([data-lightMode="light"]) pre[class*="language-"] {
--color: #6ae;
--textShadow: #000;
--comment: #9ab;
--punctuation: #ccc;
--property: #e60;
--operator: #d7f;
--selector: #8b2;
--url: #cde;
--urlBg: rgba(0,0,0,.5);
--boolean: #a8f;
--atrule: #ffb;
--keyword: #f55;
--function: #fe6;
--regex: #f91;
--boxShadow: #000;
--focusOutline: hsla(214, 100%, 85%, .6);
--codeBgImg: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1920 64'%3E%3Ccircle stroke='rgba(0,0,0,.7)' stroke-width='2' fill='none' cx='20' cy='49' r='12'/%3E%3Cpath fill='%23101610' fill-rule='evenodd' d='M1920 64H0V0h1920v64zM20 36a11 11 0 110 22 11 11 0 010-22z'/%3E%3Cpath stroke='%23121' stroke-width='2' d='M0 1h1920M0 5h1920M0 9h1920M0 13h1920M0 17h1920M0 21h1920M0 25h1920M0 29h1920'/%3E%3Cpath stroke='%23121' stroke-dasharray='2 6 2 6' stroke-width='2' d='M40 2v60'/%3E%3C/svg%3E");
}
}</code></pre>
</figure>
<figure>
<figcaption>CSS dark-mode colours <small>(manual switch mode)</small></figcaption>
<pre><code class=language-css contenteditable spellcheck=false>body[data-lightMode="dark"] code[class*="language-"]:not([contenteditable]),
body[data-lightMode="dark"] pre[class*="language-"] {
/* Exactly the same as prefers-color-scheme: dark */
--color: #6ae;
--textShadow: #000;
--comment: #9ab;
--punctuation: #ccc;
--property: #e60;
--operator: #d7f;
--selector: #8b2;
--url: #cde;
--urlBg: rgba(0,0,0,.5);
--boolean: #8af;
--atrule: #ffb;
--keyword: #f55;
--function: #fe6;
--regex: #f91;
--boxShadow: #000;
--focusOutline: hsla(214, 100%, 85%, .6);
--codeBgImg: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1920 64'%3E%3Ccircle stroke='rgba(0,0,0,.7)' stroke-width='2' fill='none' cx='20' cy='49' r='12'/%3E%3Cpath fill='%23101610' fill-rule='evenodd' d='M1920 64H0V0h1920v64zM20 36a11 11 0 110 22 11 11 0 010-22z'/%3E%3Cpath stroke='%23121' stroke-width='2' d='M0 1h1920M0 5h1920M0 9h1920M0 13h1920M0 17h1920M0 21h1920M0 25h1920M0 29h1920'/%3E%3Cpath stroke='%23121' stroke-dasharray='2 6 2 6' stroke-width='2' d='M40 2v60'/%3E%3C/svg%3E");
}</code></pre>
</figure>
<figure>
<figcaption>CSS colour variable styles</figcaption>
<pre><code class=language-css contenteditable spellcheck=false>code[class*="language-"],
pre[class*="language-"] {
color: var(--color);
text-shadow: 0 1px var(--textShadow);
}
/* Background image is applied to the pre element on blocks, mainly because it is cropped when applied to the code element. */
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background-image: var(--codeBgImg);
}
pre[class*="language-"]:hover,
pre[class*="language-"]:focus-within {
box-shadow: 0 .25rem .25rem var(--boxShadow);
}
pre[class*="language-"]:focus-within {
outline-offset: calc(-0.25rem - 1px);
outline: var(--focusOutline) solid 0.25rem;
z-index: 5;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: var(--comment);
}
.token.punctuation {
color: var(--punctuation);
}
.token.property,
.token.symbol,
.token.tag,
.token.constant,
.token.deleted {
color: var(--property);
}
.token.boolean,
.token.number {
color: var(--boolean);
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: var(--selector);
}
.token.operator {
color: var(--operator);
}
.token.url,
.token.entity,
.language-css .token.string,
.style .token.string {
color: var(--url);
background-color: var(--urlBg);
}
.token.atrule,
.token.attr-value {
color: var(--atrule);
}
.token.keyword {
color: var(--keyword);
}
.token.function {
color: var(--function);
}
.token.regex,
.token.important,
.token.variable {
color: var(--regex);
}</code></pre>
</figure>
<h2>Miscellaneous</h2>
<figure>
<figcaption>Print styles</figcaption>
<pre><code class=language-css contenteditable spellcheck=false>@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}</code></pre>
</figure>
<figure>
<figcaption>Code paper SVG <small>(light-mode)</small></figcaption>
<pre class=pre-oneLine><code class=language-html contenteditable spellcheck=false><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 64">
<circle stroke="rgba(0,64,0,.3)" stroke-width="2" fill="none" cx="20" cy="49" r="12"/>
<path fill="#fcfcfa" fill-rule="evenodd" d="M1920 64H0V0h1920v64zM20 36a11 11 0 110 22 11 11 0 010-22z"/>
<path stroke="#edf3ed" stroke-width="2" d="M0 1h1920M0 5h1920M0 9h1920M0 13h1920M0 17h1920M0 21h1920M0 25h1920M0 29h1920"/>
<path stroke="#e4ede4" stroke-dasharray="2 6 2 6" stroke-width="2" d="M40 2v60"/>
</svg>
</code></pre>
</figure>
<figure>
<figcaption>Code paper SVG <small>(dark-mode)</small></figcaption>
<pre class=pre-oneLine><code class=language-html contenteditable spellcheck=false><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 64">
<circle stroke="rgba(0,0,0,.7)" stroke-width="2" fill="none" cx="20" cy="49" r="12"/>
<path fill="#101610" fill-rule="evenodd" d="M1920 64H0V0h1920v64zM20 36a11 11 0 110 22 11 11 0 010-22z"/>
<path stroke="#121" stroke-width="2" d="M0 1h1920M0 5h1920M0 9h1920M0 13h1920M0 17h1920M0 21h1920M0 25h1920M0 29h1920"/>
<path stroke="#131" stroke-dasharray="2 6 2 6" stroke-width="2" d="M40 2v60"/>
</svg></code></pre>
</figure>
<p>The SVG was converted into a CSS background using: <a target=_blank title="[new window]" href="https://websemantics.uk/tools/svg-to-background-image-conversion/">SVG to CSS background-image converter</a>. I did investigate using CSS variables here. Unfortunately, CSS vars do not work inside a background-image. Besides, it does allow for a different image in each mode.</p>
<h2 id=minified>Minified CSS & JavaScript</h2>
<figure>
<figcaption>All CSS <small>[5.10 KB, Gzip: 1.53 KB]</small></figcaption>
<pre class=pre-oneLine><code class=language-css contenteditable spellcheck=false>[class*="language-"] ::selection{color:#000;background:#b2d3ff;text-shadow:none}pre[class*=language-]{overflow:auto;margin:0;background-color:transparent;padding-right:.5rem;background-origin:border-box;border-left:2.5rem solid transparent;background-size:120rem 4rem;background-position:top -1.2rem left 0;position:relative;resize:horizontal;min-width:calc(100% - 3rem);transition:box-shadow .3s ease-out}code[class*=language-]{font-family:monospace,monospace;letter-spacing:.01em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:2;tab-size:2;hyphens:none}pre>code[class*=language-],pre[class*=language-]>code{display:block;padding:.75rem 0;text-overflow:ellipsis;overflow-x:scroll}pre:focus-within>code[class*=language-],pre:hover>code[class*=language-]{outline:0;text-overflow:inherit}:not(pre)>code[class*=language-]{font-size:inherit;background-position:top right;background-size:auto 4rem;padding:.125em .25em;white-space:normal;word-wrap:nowrap}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.namespace{opacity:.7}:not(pre)>code[class*=language-],pre[class*=language-]{--color:#000;--textShadow:#fff;--comment:#7a7a7a;--punctuation:#6e6e6e;--property:#905;--operator:#70b;--selector:#487b00;--url:#8d6640;--urlBg:hsla(0, 0%, 100%, .5);--boolean:#905;--atrule:#0075a8;--keyword:#0075a8;--function:#c93654;--regex:#860;--boxShadow:hsla(0,0%,0%,.3);--focusOutline:hsla(214, 100%, 85%, 1);--codeBgImg:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1920 64'%3E%3Ccircle stroke='rgba(0,64,0,.3)' stroke-width='2' fill='none' cx='20' cy='49' r='12'/%3E%3Cpath fill='%23fcfcfa' fill-rule='evenodd' d='M1920 64H0V0h1920v64zM20 36a11 11 0 110 22 11 11 0 010-22z'/%3E%3Cpath stroke='%23edf3ed' stroke-width='2' d='M0 1h1920M0 5h1920M0 9h1920M0 13h1920M0 17h1920M0 21h1920M0 25h1920M0 29h1920'/%3E%3Cpath stroke='%23e4ede4' stroke-dasharray='2 6 2 6' stroke-width='2' d='M40 2v60'/%3E%3C/svg%3E");background-image:var(--codeBgImg)}@media (prefers-color-scheme:dark){body:not([data-lightMode=light]) code[class*=language-]:not([contenteditable]),body:not([data-lightMode=light]) pre[class*=language-]{--color:#6ae;--textShadow:#000;--comment:#9ab;--punctuation:#ccc;--property:#e60;--operator:#d7f;--selector:#8b2;--url:#cde;--urlBg:rgba(0,0,0,.5);--boolean:#a8f;--atrule:#ffb;--keyword:#f55;--function:#fe6;--regex:#f91;--boxShadow:#000;--focusOutline:hsla(214, 100%, 85%, .6);--codeBgImg:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1920 64'%3E%3Ccircle stroke='rgba(0,0,0,.7)' stroke-width='2' fill='none' cx='20' cy='49' r='12'/%3E%3Cpath fill='%23101610' fill-rule='evenodd' d='M1920 64H0V0h1920v64zM20 36a11 11 0 110 22 11 11 0 010-22z'/%3E%3Cpath stroke='%23121' stroke-width='2' d='M0 1h1920M0 5h1920M0 9h1920M0 13h1920M0 17h1920M0 21h1920M0 25h1920M0 29h1920'/%3E%3Cpath stroke='%23121' stroke-dasharray='2 6 2 6' stroke-width='2' d='M40 2v60'/%3E%3C/svg%3E")}}body[data-lightMode=dark] code[class*=language-]:not([contenteditable]),body[data-lightMode=dark] pre[class*=language-]{--color:#6ae;--textShadow:#000;--comment:#9ab;--punctuation:#ccc;--property:#e60;--operator:#d7f;--selector:#8b2;--url:#cde;--urlBg:rgba(0,0,0,.5);--boolean:#8af;--atrule:#ffb;--keyword:#f55;--function:#fe6;--regex:#f91;--boxShadow:#000;--focusOutline:hsla(214, 100%, 85%, .6);--codeBgImg:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1920 64'%3E%3Ccircle stroke='rgba(0,0,0,.7)' stroke-width='2' fill='none' cx='20' cy='49' r='12'/%3E%3Cpath fill='%23101610' fill-rule='evenodd' d='M1920 64H0V0h1920v64zM20 36a11 11 0 110 22 11 11 0 010-22z'/%3E%3Cpath stroke='%23121' stroke-width='2' d='M0 1h1920M0 5h1920M0 9h1920M0 13h1920M0 17h1920M0 21h1920M0 25h1920M0 29h1920'/%3E%3Cpath stroke='%23131' stroke-dasharray='2 6 2 6' stroke-width='2' d='M40 2v60'/%3E%3C/svg%3E")}code[class*=language-],pre[class*=language-]{color:var(--color);text-shadow:0 1px var(--textShadow)}pre[class*=language-]:focus-within,pre[class*=language-]:hover{box-shadow:0 .25rem .25rem var(--boxShadow)}pre[class*=language-]:focus-within{outline-offset:calc(-.25rem - 1px);outline:solid var(--focusOutline);z-index:5}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:var(--comment)}.token.punctuation{color:var(--punctuation)}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:var(--property)}.token.boolean,.token.number{color:var(--boolean)}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:var(--selector)}.token.operator{color:var(--operator)}.language-css .token.string,.style .token.string,.token.entity,.token.url{color:var(--url);background-color:var(--urlBg)}.token.atrule,.token.attr-value{color:var(--atrule)}.token.keyword{color:var(--keyword)}.token.function{color:var(--function)}.token.important,.token.regex,.token.variable{color:var(--regex)}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}</code></pre>
</figure>
<figure>
<figcaption>JavaScript <small>[6.77 KB] (built at <a href="https://prismjs.com/">prismjs.com</a>)</small></figcaption>
<pre><code class=language-js contenteditable spellcheck=false>/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript */
var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-(\w+)\b/i,t=0,n=_self.Prism={manual:_self.Prism&&_self.Prism.manual,util:{encode:function(e){return e instanceof a?new a(e.type,n.util.encode(e.content),e.alias):"Array"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function(e){var t=n.util.type(e);switch(t){case"Object":var a={};for(var r in e)e.hasOwnProperty(r)&&(a[r]=n.util.clone(e[r]));return a;case"Array":return e.map&&e.map(function(e){return n.util.clone(e)})}return e}},languages:{extend:function(e,t){var a=n.util.clone(n.languages[e]);for(var r in t)a[r]=t[r];return a},insertBefore:function(e,t,a,r){r=r||n.languages;var i=r[e];if(2==arguments.length){a=arguments[1];for(var l in a)a.hasOwnProperty(l)&&(i[l]=a[l]);return i}var o={};for(var s in i)if(i.hasOwnProperty(s)){if(s==t)for(var l in a)a.hasOwnProperty(l)&&(o[l]=a[l]);o[s]=i[s]}return n.languages.DFS(n.languages,function(t,n){n===r[e]&&t!=e&&(this[t]=o)}),r[e]=o},DFS:function(e,t,a,r){r=r||{};for(var i in e)e.hasOwnProperty(i)&&(t.call(e,i,e[i],a||i),"Object"!==n.util.type(e[i])||r[n.util.objId(e[i])]?"Array"!==n.util.type(e[i])||r[n.util.objId(e[i])]||(r[n.util.objId(e[i])]=!0,n.languages.DFS(e[i],t,i,r)):(r[n.util.objId(e[i])]=!0,n.languages.DFS(e[i],t,null,r)))}},plugins:{},highlightAll:function(e,t){var a={callback:t,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};n.hooks.run("before-highlightall",a);for(var r,i=a.elements||document.querySelectorAll(a.selector),l=0;r=i[l++];)n.highlightElement(r,e===!0,a.callback)},highlightElement:function(t,a,r){for(var i,l,o=t;o&&!e.test(o.className);)o=o.parentNode;o&&(i=(o.className.match(e)||[,""])[1].toLowerCase(),l=n.languages[i]),t.className=t.className.replace(e,"").replace(/\s+/g," ")+" language-"+i,o=t.parentNode,/pre/i.test(o.nodeName)&&(o.className=o.className.replace(e,"").replace(/\s+/g," ")+" language-"+i);var s=t.textContent,u={element:t,language:i,grammar:l,code:s};if(n.hooks.run("before-sanity-check",u),!u.code||!u.grammar)return u.code&&(n.hooks.run("before-highlight",u),u.element.textContent=u.code,n.hooks.run("after-highlight",u)),n.hooks.run("complete",u),void 0;if(n.hooks.run("before-highlight",u),a&&_self.Worker){var g=new Worker(n.filename);g.onmessage=function(e){u.highlightedCode=e.data,n.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,r&&r.call(u.element),n.hooks.run("after-highlight",u),n.hooks.run("complete",u)},g.postMessage(JSON.stringify({language:u.language,code:u.code,immediateClose:!0}))}else u.highlightedCode=n.highlight(u.code,u.grammar,u.language),n.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,r&&r.call(t),n.hooks.run("after-highlight",u),n.hooks.run("complete",u)},highlight:function(e,t,r){var i=n.tokenize(e,t);return a.stringify(n.util.encode(i),r)},matchGrammar:function(e,t,a,r,i,l,o){var s=n.Token;for(var u in a)if(a.hasOwnProperty(u)&&a[u]){if(u==o)return;var g=a[u];g="Array"===n.util.type(g)?g:[g];for(var c=0;c<g.length;++c){var h=g[c],f=h.inside,d=!!h.lookbehind,m=!!h.greedy,p=0,y=h.alias;if(m&&!h.pattern.global){var v=h.pattern.toString().match(/[imuy]*$/)[0];h.pattern=RegExp(h.pattern.source,v+"g")}h=h.pattern||h;for(var b=r,k=i;b<t.length;k+=t[b].length,++b){var w=t[b];if(t.length>e.length)return;if(!(w instanceof s)){h.lastIndex=0;var _=h.exec(w),P=1;if(!_&&m&&b!=t.length-1){if(h.lastIndex=k,_=h.exec(e),!_)break;for(var A=_.index+(d?_[1].length:0),j=_.index+_[0].length,x=b,O=k,S=t.length;S>x&&(j>O||!t[x].type&&!t[x-1].greedy);++x)O+=t[x].length,A>=O&&(++b,k=O);if(t[b]instanceof s||t[x-1].greedy)continue;P=x-b,w=e.slice(k,O),_.index-=k}if(_){d&&(p=_[1].length);var A=_.index+p,_=_[0].slice(p),j=A+_.length,N=w.slice(0,A),C=w.slice(j),E=[b,P];N&&(++b,k+=N.length,E.push(N));var L=new s(u,f?n.tokenize(_,f):_,y,_,m);if(E.push(L),C&&E.push(C),Array.prototype.splice.apply(t,E),1!=P&&n.matchGrammar(e,t,a,b,k,!0,u),l)break}else if(l)break}}}}},tokenize:function(e,t){var a=[e],r=t.rest;if(r){for(var i in r)t[i]=r[i];delete t.rest}return n.matchGrammar(e,a,t,0,0,!1),a},hooks:{all:{},add:function(e,t){var a=n.hooks.all;a[e]=a[e]||[],a[e].push(t)},run:function(e,t){var a=n.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(t)}}},a=n.Token=function(e,t,n,a,r){this.type=e,this.content=t,this.alias=n,this.length=0|(a||"").length,this.greedy=!!r};if(a.stringify=function(e,t,r){if("string"==typeof e)return e;if("Array"===n.util.type(e))return e.map(function(n){return a.stringify(n,t,e)}).join("");var i={type:e.type,content:a.stringify(e.content,t,r),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===n.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}n.hooks.run("wrap",i);var o=Object.keys(i.attributes).map(function(e){return e+'="'+(i.attributes[e]||"").replace(/"/g,""")+'"'}).join(" ");return"<"+i.tag+' class="'+i.classes.join(" ")+'"'+(o?" "+o:"")+">"+i.content+"</"+i.tag+">"},!_self.document)return _self.addEventListener?(_self.addEventListener("message",function(e){var t=JSON.parse(e.data),a=t.language,r=t.code,i=t.immediateClose;_self.postMessage(n.highlight(r,n.languages[a],a)),i&&_self.close()},!1),_self.Prism):_self.Prism;var r=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return r&&(n.filename=r.src,!document.addEventListener||n.manual||r.hasAttribute("data-manual")||("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(n.highlightAll):window.setTimeout(n.highlightAll,16):document.addEventListener("DOMContentLoaded",n.highlightAll))),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
Prism.languages.markup={comment:/<!--[\s\S]*?-->/,prolog:/<\?[\s\S]+?\?>/,doctype:/<!DOCTYPE[\s\S]+?>/i,cdata:/<!\[CDATA\[[\s\S]*?]]>/i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\s\S])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:('|")[\s\S]*?(\1)|[^\s>]+)/i,inside:{punctuation:/[=>"']/}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Prism.languages.xml=Prism.languages.markup,Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup;
Prism.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*?(?=\s*\{)/,string:{pattern:/("|')(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.util.clone(Prism.languages.css),Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/(<style[\s\S]*?>)[\s\S]*?(?=<\/style>)/i,lookbehind:!0,inside:Prism.languages.css,alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag));
Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:{pattern:/(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/};
Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,"function":/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i,operator:/-[-=]?|\+[+=]?|!=?=?|<<?=?|>>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^\/])\/(?!\/)(\[[^\]\r\n]+]|\\.|[^\/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\\\|\\?[^\\])*?`/,greedy:!0,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/(<script[\s\S]*?>)[\s\S]*?(?=<\/script>)/i,lookbehind:!0,inside:Prism.languages.javascript,alias:"language-javascript"}}),Prism.languages.js=Prism.languages.javascript;</code></pre>
</figure>
<h2>References</h2>
<ul>
<li><a target=_blank title="[new window]" href="https://websemantics.uk/articles/displaying-code-in-web-pages/">Displaying code in a web pages</a></li>
<li><a target=_blank title="[new window]" href="https://hankchizljaw.com/wrote/create-a-user-controlled-dark-or-light-mode/">Create a user controlled dark or light mode</a></li>
<li><a target=_blank title="[new window]" href="https://codepen.io/2kool2/pen/abzgPzJ">Light & dark mode, with user switching button</a></li>
<li><a target=_blank title="[new window]" href="https://websemantics.uk/tools/svg-to-background-image-conversion/">SVG to CSS background-image converter</a></li>
<li><a target=_blank title="[new window]" href="https://websemantics.uk/tools/wcag-colour-contrast-checker/">WCAG colour contrast checker</a></li>
<li><a target=_blank title="[new window]" href="https://prismjs.com/">Prism syntax highlighting</a></li>
<li><a target=_blank title="[new window]" href="https://websemantics.uk/tools/escaping-html/">Escaping HTML symbols/entities</a></li>
<!--
<li><a target=_blank title="[new window]" href=""></a></li>
-->
</ul>
</body>
<style>
/* CSS included here to allow the main styles to be included into other CodePen projects */
*, *::after, *::before {
box-sizing: inherit;
}
body {
font-family: sans-serif;
font-size: 1rem;
text-rendering: optimizeLegibility;
margin: 1rem;
line-height: 1.5;
padding-bottom: 2rem;
background-attachment: fixed;
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.4'/%3E%3C/filter%3E%3C/defs%3E%3Crect filter='url(%23a)' opacity='.3' width='100%25' height='100%25'/%3E%3C/svg%3E");
}
h1 {
font-weight: 100;
margin-top: 2rem;
margin-bottom: 1rem;
text-align: center;
}
h1 + p {
font-size: 1.35rem;
font-weight: 100;
text-align: center;
}
h2 {
font-weight: 400;
margin-top: 3rem;
margin-bottom: 1rem;
text-align: center;
}
p, li {
font-size: 1.125rem;
}
ul, p {
max-width: 40rem;
margin: 1em auto;
}
li {
margin:.25rem 0;
}
figure {
margin: 2rem auto;
max-width: 40rem;
}
figure + figure {
margin-top: 3rem;
}
figcaption {
font-size: 1.25rem;
font-weight: 100;
}
a:link,
a:visited {
color: var(--linkColor);
text-decoration-color: var(--linkColorUnderline);
}
a:hover {
color: var(--linkColorHover);
}
a:focus {
color: var(--linkColorHover);
}
</style>
<style id=action_button_animations>
/* Buttons (or links) */
[class^="actions_btn"],
[class^="actions_btn"]:visited {
/* position: fixed;
top: .5rem;
right: .5rem; */
/* button colors light */
--btn-fg: #503660;
--btn-bg: #fafafd;
--btn-fg-hover: #418cec;
--btn-bg-hover: #fff;
box-sizing: content-box;
display: block;
width: 2.25rem;
height: 2.25rem;
padding: 0.25rem;
color: var(--btn-fg);
background-color: var(--btn-bg);
border: 0.125rem solid transparent;
border-radius: 50%;
box-shadow: 0 0.25em 0.25em rgba(0, 0, 0, 0.3);
text-decoration: none;
outline: 0 solid;
transition: all 0.3s ease-out;
}
[class^="actions_btn"]:hover,
[class^="actions_btn"]:focus {
color: var(--btn-fg-hover);
background-color: var(--btn-bg-hover);
border-color: var(--btn-fg-hover);
transform: scale(1.2);
box-shadow: 0 0.5em 0.5em rgba(0, 0, 0, 0.4);
}
[class^="actions_svg"] {
width: 2.25rem;
height: 2.25rem;
fill: currentColor;
stroke: currentColor;
border-radius: 100%;
overflow: hidden;
pointer-events: none;
transition: transform 0.5s ease-out;
}
/* Button click animation */
[class^="actions_btn"].-js-clicked {
animation: actions_btn-clicked 0.3s ease-out forwards;
}
@keyframes actions_btn-clicked {
0% {transform: scale(1.2);}
50% {transform: scale(0.8);}
100% {transform: scale(1.2);}
}
/* Remove all buttons from printouts */
@media print {
[class^="actions_container"] {
display: none !important;
}
}
</style>
<!-- Codepen footer include -->
[[[https://codepen.io/2kool2/pen/mKeeGM]]]
/* PrismJS - used for code highlighting */
[class*="language-"] ::selection {
color: #000;
background: hsl(214, 100%, 85%);
text-shadow: none;
}
pre[class*="language-"] {
overflow: auto;
margin: 0;
background-color: transparent;
/* Allow space for an overflow ellipsis */
padding-right: 0.5rem;
/* Allow space for SVG "tear off strip" */
background-origin: border-box;
border-left: 2.5rem solid transparent;
background-size: 120rem 4rem;
/* Single line does not sit on stripes */
background-position: top -1.2rem left 0;
/* Allow horizontal resizing - could be adjusted to allow vertical resizing too */
position: relative;
resize: horizontal;
min-width: calc(100% - 3rem);
transition: box-shadow .3s ease-out;
}
code[class*="language-"] {
font-family: monospace, monospace;
text-shadow: 0 1px var(--textShadow);
letter-spacing: 0.01em;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
/* Safari requirement for contenteditable */
word-wrap: normal;
line-height: 2;
tab-size: 2;
hyphens: none;
}
pre > code[class*="language-"],
pre[class*="language-"] > code {
display: block;
padding: 0.75rem 0;
/* Use an ellipsis to indicate code is wider than the display area */
text-overflow: ellipsis;
overflow-x: scroll;
}
pre:hover > code[class*="language-"],
pre:focus-within > code[class*="language-"] {
outline: none;
text-overflow: inherit;
}
/* Inline code only */
:not(pre) > code[class*="language-"] {
font-size: inherit;
background-position: top right;
background-size: auto 4rem;
padding: 0.125em 0.25em;
white-space: normal;
word-wrap: nowrap;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
.namespace {
opacity: 0.7;
}
/* Default colors (Light mode) */
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
--color: #33a;
--textShadow: #fff;
--comment: #6e6e6e;
--punctuation: #4e4e4e;
--property: #905;
--operator: #70b;
--selector: #487b00;
--url: #8d6640;
--urlBg: hsla(0, 0%, 100%, .5);
--boolean: #905;
--atrule: #0075a8;
--keyword: #0075a8;
--function: #c93654;
--regex: #860;
--boxShadow: hsla(0,0%,0%,.3);
--focusOutline: hsla(214, 100%, 85%, 1);
--codeBgImg: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1920 64'%3E%3Ccircle stroke='rgba(0,64,0,.3)' stroke-width='2' fill='none' cx='20' cy='49' r='12'/%3E%3Cpath fill='%23fcfcfa' fill-rule='evenodd' d='M1920 64H0V0h1920v64zM20 36a11 11 0 110 22 11 11 0 010-22z'/%3E%3Cpath stroke='%23edf3ed' stroke-width='2' d='M0 1h1920M0 5h1920M0 9h1920M0 13h1920M0 17h1920M0 21h1920M0 25h1920M0 29h1920'/%3E%3Cpath stroke='%23e4ede4' stroke-dasharray='2 6 2 6' stroke-width='2' d='M40 2v60'/%3E%3C/svg%3E");
}
/* If the OS has dark mode set then... */
/* Change dark to light to test */
@media (prefers-color-scheme: dark) {
body:not([data-lightMode="light"]) code[class*="language-"]:not([contenteditable]),
body:not([data-lightMode="light"]) pre[class*="language-"] {
--color: #6ae;
--textShadow: #000;
--comment: #9ab;
--punctuation: #ccc;
--property: #e70;
--operator: #d7f;
--selector: #8b2;
--url: #cde;
--urlBg: rgba(0,0,0,.5);
--boolean: #a8f;
--atrule: #ffb;
--keyword: #fe6;
--function: #f55;
--regex: #f91;
--boxShadow: #000;
--focusOutline: hsla(214, 100%, 85%, .6);
--codeBgImg: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1920 64'%3E%3Ccircle stroke='rgba(0,0,0,.7)' stroke-width='2' fill='none' cx='20' cy='49' r='12'/%3E%3Cpath fill='%23101610' fill-rule='evenodd' d='M1920 64H0V0h1920v64zM20 36a11 11 0 110 22 11 11 0 010-22z'/%3E%3Cpath stroke='%23121' stroke-width='2' d='M0 1h1920M0 5h1920M0 9h1920M0 13h1920M0 17h1920M0 21h1920M0 25h1920M0 29h1920'/%3E%3Cpath stroke='%23131' stroke-dasharray='2 6 2 6' stroke-width='2' d='M40 2v60'/%3E%3C/svg%3E");
}
}
/* Manual switch mode - where implemented */
body[data-lightMode="dark"] code[class*="language-"]:not([contenteditable]),
body[data-lightMode="dark"] pre[class*="language-"] {
/* Exactly the same as prefers-color-scheme: dark */
--color: #6ae;
--textShadow: #000;
--comment: #9ab;
--punctuation: #ccc;
--property: #e70;
--operator: #d7f;
--selector: #8b2;
--url: #cde;
--urlBg: rgba(0,0,0,.5);
--boolean: #8af;
--atrule: #ffb;
--keyword: #fe6;
--function: #f55;
--regex: #f91;
--boxShadow: #000;
--focusOutline: hsla(214, 100%, 85%, .6);
--codeBgImg: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1920 64'%3E%3Ccircle stroke='rgba(0,0,0,.7)' stroke-width='2' fill='none' cx='20' cy='49' r='12'/%3E%3Cpath fill='%23101610' fill-rule='evenodd' d='M1920 64H0V0h1920v64zM20 36a11 11 0 110 22 11 11 0 010-22z'/%3E%3Cpath stroke='%23121' stroke-width='2' d='M0 1h1920M0 5h1920M0 9h1920M0 13h1920M0 17h1920M0 21h1920M0 25h1920M0 29h1920'/%3E%3Cpath stroke='%23131' stroke-dasharray='2 6 2 6' stroke-width='2' d='M40 2v60'/%3E%3C/svg%3E");
}
code[class*="language-"],
pre[class*="language-"] {
color: var(--color);
text-shadow: 0 1px var(--textShadow);
}
/* Background image is applied to the pre element on blocks, mainly because it is cropped when applied to the code element. */
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background-image: var(--codeBgImg);
}
pre[class*="language-"]:hover,
pre[class*="language-"]:focus-within {
box-shadow: 0 .25rem .25rem var(--boxShadow);
}
pre[class*="language-"]:focus-within {
outline-offset: calc(-0.25rem - 1px);
outline: var(--focusOutline) solid 0.25rem;
z-index: 5;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: var(--comment);
}
.token.punctuation {
color: var(--punctuation);
}
.token.property,
.token.symbol,
.token.tag,
.token.constant,
.token.deleted {
color: var(--property);
}
.token.boolean,
.token.number {
color: var(--boolean);
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: var(--selector);
}
.token.operator {
color: var(--operator);
}
.token.url,
.token.entity,
.language-css .token.string,
.style .token.string {
color: var(--url);
background-color: var(--urlBg);
}
.token.atrule,
.token.attr-value {
color: var(--atrule);
}
.token.keyword {
color: var(--keyword);
}
.token.function {
color: var(--function);
}
.token.regex,
.token.important,
.token.variable {
color: var(--regex);
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
// Prism - used for code highlighting
// http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript
var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-(\w+)\b/i,t=0,n=_self.Prism={manual:_self.Prism&&_self.Prism.manual,util:{encode:function(e){return e instanceof a?new a(e.type,n.util.encode(e.content),e.alias):"Array"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function(e){var t=n.util.type(e);switch(t){case"Object":var a={};for(var r in e)e.hasOwnProperty(r)&&(a[r]=n.util.clone(e[r]));return a;case"Array":return e.map&&e.map(function(e){return n.util.clone(e)})}return e}},languages:{extend:function(e,t){var a=n.util.clone(n.languages[e]);for(var r in t)a[r]=t[r];return a},insertBefore:function(e,t,a,r){r=r||n.languages;var i=r[e];if(2==arguments.length){a=arguments[1];for(var l in a)a.hasOwnProperty(l)&&(i[l]=a[l]);return i}var o={};for(var s in i)if(i.hasOwnProperty(s)){if(s==t)for(var l in a)a.hasOwnProperty(l)&&(o[l]=a[l]);o[s]=i[s]}return n.languages.DFS(n.languages,function(t,n){n===r[e]&&t!=e&&(this[t]=o)}),r[e]=o},DFS:function(e,t,a,r){r=r||{};for(var i in e)e.hasOwnProperty(i)&&(t.call(e,i,e[i],a||i),"Object"!==n.util.type(e[i])||r[n.util.objId(e[i])]?"Array"!==n.util.type(e[i])||r[n.util.objId(e[i])]||(r[n.util.objId(e[i])]=!0,n.languages.DFS(e[i],t,i,r)):(r[n.util.objId(e[i])]=!0,n.languages.DFS(e[i],t,null,r)))}},plugins:{},highlightAll:function(e,t){var a={callback:t,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};n.hooks.run("before-highlightall",a);for(var r,i=a.elements||document.querySelectorAll(a.selector),l=0;r=i[l++];)n.highlightElement(r,e===!0,a.callback)},highlightElement:function(t,a,r){for(var i,l,o=t;o&&!e.test(o.className);)o=o.parentNode;o&&(i=(o.className.match(e)||[,""])[1].toLowerCase(),l=n.languages[i]),t.className=t.className.replace(e,"").replace(/\s+/g," ")+" language-"+i,o=t.parentNode,/pre/i.test(o.nodeName)&&(o.className=o.className.replace(e,"").replace(/\s+/g," ")+" language-"+i);var s=t.textContent,u={element:t,language:i,grammar:l,code:s};if(n.hooks.run("before-sanity-check",u),!u.code||!u.grammar)return u.code&&(n.hooks.run("before-highlight",u),u.element.textContent=u.code,n.hooks.run("after-highlight",u)),n.hooks.run("complete",u),void 0;if(n.hooks.run("before-highlight",u),a&&_self.Worker){var g=new Worker(n.filename);g.onmessage=function(e){u.highlightedCode=e.data,n.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,r&&r.call(u.element),n.hooks.run("after-highlight",u),n.hooks.run("complete",u)},g.postMessage(JSON.stringify({language:u.language,code:u.code,immediateClose:!0}))}else u.highlightedCode=n.highlight(u.code,u.grammar,u.language),n.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,r&&r.call(t),n.hooks.run("after-highlight",u),n.hooks.run("complete",u)},highlight:function(e,t,r){var i=n.tokenize(e,t);return a.stringify(n.util.encode(i),r)},matchGrammar:function(e,t,a,r,i,l,o){var s=n.Token;for(var u in a)if(a.hasOwnProperty(u)&&a[u]){if(u==o)return;var g=a[u];g="Array"===n.util.type(g)?g:[g];for(var c=0;c<g.length;++c){var h=g[c],f=h.inside,d=!!h.lookbehind,m=!!h.greedy,p=0,y=h.alias;if(m&&!h.pattern.global){var v=h.pattern.toString().match(/[imuy]*$/)[0];h.pattern=RegExp(h.pattern.source,v+"g")}h=h.pattern||h;for(var b=r,k=i;b<t.length;k+=t[b].length,++b){var w=t[b];if(t.length>e.length)return;if(!(w instanceof s)){h.lastIndex=0;var _=h.exec(w),P=1;if(!_&&m&&b!=t.length-1){if(h.lastIndex=k,_=h.exec(e),!_)break;for(var A=_.index+(d?_[1].length:0),j=_.index+_[0].length,x=b,O=k,S=t.length;S>x&&(j>O||!t[x].type&&!t[x-1].greedy);++x)O+=t[x].length,A>=O&&(++b,k=O);if(t[b]instanceof s||t[x-1].greedy)continue;P=x-b,w=e.slice(k,O),_.index-=k}if(_){d&&(p=_[1].length);var A=_.index+p,_=_[0].slice(p),j=A+_.length,N=w.slice(0,A),C=w.slice(j),E=[b,P];N&&(++b,k+=N.length,E.push(N));var L=new s(u,f?n.tokenize(_,f):_,y,_,m);if(E.push(L),C&&E.push(C),Array.prototype.splice.apply(t,E),1!=P&&n.matchGrammar(e,t,a,b,k,!0,u),l)break}else if(l)break}}}}},tokenize:function(e,t){var a=[e],r=t.rest;if(r){for(var i in r)t[i]=r[i];delete t.rest}return n.matchGrammar(e,a,t,0,0,!1),a},hooks:{all:{},add:function(e,t){var a=n.hooks.all;a[e]=a[e]||[],a[e].push(t)},run:function(e,t){var a=n.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(t)}}},a=n.Token=function(e,t,n,a,r){this.type=e,this.content=t,this.alias=n,this.length=0|(a||"").length,this.greedy=!!r};if(a.stringify=function(e,t,r){if("string"==typeof e)return e;if("Array"===n.util.type(e))return e.map(function(n){return a.stringify(n,t,e)}).join("");var i={type:e.type,content:a.stringify(e.content,t,r),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===n.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}n.hooks.run("wrap",i);var o=Object.keys(i.attributes).map(function(e){return e+'="'+(i.attributes[e]||"").replace(/"/g,""")+'"'}).join(" ");return"<"+i.tag+' class="'+i.classes.join(" ")+'"'+(o?" "+o:"")+">"+i.content+"</"+i.tag+">"},!_self.document)return _self.addEventListener?(_self.addEventListener("message",function(e){var t=JSON.parse(e.data),a=t.language,r=t.code,i=t.immediateClose;_self.postMessage(n.highlight(r,n.languages[a],a)),i&&_self.close()},!1),_self.Prism):_self.Prism;var r=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return r&&(n.filename=r.src,!document.addEventListener||n.manual||r.hasAttribute("data-manual")||("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(n.highlightAll):window.setTimeout(n.highlightAll,16):document.addEventListener("DOMContentLoaded",n.highlightAll))),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
Prism.languages.markup={comment:/<!--[\s\S]*?-->/,prolog:/<\?[\s\S]+?\?>/,doctype:/<!DOCTYPE[\s\S]+?>/i,cdata:/<!\[CDATA\[[\s\S]*?]]>/i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\s\S])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:('|")[\s\S]*?(\1)|[^\s>]+)/i,inside:{punctuation:/[=>"']/}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Prism.languages.xml=Prism.languages.markup,Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup;
Prism.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*?(?=\s*\{)/,string:{pattern:/("|')(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.util.clone(Prism.languages.css),Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/(<style[\s\S]*?>)[\s\S]*?(?=<\/style>)/i,lookbehind:!0,inside:Prism.languages.css,alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag));
Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:{pattern:/(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/};
Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,"function":/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i,operator:/-[-=]?|\+[+=]?|!=?=?|<<?=?|>>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^\/])\/(?!\/)(\[[^\]\r\n]+]|\\.|[^\/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\\\|\\?[^\\])*?`/,greedy:!0,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/(<script[\s\S]*?>)[\s\S]*?(?=<\/script>)/i,lookbehind:!0,inside:Prism.languages.javascript,alias:"language-javascript"}}),Prism.languages.js=Prism.languages.javascript;
Also see: Tab Triggers