123

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

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

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

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

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.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
              <script>console.clear();</script>
<h1>Test</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent bibendum, lorem vel tincidunt imperdiet, nibh elit laoreet felis, a bibendum nisl tortor non orci. Donec pretium fermentum felis, quis aliquet est rutrum ut. Integer quis massa ut lacus viverra pharetra in eu lacus. Aliquam tempus odio adipiscing diam pellentesque rhoncus. Curabitur a bibendum est. Mauris vehicula cursus risus id luctus. Curabitur accumsan venenatis nibh, non egestas ipsum vulputate ac. Vivamus consectetur dolor sit amet enim aliquet eu scelerisque ipsum hendrerit. Donec lobortis suscipit vestibulum. Nullam luctus pellentesque risus in ullamcorper. Nam neque nunc, mattis vitae ornare ut, feugiat a erat. Ut tempus iaculis augue vel pellentesque.</p>

<p id="para-2">Vestibulum nunc massa, gravida quis porta nec, feugiat id metus. Nunc ac arcu dolor, quis vestibulum leo. Cras viverra mollis ipsum, non rhoncus lectus aliquam et. Morbi faucibus purus sit amet lacus aliquet elementum. Donec sit amet posuere enim. Cras in eros id tortor fringilla ultricies. Mauris faucibus ullamcorper velit, pulvinar varius odio eleifend eu. Quisque id odio metus. Morbi adipiscing ultricies posuere. Pellentesque elementum porttitor eros in molestie. Maecenas ut leo quis nisi tempor tincidunt.</p>

<p>Donec nunc ligula, vulputate quis mollis eu, interdum quis libero. Donec nulla ante, facilisis sit amet vulputate at, tincidunt a velit. Maecenas vestibulum, nulla sed tincidunt viverra, lorem turpis aliquam urna, ut pretium orci purus consequat augue. Etiam a enim orci, vitae pulvinar odio. In elit urna, tincidunt a pellentesque et, scelerisque at nibh. Sed nec est sapien. Aliquam ullamcorper eros eu quam ultrices vel faucibus eros interdum. Etiam mattis eleifend sapien, eu iaculis massa feugiat sed. Aliquam erat volutpat. Vivamus facilisis ultricies eros, a pretium purus mollis id. Sed dapibus elit ut neque rutrum dignissim. Nulla eros nisl, venenatis quis rhoncus sit amet, molestie nec nisl. Pellentesque vel neque sapien, et sagittis nulla.</p>

<p>Aliquam eu iaculis mauris. Etiam arcu lectus, imperdiet sit amet volutpat vitae, commodo sed nibh. Fusce faucibus tempor cursus. Donec ut ligula tortor. Maecenas malesuada, diam vitae pharetra dictum, erat ante iaculis risus, sed sollicitudin nisl nisl vel metus. Nulla libero augue, convallis nec luctus id, iaculis nec urna. Cras vitae mi ut augue ultricies tempus.</p>

<p>Vestibulum euismod vehicula sollicitudin. Duis nibh justo, rhoncus ac ullamcorper nec, rutrum sit amet leo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum varius posuere nisi sed aliquet. Etiam dolor nisi, placerat vel congue tempus, posuere sed erat. Phasellus turpis eros, molestie sed consequat in, pretium at erat. In sed faucibus metus. Vestibulum fermentum libero nec eros fermentum dapibus. Duis nec libero eros. Pellentesque magna ligula, sagittis dictum fringilla at, posuere porttitor sem. Donec aliquam, ipsum quis pulvinar dapibus, augue sem viverra sapien, nec tempus odio nulla ac metus. Nunc ut augue mi, nec consequat urna.</p>
            
          
!
            
              .test { font-style: italic; }

