The best way I learn code is by trying it out for myself, which often means I'm reaching for my favourite online live code editor CodePen. Wouldn't be cool if you could wrap code blocks in a single Web Component which then allows people to open that code block in the CodePen editor? Well now you can.
code-pen
The <code-pen> component when wrapped around a <code> element will append a button which once clicked will open CodePen and pre-fill the editor with the code contained within the original <code> element.

Features
This Web Component allows you to:
- Open
codesamples in the CodePen editor without any configuration- Open a single HTML
codesample - Open a pair of HTML and CSS
codesamples, in respective order - Open a trio of HTML, CSS and JavaScript
codesamples, in respective order
- Open a single HTML
- Adjust where the code sample is filled into in CodePen using the
cssandjsattributes (htmlis the default) - Adjust which elements are used as the code sample source by using the
html,cssandjsattributes and an element selector as its value (e.g.css="textarea") - Add a title to the pre-filled pen using the
titleattribute - Change the "Open in CodePen" button text label using the
labelattribute - Allow readers to edit the code before opening in CodePen using
contenteditableon the code container - Use a custom template for specific instances using the template attribute
Usage
The <code-pen> component can be used with the help of a script tag and wrapping it around a block of HTML containing a code element:
<script type="module" src="code-pen.js"></script>
<code-pen>
<pre>
<code><p>Hello world</p></code>
</pre>
</code-pen>A reduced example of using code-pen in regular HTML
Note that for the purposes of presenting the HTML code sample accurately the above code sample within the example above has been escaped.
You can also wrap multiple elements with the <code-pen> component which will result in each sample being pre-filled into the HTML, CSS and JavaScript respectively.
<script type="module" src="code-pen.js"></script>
<code-pen>
<pre>
<code><p>Hello world</p></code>
</pre>
<pre>
<code>:root { color: hotpink; }</code>
</pre>
<pre>
<code>document.querySelector("p").style.backgroundColor = "orange";</code>
</pre>
</code-pen>An example of using 3 code blocks to fill the HTML, CSS and JavaScript editors in CodePen
Using attributes
By default the <code-pen> component will assume the first code element it finds goes into the HTML editor in CodePen, the second goes into the CSS editor, and JavaScript into the third. If there is only one or two code elements it'll still follow this order and leave the missing ones blank in CodePen. However with attributes the order can be modified and changed.
Applying the css or js attributes will cause a single code elements content to be insered into the CSS or JavaScript editors in CodePen respectively:
<script type="module" src="code-pen.js"></script>
<code-pen css>
<pre>
<code>:root { background: hotpink; }</code>
</pre>
</code-pen>An example of using the css attribute to fill the code sample into the CSS editor in CodePen
You can also overwrite the element selection entirely using the html, css and js attributues to set an element selector for each piece of code. This is useful for cases where your code is out of order, you have extra rogue elements in your content or if you wish to use a different element entirely.
<script type="module" src="code-pen.js"></script>
<code-pen html=".language-html" css=".language-css" js=".language-js">
<pre>
<code>I'm a rogue code block to ruin this Web Component demo</code>
</pre>
<pre>
<code class="language-js">document.querySelector("p").style.backgroundColor = "orange";</code>
</pre>
<pre>
<code class="language-html"><p>Hello world</p></code>
</pre>
<pre>
<code class="language-css">:root { color: hotpink; }</code>
</pre>
</code-pen>Complex example of using the html, css and js attributes to target specific elements
Note in this example that not only is there a rogue code element at the beginning but also that the actual code examples are in a different order. Having this fine grain control is great for these unique circumstances.
<script type="module" src="code-pen.js"></script>
<code-pen css="textarea">
<textarea>:root { background: hotpink; }</textarea>
</code-pen>More simple example where a textarea element is being used and css="textarea" attribute is applied to adjust accordingly
If configured correctly you can use the <code-pen> Web Component in Markdown like so:
<code-pen>
```
<p>Hello world</p>
```
</code-pen><code-pen> component used with a Markdown code block
Labelling
For additional fine tuning you can control the label text within the "Open in CodePen" button using the label attribute, as well as the title that appears when CodePen is opened using the title attribute.
<script type="module" src="code-pen.js"></script>
<code-pen title="Hello world example" label="Create new pen">
<pre>
<code><p>Hello world</p></code>
</pre>
</code-pen>Custom button label and CodePen title example
Demos
I've listed all the current running demos below if you want to see them in action:
- Default usage, with single and multiple
codeelements - Attribute usage, overwriting defaults and customisations
Editable code
The component also works if you want readers to be able to edit the code before opening it in CodePen. Either use a textarea or input element to contain the code samples or add a contenteditable="true" attribute to the immediate containing element:
<script type="module" src="code-pen.js"></script>
<code-pen>
<pre>
<code contenteditable="true"><p>Hello world</p></code>
</pre>
</code-pen>Further reading
If you'd like to try the Web Component for yourself or learn more about templating you can check out the documentation and further examples on GitHub:

Credit
Thank you to Simon MacDonald, Apple Annie, Raymond Camden and Ryan Mulligan for testing out this Web Component before release.
