Pen Settings



CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource


Babel includes JSX processing.

Add External Scripts/Pens

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.

+ add another resource


Add Packages

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.


Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.


    <h1>Cistercian Numerals</h1>
    <label for="Number">Enter 1&ndash;9999:</label>
    <input type="number" max="9999" min="0" step="1" maxlength="4" id="Number" value="1984" onchange="updateGlyph(this.value,'CistercianGlyph');">
    <button type="button" onclick="updateGlyph(document.getElementById('Number').value,'CistercianGlyph');">Apply</button>
    <button type="button" onclick="countDown(document.getElementById('Number').value,'CistercianGlyph');">Countdown</button>

    <svg xmlns="" viewBox="0 0 39.5 58.8" role="img" focusable="false" aria-labelledby="CistercianNumber" aria-describedby="CistercianDesc" id="CistercianGlyph" class="z1000 z900 z80 z4">
     <title id="CistercianNumber">1984</title>
     <desc id="CistercianDesc">A number as represented in Cistercian glyph</desc>
       .z1 .c1, .z2 .c2, .z3 .c3, .z4 .c4, .z5 .c5, .z6 .c6, .z7 .c7, .z8 .c8, .z9 .c9, .z10 .t1, .z20 .t2, .z30 .t3, .z40 .t4, .z50 .t5, .z60 .t6, .z70 .t7, .z80 .t8, .z90 .t9, .z100 .h1, .z200 .h2, .z300 .h3, .z400 .h4, .z500 .h5, .z600 .h6, .z700 .h7, .z800 .h8, .z900 .h9, .z1000 .d1, .z2000 .d2, .z3000 .d3, .z4000 .d4, .z5000 .d5, .z6000 .d6, .z7000 .d7, .z8000 .d8, .z9000 .d9 {
         stroke: currentColor;
     <path stroke="currentColor" d="M19.8 1v56.8"></path>
     <g id="Zeds">
      <path class="c1 c5 c7 c9" d="M38.5 1H19.8"></path>
      <path class="c2 c8 c9" d="M19.8 20.4h18.7"></path>
      <path class="c3" d="M19.8 1l18.7 19.4"></path>
      <path class="c4 c5" d="M19.8 20.4L38.5 1"></path>
      <path class="c6 c7 c8 c9" d="M38.5 20.4V1"></path>
     <g id="Tens">
      <path class="t1 t5 t7 t9" d="M19.8 1H1"></path>
      <path class="t2 t8 t9" d="M1 20.4h18.8"></path>
      <path class="t3" d="M19.8 1L1 20.4"></path>
      <path class="t4 t5" d="M19.8 20.4L1 1"></path>
      <path class="t6 t7 t8 t9" d="M1 1v19.4"></path>
     <g id="Hundreds">
      <path class="h1 h5 h7 h9" d="M19.8 57.8h18.7"></path>
      <path class="h2 h8 h9" d="M38.5 38.4H19.8"></path>
      <path class="h3" d="M19.8 57.8l18.7-19.4"></path>
      <path class="h4 h5" d="M19.8 38.4l18.7 19.4"></path>
      <path class="h6 h7 h8 h9" d="M38.5 57.8V38.4"></path>
     <g id="Thousands">
      <path class="d1 d5 d7 d9" d="M1 57.8h18.8"></path>
      <path class="d2 d8 d9" d="M19.8 38.4H1"></path>
      <path class="d3" d="M19.8 57.8L1 38.4"></path>
      <path class="d4 d5" d="M19.8 38.4L1 57.8"></path>
      <path class="d6 d7 d8 d9" d="M1 38.4v19.4"></path>


  <li>All shapes are in the SVG.</li>
  <li>Uses classes to selectively apply stroke colors.</li>
  <li>Sets the SVG as an image with <code>role="img"</code>.</li>
  <li>Uses <code>&lt;title&gt;</code> with <code>aria-labelledby</code> to provide an accessible name.</li>
  <li>The <code>&lt;title&gt;</code> acts as a tool-tip in many browsers, whether or not I want it to.</li>
  <li>Uses <code>&lt;desc&gt;</code> with <code>aria-describedby</code> to provide an accessible description.</li>
  <li>Works in Windows High Contrast Mode.</li>
  <li>Uses <code>focusable="false"</code> to prevent IE tab stops.</li>
  <li>1 request, 7.8kb, 804 bytes from script.</li>
  <li>You can save the SVG for your own use and adjust the classes to make any number in the range that you want.</li>
  <li>I wrote a post with some background: <a href=""><cite>Cistercian SVG</cite></a></li>


  <li><a href="">Cistercian numerals</a> at Wikipedia.</li>
  <li>The <a href="">tweet from UCL Department of Mathematics</a>.</li>
  <li><a href="">Clairvo</a>, a proof of concept OpenType font.</li>
  <li>A <a href="">React-driven app</a> mutating an SVG (5 HTTP requests, 68kb, ~57kb from React).</li>
  <li>Another <a href="">React-driven SVG-morphing</a> effort at Codepen (7 HTTP requests, 89kb, ~40kb from React, ~40 from fonts).</li>


                body {
  font-family: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto,
    Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
  line-height: 1.4;

h1 {
  line-height: 1;
  margin: 0 0 1em 0;

body > div {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  margin: 2em 0 0 0;
  max-width: 50em;

body > div > div {
  flex: 0 1 15em;
  margin: 0 0 2em 0;

body > div > div:first-child {
  padding: .5em 1em;
  border: .3em double currentColor;

label, button {
  display: block;
  margin: .25em 0;

input {
  font: inherit;
  letter-spacing: inherit;
  word-spacing: inherit;

button {
  margin: .5em 0 1.5em 0;

input {
  width: 4em;

#CistercianGlyph {
  width: 15em;


                function updateGlyph(strNum,svgID) {
  var theSVG = document.getElementById(svgID);
  intNum = Number(strNum);
  document.querySelector("#" + svgID + " title").innerHTML = intNum;
  theSVG.setAttribute("class", "");
  const x = strNum.padStart(4,"0");
  theSVG.classList.add("z" + x.split("")[0] + "000");
  theSVG.classList.add("z" + x.split("")[1] + "00");
  theSVG.classList.add("z" + x.split("")[2] + "0");
  theSVG.classList.add("z" + x.split("")[3]);

async function countDown(strNum,svgID) {
  intNum = Number(strNum);
  for (let i = intNum; i > 0; i--) {
    const x = i.toString();
    document.getElementById('Number').value = x;
    await sleep(1000);

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));