.strange { color: #900; }

img { max-width: 100%; height: auto; }
body { padding: 1em; }
            
          
!
            
              (function(win,doc){
  'use strict';

  var arr = Array.prototype,
      strType = typeof '',
      fnType = typeof function(){},
      idOrHTML = /^\s*?(#([-\w]*)|<[\w\W]*>)\s*?$/,
      half$,
      _$ = win.$;

  var $ = half$ = function(selector, context) {
    return new $.fn.init(selector, context);
  }

  var fn = $.fn = $.prototype = {
    half$: true,
    constructor: $,
    length: 0,

    toArray: function() { return arr.slice.call(this); },

    get: function(index) {
      if ( index === undefined ) { return this.slice(); }
      return ( index < 0 ? this[index + this.length] : this[index] ) || false;
    },
    eq: function(index) { return $(this.get(index)); },
    first: function(){ return this.eq(0); },
    last: function(){ return this.eq(-1); },

    concat: function(){
      $.each(arguments,function(i,el){
        if ( $.isArray(el) ) {
          this.concat.apply(this,el);
        } else {
          this.push(el);
        }
      }.bind(this));
      return this;
    }
  };

  function onReady(fn) {
    if ( doc.readyState !== 'loading' ) { fn(); }
    else { doc.addEventListener('DOMContentLoaded', fn); }
  }

  fn.init = function(selector, context) {

    if ( !selector ) { return this; }
    // If already $, don't process further.
    if ( $.is$(selector) ) { return selector; }
    // If function, use as shortcut for DOM ready
    else if ( $.isFunction(selector) ) { onReady(selector); return this; }

    context = context || doc;

    var i = 0,
        elems, length, match;

    if ( $.isString(selector) ) {
      // Check if the selector string is an ID or HTML
      match = idOrHTML.exec(selector);
      // If an ID use the faster getElementById check
      if ( match && match[2]  ) { elems = [document.getElementById(match[2])]; }
      // If HTML, parse it into real elements, else use querySelectorAll
      else { elems = ( match ? $.parseHTML(selector) : context.querySelectorAll(selector) ); }
    } else {
      elems = ( selector.nodeType || selector === win ? [selector] : selector );
    }

    length = this.length = ( elems.length ? elems.length : 0 );

    for ( ; i < length; i++ ) { this[i] = elems[i]; }
    return this;
  }

  fn.init.prototype = fn;

  $.extend = fn.extend = function() {
    var target = arguments[0],
        length = arguments.length,
        i = 1;

    if ( length === 1 ) {
      target = this;
      i = 0;
    }

    for (; i < length; i++) {
      if (!arguments[i]) { continue; }
      for (var key in arguments[i]) {
        if ( arguments[i].hasOwnProperty(key) ) { target[key] = arguments[i][key]; }
      }
    }

    return target;
  }

  $.extend({
    type: function(obj) { return typeof obj; },
    is$: function(obj){ return obj instanceof $; },
    isHalf$: function(obj){ return obj.half$ ? true : false; },
    isArray: Array.isArray,
    isString: function(obj) { return typeof obj === strType; },
    isFunction: function(obj) { return typeof obj === fnType; },
    isNumeric: function(n) { return !isNaN(parseFloat(n)) && isFinite(n); },
    noop: function(){},
    now: Date.now,
    parseHTML: function(str) {
      var tmp = document.implementation.createHTMLDocument();
      tmp.body.innerHTML = str;
      return arr.slice.call(tmp.body.children);
    }
  });

  $.each = fn.each = function(obj,callback){
    if ( arguments.length === 1) {
      callback = arguments[0];
      obj = this;
    }

    var length = obj.length,
        likeArray = (length === 0 || ( length > 0 && (length - 1) in obj )),
        i = 0;

    if ( likeArray ) {
      for ( ; i < length; i++ ) {
        if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; }
      }
    } else {
      for (i in obj) {
        if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; }
      }
    }

    return obj;
  };

  // Inherit all Array prototype functions
  $.each(Object.getOwnPropertyNames(arr),function(i,key){
    if ( key !== 'constructor' && !$.fn[key] ) { 
      $.fn[key] = function(){ 
        var results = arr[key].apply(this,arguments);
        // If function doesn't return results, keep the function chainable (forEach)
        // If function returns an array, make it a $ object (filter, slice, concat)
        // Otherwise just return the results (indexOf, every, some, join)
        return ( results === undefined ? this : $.isArray(results) ? $(results) : results );
      }
    }
  });
  
  
  
  // noConflict to remove half$ if the original $ is needed;
  $.noConflict = function(){
    if ( win.$ === half$ ) { win.$ = _$; }
    return half$;
  };
  
  // Set half$ up in the global space to be used by other scripts
  win.$ = win.half$ = $;

}(window,document));

