octocatstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

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.

            
              <div class="demo">
  <svg class="sidebar" viewBox="0 0 300 500">
    <path class="s-path" fill="#fff" d="M0,0 50,0 a0,250 0 1,1 0,500 L0,500" />
  </svg>
  <div class="static">
    <div class="static__text">Pull white sidebar to the right</div>
  </div>
  <div class="sidebar-content">
    <div class="contact">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/142996/elastic-man.png" alt="" class="contact__photo" />
      <span class="contact__name">Ethan Hawke</span>
      <span class="contact__status online"></span>
    </div>
    <div class="contact">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/142996/elastic-girl.png" alt="" class="contact__photo" />
      <span class="contact__name">Natalie Portman</span>
      <span class="contact__status online"></span>
    </div>
    <div class="contact">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/142996/elastic-man.png" alt="" class="contact__photo" />
      <span class="contact__name">Kevin Spacey</span>
      <span class="contact__status online"></span>
    </div>
    <div class="contact">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/142996/elastic-girl.png" alt="" class="contact__photo" />
      <span class="contact__name">Rosamund Pike</span>
      <span class="contact__status online"></span>
    </div>
    <div class="contact">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/142996/elastic-man.png" alt="" class="contact__photo" />
      <span class="contact__name">Robert Redford</span>
      <span class="contact__status online"></span>
    </div>
    <div class="contact">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/142996/elastic-girl.png" alt="" class="contact__photo" />
      <span class="contact__name">Scarlett Johansson</span>
      <span class="contact__status online"></span>
    </div>
    <div class="contact">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/142996/elastic-man.png" alt="" class="contact__photo" />
      <span class="contact__name">Tom Cruise</span>
      <span class="contact__status"></span>
    </div>
    <div class="contact">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/142996/elastic-girl.png" alt="" class="contact__photo" />
      <span class="contact__name">Eva Green</span>
      <span class="contact__status"></span>
    </div>
    <div class="contact">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/142996/elastic-man.png" alt="" class="contact__photo" />
      <span class="contact__name">Paul Newman</span>
      <span class="contact__status"></span>
    </div>
    <div class="search">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/142996/elastic-srch.png" alt="" class="search__img" />
      <input type="text" class="search__input" placeholder="Search" />
    </div>
  </div>
  <div class="chat">
    <span class="chat__back"></span>
    <span class="chat__status">status</span>
    <div class="chat__person">
      <span class="chat__online active"></span>
      <span class="chat__name">Huehue Huehue</span>
    </div>
    <div class="chat__messages">
      <div class="chat__msgRow">
        <div class="chat__message mine">Such SVG, much Javascript, very CSS!</div>
      </div>
      <div class="chat__msgRow">
        <div class="chat__message notMine">Wow!</div>
      </div>
      <div class="chat__msgRow">
        <div class="chat__message notMine">Very elastic! Such easings!</div>
      </div>
      <div class="chat__msgRow">
        <div class="chat__message mine">
          Check out my other <a href="http://codepen.io/suez/public/" target="_blank">pens</a>
        </div>
      </div>
    </div>
    <input type="text" class="chat__input" placeholder="Your message" />
  </div>
</div>
            
          
!
            
              @import "compass/css3";

