Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

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.

+ add another resource

JavaScript

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

Packages

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.

Behavior

Auto Save

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.

HTML

              
                <p>Too lazy to copy and paste the JS? I got you. run <a href="https://www.npmjs.com/package/@lrnwebcomponents/moar-sarcasm" target="_blank">npm install @lrnwebcomponents/moar-sarcasm</a> then.</p>
<p>Look, I know what your thinking. You're thinking <moar-sarcasm>HTML is so easy</moar-sarcasm> right?</p>
          <p>Or maybe your sick of those web component zombies and their <moar-sarcasm>Just use the platform</moar-sarcasm> memes.</p>
          <p>Well now, we the keepers of the internet are here to remind you that <moar-sarcasm>Web components always have dependencies</moar-sarcasm>. All of them without exception. The best way to stick it to those web component noobs is to add <moar-sarcasm> moar sarcasm</moar-sarcasm> to your next app. That'll show em. <moar-sarcasm>Take that you web components losers!</moar-sarcasm></p>
              
            
!

CSS

              
                moar-sarcasm {
  font-weight: bold;
}
p {
  font-size: 28px;
}
              
            
!

JS

              
                /**
 * Copyright 2020 The Pennsylvania State University
 * @license Apache-2.0, see License.md for full text.
 */

/**
 * `moar-sarcasm`
 * `Provide a laugh and a good example of VanillaJS for demos`
 * @demo demo/index.html
 * @element moar-sarcasm
 */
class MoarSarcasm extends HTMLElement {
  /**
   * This is a convention, not the standard
   */
  static get tag() {
    return "moar-sarcasm";
  }
  /**
   * object life cycle
   */
  constructor() {
    super();
    this.a11y = "the following is sarcastic ";
    // create a template element for processing shadowRoot
    this.template = document.createElement("template");
    // create a shadowRoot
    this.attachShadow({ mode: "open" });
    this.render();
    this.observer = new MutationObserver(mutations => {
      mutations.forEach(mutation => {
        this.say = this.innerText;
      });
    });
    this.observer.observe(this, {
      characterData: true,
      attributes: false,
      childList: false,
      subtree: true
    });
  }
  // render HTML
  get html() {
    return `
      <style>
        :host {
          display: inline-block;
        }
        span {
          font-style: italic;
        }
        .letter:nth-child(odd) {
          text-transform: uppercase;
        }
        .letter:nth-child(even) {
          text-transform: lowercase;
        }
        .slot {
          position: absolute!important;
          width: 1px!important;
          height: 1px!important;
          padding: 0!important;
          margin: -1px!important;
          overflow: hidden!important;
          clip: rect(0,0,0,0)!important;
          white-space: nowrap!important;
          border: 0!important;
        }
      </style>
      <span class="sarcastic" aria-hidden="true"></span>
      <span class="slot">${this.a11y}<slot></slot></span>
    `;
  }
  /**
   * life cycle, element is afixed to the DOM
   */
  connectedCallback() {
    if (window.ShadyCSS) {
      window.ShadyCSS.styleElement(this);
    }
    this.say = this.innerText;
  }
  /**
   * Render / rerender the shadowRoot
   */
  render() {
    this.shadowRoot.innerHTML = null;
    this.template.innerHTML = this.html;

    if (window.ShadyCSS) {
      window.ShadyCSS.prepareTemplate(this.template, this.tag);
    }
    this.shadowRoot.appendChild(this.template.content.cloneNode(true));
  }
  /**
   * Process the text in question
   */
  processText(text) {
    // empty whats there
    this.shadowRoot.querySelector(".sarcastic").innerHTML = "";
    // loop through text to process and convert to span tags
    for (var i = 0; i < text.length; i++) {
      let tag = document.createElement("span");
      if (text.charAt(i).match(/[a-z]/i)) {
        tag.classList.add("letter");
        tag.innerText = text.charAt(i);
      } else {
        tag = document.createTextNode(text.charAt(i));
      }
      this.shadowRoot.querySelector(".sarcastic").appendChild(tag);
    }
  }
  /**
   * attributes to notice changes to
   */
  static get observedAttributes() {
    return ["say", "a11y"];
  }
  set say(val) {
    this.setAttribute("say", val);
  }
  set a11y(val) {
    this.setAttribute("a11y", val);
  }
  get say() {
    return this.getAttribute("say");
  }
  get a11y() {
    return this.getAttribute("a11y");
  }
  /**
   * callback when any observed attribute changes
   */
  attributeChangedCallback(attr, oldValue, newValue) {
    if (newValue) {
      switch (attr) {
        case "say":
          this.processText(newValue);
          break;
        case "a11y":
          this.render();
          break;
      }
    }
  }
}
customElements.define(MoarSarcasm.tag, MoarSarcasm);
              
            
!
999px

Console