(function($){


  ////////////////////////////////////////
  // Classes

  function modifyClass(act,obj,c) {
    if ( !c ) { return obj; }
    var classes = c.split(' ');
    $.each(classes,function(i,c){
      obj.each(function(){
        if ( this.classList ) { this.classList[act](c); }
        else if ( act === 'add' ) { this.className += ' ' + c; }
        else if ( act === 'remove') { this.className = this.className.replace(c,''); }
      });
    });
    return obj;
  }

  $.fn.extend({
    addClass: function(c){ return modifyClass('add',this,c); },
    removeClass: function(c){ return modifyClass('remove',this,c); },
    toggleClass: function(c, state){
      if ( state !== undefined ) { return modifyClass(state ? 'add' : 'remove' ,this,c); }
      return this.each(function(){
        if ( this.classList && this.classList.toggle ) { this.classList.toggle(c); }
        else { modifyClass(this.className.indexOf(c) >= 0 ? 'remove' : 'add',this,c); }
      });
    },
    hasClass: function(c){
      var check = false;
      if ( !c ) { return check; }
      this.each(function(){
        check = ( this.classList ? this.classList.contains(c) : new RegExp('(^|\s)' + c + '(\s|$)', 'gi').test(this.className) );
        return !check; // We only need one to be true, so break the loop if true.
      });
      return check;
    }
  });



  ////////////////////////////////////////
  // Attributes

  $.fn.extend({

    attr: function(attrName, value){
      if ( $.isString(attrName) ) {
        if ( arguments.length === 1 ) { return this[0].getAttribute(attrName); }
        else if ( value === undefined ) { return this; }
        this.each(function(){ this.setAttribute(attrName,value); });
      } else {
        $.each(attrName,function(attr,val){
          this.each(function(){ this.setAttribute(attr,val); })
        }.bind(this));
      }
      return this;
    },
    removeAttr: function(attrName){
      return this.each(function(){ this.removeAttribute(attrName); });
    },
    data: function(){
      arguments[0] = 'data-' + arguments[0];
      return this.attr.apply(this,arguments); //this.attr('data-'+key,value);
    },
    removeData: function(d){ return this.removeAttr('data-' + d); },
    prop: function(propName, value){
      if ( arguments.length === 1 ) { return this[0][propName]; }
      return this.each(function(){ this[propName] = value; });
    },
    removeProp: function(propName) {
      return this.each(function(){ delete this[propName]; });
    },
    val: function(){
      var ar = slice.call(arguments);
      ar.unshift('value');
      return this.prop.apply(this,ar);
    }

  });


  ////////////////////////////////////////
  // Inner Content Manipulation

  $.fn.extend({
    html: function(content){
      if ( arguments.length === 0 ) { return this[0].innerHTML; }
      return this.each(function(){ this.innerHTML = content; });
    },
    text: function(content){
      if ( arguments.length === 0 ) { return this[0].textContent; }
      return this.each(function(){ this.textContent = content; });
    },
    empty: function(){ return this.html(''); }
  });



  ////////////////////////////////////////
  // DOM manipulation

  var methods = {
    'prepend': {
      insert: 'afterbegin',
      dom: function(el,child){
        var first = el.childNodes[0];
        el.insertBefore(child,first);
      }
    },
    'append': {
      insert: 'beforeend',
      dom: function(el,child){ el.appendChild(child); }
    }
  };

  function insertContent(method,el,child){
    if ( $.isString(child) ) {
      $.each(el,function(){
        this.insertAdjacentHTML(methods[method].insert,child);
      });
    } else if ( child.nodeType ) {
      if ( el.length ) {
        $.each(el,function(i,elem){
          methods[method].dom(elem,( i === 0 ? child : child.cloneNode(true) ));
        });
      } else {
        methods[method].dom(el,child);
      }
    } else if ( child.length ) {
      $.each(child,function(i,c){ insertContent(method,el,c); });
    }
  }

  $.fn.extend({
    append: function(){ insertContent('append',this,arguments); return this; },
    prepend: function(){ insertContent('prepend',this,arguments); return this; },
    appendTo: function(el){ insertContent('append',el,this); return this; },
    prependTo: function(el){ insertContent('prepend',el,this); return this; },
    remove: function(){ return this.each(function(i,el){ if ( el.remove) { el.remove(); } }); }
  });


  function matches(el, selector) {
    return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector);
  }

  var slice = Array.prototype.slice;

  function find(selector,context) {
    context = context || document;
    var elems = context.querySelectorAll(selector);
    return slice.call(elems);
  }

  $.fn.extend({

    is: function(selector){
      var match = false,
          isStr;
      if ( !selector ) { return match; }
      isStr = $.isString(selector);
      this.each(function(){
        match = ( isStr ? matches(this,selector) : ( this === selector ) );
        return !match;
      });
      return match;
    },

    // Find decendents by selector
    find: function(selector){
      var $elems = $();
      if ( !selector ) { return $elems; }

      this.each(function(){
        $elems = $elems.concat(find(selector,this));
      });

      return $elems;
    },

    // Filter only elements that match selector
    filter: function(selector){
      var $elems = $();
      if ( !selector ) { return $elems; }

      this.each(function(){
        if ( selector && !matches(this,selector) ) { return true; }
        $elems.push(this);
      });

      return $elems;
    },

    // Get children, optionally filtered by selector
    children: function(selector){
      var $elems = $();

      this.each(function(){
        $.each(this.children,function(){
          if ( selector && !matches(this,selector) ) { return true; }
          $elems.push(this);
        });
      });

      return $elems;
    },

    // Get parent, optionally filtered by selector
    parent: function(selector){
      var $elems = $();

      this.each(function(){
        var parent = this.parentNode;
        if ( selector && !matches(parent,selector) ) { return true; }
        $elems.push(parent);
      });

      return $elems;
    }

  });

  ////////////////////////////////////////
  // CSS



  var getPrefixedProp = (function() {
    var cache = {},
        div = document.createElement('div'),
        style = div.style;

    var camelRegex = /(?:^\w|[A-Z]|\b\w|\s+)/g,
        nonAlpha = /[^a-z\ ]/ig;

    function camelCase(str) {
      return str.replace(nonAlpha,' ').replace(camelRegex, function(match, index) {
        if ( +match === 0 ) { return ''; } // or if (/\s+/.test(match)) for white spaces
        return ( index === 0 ? match.toLowerCase() : match.toUpperCase() );
      });
    }

    return function(prop) {
      prop = camelCase(prop);
      if ( cache[prop] !== undefined ) { return cache[prop]; }

      var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
          prefixes = ["webkit", "moz", "ms"],
          props = (prop + ' ' + (prefixes).join(ucProp + ' ') + ucProp).split(' '),
          i = props.length;

      while (i--) {
        if ( props[i] in style ) {
          cache[prop] = props[i];
          return props[i];
        }
      }

      return prop;
    };
  }());

  $.fn.extend({

    css: function(ruleName,value){

      var isString = $.isString(ruleName);
      if ( isString ) { ruleName = getPrefixedProp(ruleName); }

      if ( arguments.length === 1 ) {
        if ( isString ) {
          return getComputedStyle(this[0])[ruleName];
        } else {
          $.each(ruleName,function(key,val){ this.css(key,val); }.bind(this));
          return this;
        }
      }

      return this.each(function(){ this.style[ruleName] = value; });
    }

  });

  ////////////////////////////////////////
  // Events

  $.fn.extend({

    on: function(event,callback){
      return this.each(function(){
        this.addEventListener(event,callback);
      });
    },

    off: function(event,callback){
      return this.each(function(){
        this.removeEventListener(event,callback);
      });
    },

    one: function(event,callback){
      return this.each(function(){
        var fn = function(){
          callback.apply(this, arguments);
          this.removeEventListener(event,fn);
        };
        this.addEventListener(event,fn);
      });
    }

  });


  ////////////////////////////////////////
  // Clone

  $.fn.extend({
    clone: function(){
      var $elems = $();
      this.each(function(){
        $elems.push(this.cloneNode(true));
      });
      return $elems;
    }
  });////////////////////////////////////////
// Get Width / Height


  $.fn.extend({

    height: function(){ return this[0].clientHeight; },
    outerHeight: function(){ return this[0].offsetHeight; },

    width: function(){ return this[0].clientWidth; },
    outerWidth: function(){ return this[0].offsetWidth; }

  });

////////////////////////////////////////
// Offset & Position

  $.fn.extend({

    position: function(){
      var el = this[0];
      return {
        top: el.offsetTop,
        left: el.offsetLeft
      };
    },
    
    offsetParent: function(){ return $(this[0].offsetParent); },

    offset: function(){
      var rect = this[0].getBoundingClientRect(),
          b = document.body;
      return {
        top: rect.top + b.scrollTop,
        left: rect.left + b.scrollLeft
      };
    }


  });
  
////////////////////////////////////////
// AJAX

  function ajaxRequest(opts){

    if ( !opts ) { return false; }

    if ( !opts.url ) {
      if ( opts.error ) { opts.error.call(false, 'no url'); }
      return false;
    }

    opts.method = opts.method || 'GET';

    var request = new XMLHttpRequest();
    request.open(opts.method, opts.url, true);

    if ( opts.method === 'POST' ) {
      request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    }

    request.onload = function() {
      var resp = request.responseText,
          status = request.status;

      if ( status >= 200 && status < 400) {
        // Success!
        if ( opts.success ) { opts.success.call(request, resp, status, request ); }
      } else {
        // We reached our target server, but it returned an error
        if ( opts.error ) { opts.error.call(request, request, status, resp ); }
      }
      if ( opts.complete ) { opts.complete.call(request, request, status); }
    };

    request.onerror = function() {
      // There was a connection error of some sort
      if ( opts.error ) { opts.error.call(request, request, status, request.responseText ); }
    };

    if ( opts.dataType ) { request.overrideMimeType(opts.dataType); }

    request.send(opts.data);
    return request;
  }

  $.extend({

    ajax: function(url,opts){
      if ( arguments.length === 1 ) { opts = arguments[0]; }
      else { opts.url = url || opts.url; }
      return ajaxRequest(opts);
    },

    get: $.ajax,

    post: function(url,data,success,dataType){
      var opts = {};
      if ( arguments.length === 1 ) { opts = arguments[0]; }
      else {
        opts = {
          url: url,
          data: data,
          success: success,
          dataType: dataType
        };
      }
      opts.method = 'POST';
      return ajaxRequest(opts);
    }

  });

}($));