*, *:before, *:after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
$openSans: 'Open Sans', Helvetica, Arial, sans-serif;
$transTime: 200ms;
html, body {
  font-size: 62.5%;
  height: 100%;
}
button, input {
  border: 0;
  outline: none;
}
body {
  background: linear-gradient( 45deg, #636F85, #6960A0);
}
.demo {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -25rem;
  margin-left: -15rem;
  width: 30rem;
  height: 50rem;
  box-shadow: 0 1rem 5rem rgba(0,0,0,0.3);
}
.static {
  height: 100%;
  font-size: 1.8rem;
  font-family: $openSans;
  background: #6D7ADA;
  
  &:before,
  &:after {
    content: "";
    position: absolute;
    left: 7rem;
    width: 2rem;
    height: 2rem;
    margin-left: -1rem;
    margin-top: -1rem;
    border: 2px solid #fff;
    border-left: none;
    border-bottom: none;
    transform: rotate(45deg);
    animation: arrows 1.5s infinite;
  }
  &:before {
    top: 15rem;
  }
  &:after {
    top: 35rem;
  }
  
  &__text {
    width: 9rem;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-left: -5rem;
    transform: translate3d(0,-50%,0);
    color: #fff;
    perspective: 1px;
    backface-visibility: hidden;
  }
}
.sidebar-content {
  z-index: -1;
  position: absolute;
  top: 0;
  left: 0;
  width: 20rem;
  height: 100%;
  padding-top: 1rem;
  opacity: 0;
  transition: opacity $transTime, z-index 0s 0s;
  background-color: #E9EAF3;
  overflow: hidden;
  
  &.active {
    z-index: 2;
    opacity: 1;
  }
}
.contact {
  position: relative;
  width: 100%;
  height: 5rem;
  padding-left: 1.7rem;
  display: flex;
  align-items: center;
  cursor: pointer;
  overflow: hidden;
  
  &__photo {
    border-radius: 50%;
    margin-right: 1.5rem;
  }
  &__name {
    font-size: 1.2rem;
    font-family: $openSans;
  }
  &__status {
    position: absolute;
    top: 2.1rem;
    right: 1.5rem;
    width: 8px;
    height: 8px;
    border: 2px solid #00B570;
    border-radius: 50%;
    opacity: 0;
    transition: opacity 0.3s;
    
    &.online {
      opacity: 1;
    }
  }
}
.search {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 5.5rem;
  padding-left: 1.5rem;
  background: #fff;
  display: flex;
  align-items: center;
}
svg {
  overflow: visible;
}
.sidebar {
  z-index: 1;
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 100%;
  height: 100%;
}
.s-path {
  cursor: grab;
}
.cloned {
  position: absolute;
  z-index: 10;
  transition: top 0.3s, left 0.3s;
  transition-delay: 0.2s;
  transition-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
  
  &.removed {
    transition: opacity 0.2s 0;
    opacity: 0;
  }
}
.chat {
  display: none;
  z-index: 5;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  padding: 2.5rem 0 5.5rem 2.5rem;
  transition: opacity $transTime;
  opacity: 0;
  
  &.active {
    opacity: 1;
    
    &:before {
      width: 100%;
    }
  }
  
  &:before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 0.5rem;
    background: #1CC6AE;
    width: 0;
    transition: width 0.2s;
  }
  
  &__back {
    position: relative;
    display: inline-block;
    width: 2rem;
    height: 2rem;
    margin-top: 0.5rem;
    margin-left: -0.6rem;
    cursor: pointer;
    
    &:hover:before {
      transform: translateX(-0.3rem) rotate(-45deg);
    }
    
    &:before {
      content: "";
      position: absolute;
      display: block;
      top: 0.4rem;
      left: 0.6rem;
      width: 1.2rem;
      height: 1.2rem;
      border: 2px solid #545675;
      border-right: none;
      border-bottom: none;
      transform: rotate(-45deg);
      transition: transform 0.3s;
    }
  }
  &__status {
    position: absolute;
    top: 2rem;
    right: 6.5rem;
    font-size: 1.2rem;
    font-family: $openSans;
    text-transform: uppercase;
    color: #B1A9A9;
  }
  &__person {
    display: inline-block;
    position: absolute;
    top: 3rem;
    right: 6.5rem;
    font-size: 2rem;
    font-family: $openSans;
    color: #36343D;
  }
  &__online {
    position: absolute;
    top: 50%;
    left: -1.5rem;
    margin-top: -3px;
    width: 8px;
    height: 8px;
    border: 2px solid #00B570;
    border-radius: 50%;
    opacity: 0;
    transition: opacity 0.3s;

    &.active {
      opacity: 1;
    }
  }
  &__messages {
    position: absolute;
    top: 7.5rem;
    left: 2.5rem;
    width: 27.5rem;
    height: 37rem;
    padding-right: 2.5rem;
    overflow-y: auto;
  }
  &__msgRow {
    margin-bottom: 0.5rem;
    
    &:after {
      content: "";
      display: table;
      clear: both;
    }
  }
  &__message {
    display: inline-block;
    max-width: 60%;
    padding: 1rem;
    font-size: 1.4rem;
    font-family: $openSans;
    
    &.mine {
      color: #2B2342;
      border: 1px solid #DFDFDF;
    }
    &.notMine {
      float: right;
      color: #23244E;
      background: #E9EAF3;
    }
  }
  &__input {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 5.5rem;
    padding: 1rem 1rem 1rem 4rem;
    background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/142996/elastic-search.png');
    background-repeat: no-repeat;
    background-position: 1rem 1.5rem;
    background-color: #E9EAF3;
    color: #2B2342;
    font-size: 1.4rem;
    font-family: $openSans;
  }
}
.ripple {
  position: absolute;
  width: 10rem;
  height: 10rem;
  margin-left: -5rem;
  margin-top: -5rem;
  background: rgba(0,0,0,0.4);
  transform: scale(0);
  animation: animRipple 0.3s;
  border-radius: 50%;
}
@keyframes animRipple {
  to {
    transform: scale(2.5);
    opacity: 0;
  }
}
@keyframes arrows {
  to {
    transform: translateX(100%) rotate(45deg);
    opacity: 0;
  }
}
            
          
!
            
              $(document).ready(function() {
  var $svg = $(".sidebar"),
      $demo = $(".demo"),
      $path = $(".s-path"),
      $sCont = $(".sidebar-content"),
      $chat = $(".chat"),
      demoTop = $demo.offset().top,
      demoLeft = $demo.offset().left,
      diffX = 0,
      curX = 0,
      finalX = 0,
      frame = 1000 / 60,
      animTime = 600,
      sContTrans = 200,
      animating = false;

  var easings = {
    smallElastic: function(t,b,c,d) {
      var ts = (t/=d)*t;
      var tc = ts*t;
      return b+c*(33*tc*ts + -106*ts*ts + 126*tc + -67*ts + 15*t);
    },
    inCubic: function(t,b,c,d) {
      var tc = (t/=d)*t*t;
      return b+c*(tc);
    }
  };

  function createD(top, ax, dir) {
    return "M0,0 "+top+",0 a"+ax+",250 0 1,"+dir+" 0,500 L0,500";
  }

  var startD = createD(50,0,1),
      midD = createD(125,75,0),
      finalD = createD(200,0,1),
      clickMidD = createD(300,80,0),
      clickMidDRev = createD(200,100,1),
      clickD = createD(300,0,1),
      currentPath = startD;

  function newD(num1, num2) {
    var d = $path.attr("d"),
        num2 = num2 || 250,
        nd = d.replace(/\ba(\d+),(\d+)\b/gi, "a" + num1 + "," + num2);
    return nd;
  }

  function animatePathD(path, d, time, handlers, callback, easingTop, easingX) {
    var steps = Math.floor(time / frame),
        curStep = 0,
        oldArr = currentPath.split(" "),
        newArr = d.split(" "),
        oldLen = oldArr.length,
        newLen = newArr.length,
        oldTop = +oldArr[1].split(",")[0],
        topDiff = +newArr[1].split(",")[0] - oldTop,
        nextTop,
        nextX,
        easingTop = easings[easingTop] || easings.smallElastic,
        easingX = easings[easingX] || easingTop;

    $(document).off("mousedown mouseup");

    function animate() {
      curStep++;
      nextTop = easingTop(curStep, oldTop, topDiff, steps);
      nextX = easingX(curStep, curX, finalX-curX, steps);
      oldArr[1] = nextTop + ",0";
      oldArr[2] = "a" + Math.abs(nextX) + ",250";
      oldArr[4] = (nextX >= 0) ? "1,1" : "1,0";
      $path.attr("d", oldArr.join(" "));
      if (curStep > steps) {
        curX = 0;
        diffX = 0;
        $path.attr("d", d);
        currentPath = d;
        if (handlers) handlers1();
        if (callback) callback();
        return;
      }
      requestAnimationFrame(animate);
    }
    animate();
  }

  function handlers1() {

    $(document).on("mousedown touchstart", ".s-path", function(e) {
      var startX =  e.pageX || e.originalEvent.touches[0].pageX;

      $(document).on("mousemove touchmove", function(e) {
        var x = e.pageX || e.originalEvent.touches[0].pageX;
        diffX = x - startX;
        if (diffX < 0) diffX = 0;
        if (diffX > 300) diffX = 300;
        curX = Math.floor(diffX/2);
        $path.attr("d", newD(curX));
      });
    });

    $(document).on("mouseup touchend", function() {
      $(document).off("mousemove touchmove");
      if (animating) return;
      if (!diffX) return;
      if (diffX < 40) {
        animatePathD($path, newD(0), animTime, true);
      } else {
        animatePathD($path, finalD, animTime, false, function() {
          $sCont.addClass("active");
          setTimeout(function() {
            $(document).on("click", closeSidebar);
          }, sContTrans);
        });
      }
    });

  }

  handlers1();

  function closeSidebar(e) {
    if ($(e.target).closest(".sidebar-content").length ||
        $(e.target).closest(".chat").length) return;
    if (animating) return;
    animating = true;
    $sCont.removeClass("active");
    $chat.removeClass("active");
    $(".cloned").addClass("removed");
    finalX = -75;
    setTimeout(function() {
      animatePathD($path, midD, animTime/3, false, function() {
        $chat.hide();
        $(".cloned").remove();
        finalX = 0;
        curX = -75;
        animatePathD($path, startD, animTime/3*2, true);
        animating = false;
      }, "inCubic");
    }, sContTrans);
    $(document).off("click", closeSidebar);
  }

  function moveImage(that) {
    var $img = $(that).find(".contact__photo"),
        top = $img.offset().top - demoTop,
        left = $img.offset().left - demoLeft,
        $clone = $img.clone().addClass("cloned");

    $clone.css({top: top, left: left});
    $demo.append($clone);
    $clone.css("top");
    $clone.css({top: "1.8rem", left: "25rem"});
  }

  function ripple(elem, e) {
    var elTop = elem.offset().top,
        elLeft = elem.offset().left,
        x = e.pageX - elLeft,
        y = e.pageY - elTop;
    var $ripple = $("<div class='ripple'></div>");
    $ripple.css({top: y, left: x});
    elem.append($ripple);
  }

  $(document).on("click", ".contact", function(e) {
    if (animating) return;
    animating = true;
    $(document).off("click", closeSidebar);
    var that = this,
        name = $(this).find(".contact__name").text(),
        online = $(this).find(".contact__status").hasClass("online");
    $(".chat__name").text(name);
    $(".chat__online").removeClass("active");
    if (online) $(".chat__online").addClass("active");
    ripple($(that),e);
    setTimeout(function() {
      $sCont.removeClass("active");
      moveImage(that);
      finalX = -80;
      setTimeout(function() {
        $(".ripple").remove();
        animatePathD($path, clickMidD, animTime/3, false, function() {
          curX = -80;
          finalX = 0;
          animatePathD($path, clickD, animTime*2/3, true, function() {
            $chat.show();
            $chat.css("top");
            $chat.addClass("active");
            animating = false;
          });
        }, "inCubic");
      }, sContTrans);
    }, sContTrans);
  });

  $(document).on("click", ".chat__back", function() {
    if (animating) return;
    animating = true;
    $chat.removeClass("active");
    $(".cloned").addClass("removed");
    setTimeout(function() {
      $(".cloned").remove();
      $chat.hide();
      finalX = 100;
      animatePathD($path, clickMidDRev, animTime/3, false, function() {
        curX = 100;
        finalX = 0;
        animatePathD($path, finalD, animTime*2/3, true, function() {
          $sCont.addClass("active");
          $(document).on("click", closeSidebar);
          animating = false;
        });
      }, "inCubic");
    }, sContTrans);
  });

  $(window).on("resize", function() {
    demoTop = $demo.offset().top;
    demoLeft = $demo.offset().left;
  });

});
            
          
!
999px
Close

Asset uploading is a PRO feature.

As a PRO member, you can drag-and-drop upload files here to use as resources. Images, Libraries, JSON data... anything you want. You can even edit them anytime, like any other code on CodePen.

Go PRO

Loading ..................

Console