// Alert the dev if a collection function is not available.  
$.each('add addBack addClass after ajaxComplete ajaxError ajaxSend ajaxStart ajaxStop ajaxSuccess andSelf animate append appendTo attr before bind blur change children clearQueue click clone closest contents context css data dblclick delay delegate dequeue detach die empty end eq error fadeIn fadeOut fadeTo fadeToggle filter find finish first focus focusin focusout get has hasClass height hide hover html index innerHeight innerWidth insertAfter insertBefore is keydown keypress keyup last live load load map mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup next nextAll nextUntil not off offset offsetParent on one outerHeight outerWidth parent parents parentsUntil position prepend prependTo prev prevAll prevUntil promise prop pushStack queue ready remove removeAttr removeClass removeData removeProp replaceAll replaceWith resize scroll scrollLeft scrollTop select selector serialize serializeArray show siblings size slice slideDown slideToggle slideUp stop submit text toArray toggle toggle toggleClass trigger triggerHandler unbind undelegate unload unwrap val width wrap wrapAll wrapInner'.split(' '),function(i,fn){
  if ( !$.fn[fn] ) { $.fn[fn] = function(){ console.error('`.'+fn+'()` is not currently available. Try adding a half$ extension, or switch to jQuery'); return this; } }
});

// Alert the dev if a $ function is not available
$.each('ajax ajaxPrefilter ajaxSetup ajaxTransport boxModel browser Callbacks contains cssHooks cssNumber data Deferred dequeue error get getJSON getScript globalEval grep hasData holdReady inArray isArray isEmptyObject isFunction isNumeric isPlainObject isWindow isXMLDoc makeArray map merge noConflict noop now param parseHTML parseJSON parseXML post proxy queue removeData sub support trim type unique when boxModel browser'.split(' '),function(fn){
  if ( !$[fn] ) { $[fn] = function(){ console.error('`.'+fn+'()` is not currently available. Try adding a half$ extension, or switch to jQuery if one is not available'); return this; } }
});

////////////////////////////////////////


$(function(){ console.log('DOM Ready'); });

console.log($,jQuery);
  var $p = $('p');
  $p.first().addClass('test strange').toggleClass('strange');

  console.log($p, $p.first().offset(), $p.first().position());
  console.log($p.forEach(function(){}).forEach(function(el){ console.log('here we go again',el); }));

  $p.eq(4).addClass('test');

  var h1 = document.querySelector('h1'),
      $h1 = $(h1).toggleClass('strange');

  //console.log($.is$($h1),$h1.is('h1'), $h1.is($h1[0]), $h1.is(false),$h1.indexOf(h1),$h1.addClass('test'),$h1.hasClass('test'),$h1.hasClass('nope'));

  $h1.serialize();

  //console.log($p.push($h1[0]),$p);

  var $p2 = $('#para-2').addClass('strange').text('paragraph 2');

  $p.first().text('hi');


  $(document.createElement('img')).prependTo(document.body).attr({
    'width': '80px',
    'src':'https://www.google.com/images/srpr/logo11w.png',
    'alt': 'google'
  });

  $('<img src="https://www.google.com/images/srpr/logo11w.png" />').appendTo($h1.parent()).attr({
    'width': '80px',
    'alt': 'google'
  });

  var $body = $(document.body);

  console.log($body.css('background'));
  $body.css({ 
    'background': '#eee',
    'transform':'skewY(5deg)'
  });
  console.log($body.children('p').filter('.test').remove().appendTo($body));




            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.

Console