Pen Settings

HTML

CSS

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

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

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

Behavior

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.

HTML

              
                <div class="phone">
  <div class="phone-screen">
    <div class="phone-header">
      <div class="phone-signal">Carrier</div>
      <div class="phone-time">12:00</div>
      <div class="phone-battery"></div>
    </div>
    <div class="app">
      <header class="app-header">
        <div class="app-category">Fish</div>
        <div class="open-search button"><div class="icon-search"></div></div>
        <div class="open-foldmenu button"></div>
        <nav class="foldmenu">
          <ul>
            <li class="foldmenu-item">
              <div class="foldmenu-header">
                <div class="foldmenu-header-icon icon-html5"></div>
                <div class="foldmenu-header-caption">Corals</div>
              </div>
              <ul class="foldmenu-sub">
                <li><a class="foldmenu-sub-item" href="#">SPS Corals</a></li>
                <li><a class="foldmenu-sub-item" href="#">LPS Corals</a></li>
                <li><a class="foldmenu-sub-item" href="#">Mushrooms</a></li>
                <li><a class="foldmenu-sub-item" href="#">Soft Corals</a></li>
                <li><a class="foldmenu-sub-item" href="#">Polyps</a></li>
              </ul>
            </li>
            <li class="foldmenu-item">
              <div class="foldmenu-header">
                <div class="foldmenu-header-icon icon-css3"></div>
                <div class="foldmenu-header-caption">Fish</div>
              </div>
              <ul class="foldmenu-sub">
                <li><a class="foldmenu-sub-item" href="#">Sub-item 1</a></li>
                <li><a class="foldmenu-sub-item" href="#">Sub-item 2</a></li>
                <li><a class="foldmenu-sub-item" href="#">Sub-item 3</a></li>
                <li><a class="foldmenu-sub-item" href="#">Sub-item 4</a></li>
                <li><a class="foldmenu-sub-item" href="#">Sub-item 5</a></li>
              </ul>
            </li>
            <li class="foldmenu-item">
              <div class="foldmenu-header">
                <div class="foldmenu-header-icon icon-github"></div>
                <div class="foldmenu-header-caption">Invertebrates</div>
              </div>
              <ul class="foldmenu-sub">
                <li><a class="foldmenu-sub-item" href="#">Sub-item 1</a></li>
                <li><a class="foldmenu-sub-item" href="#">Sub-item 2</a></li>
                <li><a class="foldmenu-sub-item" href="#">Sub-item 3</a></li>
                <li><a class="foldmenu-sub-item" href="#">Sub-item 4</a></li>
                <li><a class="foldmenu-sub-item" href="#">Sub-item 5</a></li>
              </ul>
            </li>
            <li class="foldmenu-item">
              <div class="foldmenu-header">
                <div class="foldmenu-header-icon icon-dribbble"></div>
                <div class="foldmenu-header-caption">Plants</div>
              </div>
              <ul class="foldmenu-sub">
                <li><a class="foldmenu-sub-item" href="#">Sub-item 1</a></li>
                <li><a class="foldmenu-sub-item" href="#">Sub-item 2</a></li>
                <li><a class="foldmenu-sub-item" href="#">Sub-item 3</a></li>
                <li><a class="foldmenu-sub-item" href="#">Sub-item 4</a></li>
                <li><a class="foldmenu-sub-item" href="#">Sub-item 5</a></li>
              </ul>
            </li>
          </ul>
        </nav>
      </header>
      <div class="app-main">
        <header class="item-header">
          <div class="item-image">
            <img src="http://www.liveaquaria.com/images/categories/product/p-80188-clownfish.jpg" width="180" height="180"/>
          </div>
          <h1>Ocellaris clownfish</h1>
          <p>Amphiprion ocellaris</p>
        </header>
        <div class="item-content">
          <div class="item-info">
            <ul>
              <li class="item-info-item">
                <div class="icon-bar-chart"></div>
                20 G
              </li>
              <li class="item-info-item">
                <div class="icon-sun"></div>
                78-84°F
              </li>
              <li class="item-info-item">
                <div class="icon-thumbs-up-alt"></div>
                Yes
              </li>
              <li class="item-info-item">
                <div class="icon-resize-horizontal"></div>
                2"
              </li>
              <li class="item-info-item">
                <div class="icon-heart-empty"></div>
                Easy
              </li>
            </ul>
          </div>
          <div class="item-additional-info">
            <strong>Food:</strong> Meaty foods and frozen icecream
          </div>
        </div>
      </div>
      <footer class="app-footer">
        <nav class="appmenu">
          <ul>
            <li class="appmenu-item">
              <div class="icon-bookmark"></div>
              Bookmarks
            </li>
            <li class="appmenu-item">
              <div class="icon-help"></div>
              Help
            </li>
            <li class="appmenu-item">
              <div class="icon-gear"></div>
              Settings
            </li>
          </ul>
        </nav>
      </footer>
    </div>
  </div>
</div>

<p class="credits">
  Based on <a href="http://dribbble.com/shots/796696-Coral-Reference-Guide-iPhone-App-Submenu">this</a> Dribbble shot.<br/>
  Hint: It's all about the folding menu, don't expect other buttons to work :)<br/>
  Icons are probably not very accurate, sorry!
</p>
              
            
!

CSS

              
                @import "compass/css3";

@import '//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css';

$screen: #141414;
$statusbar: #ccc;
$bluegray: rgb(37, 50, 59);
$red: rgb(122, 34, 12);

@mixin simplegradient($gradient) {
  background-image: -webkit-linear-gradient(top, $gradient);
  background-image: -moz-linear-gradient(top, $gradient);
  background-image: -o-linear-gradient(top, $gradient);
  background-image: linear-gradient(to bottom, $gradient);
}

/**
 * Default elements
 */

nav ul {
  padding: 0;
  margin: 0;
  list-style: none;
}

/**
 * Resolution constraints (for easy reference)
 */

.phone, .phone-screen {
  width: 320px;
  height: 480px; // phone-header + app
}
.phone-header {
  height: 20px;
}
.app {
  height: 460px; // header + main + footer
}
.app-header {
  height: 44px;
}
.app-main {
  height: 360px;
}
.app-footer {
  height: 56px;
}

/**
 * Default classes
 */

.phone {
  padding: 124px 22px;
  border-radius: 48px;
  margin: 20px auto;
  background-color: #000;
  box-shadow: 0 0 22px #999;
}
.phone-screen {
  overflow: hidden;
  background: $screen;
}
.phone-header {
  position: relative;
  overflow: hidden;
  padding: 0 5px;
  color: $statusbar;
  font-size: 14px;
  line-height: 20px;
}
.phone-signal {
  float: left;
  text-transform: uppercase;
}
.phone-signal:before { // signal icon
  content: '';
  display: inline-block;
  width: 3px;
  height: 4px;
  margin: 0 18px 0 0;
  background: $statusbar;
  box-shadow:
    4px 0, 4px -1px,
    8px 0, 8px -2px,
    12px 0, 12px -3px,
    16px 0, 16px -4px;
}
.phone-time { // funky way to center align in phone header
  position: absolute;
  left: 50%;
  width: 40px;
  margin-left: -20px;
}
.phone-battery { // empty battery shell
  position: relative;
  float: right;
  width: 17px;
  height: 8px;
  border: 1px solid;
  border-radius: 2px;
  margin: 5px 2px 0 0;
}
.phone-battery:before { // battery center fill
  content: '';
  display: block;
  width: 15px;
  height: 6px;
  margin: 1px;
  background: $statusbar;
}
.phone-battery:after { // small right thingy
  content: '';
  position: absolute;
  top: 2px;
  right: -3px;
  display: block;
  width: 1px;
  height: 2px;
  border: 1px solid;
}

.app {
  position: relative;
  background: #fff;
  font-family: 'Source Sans Pro', sans-serif;
  transition: left 0.3s ease;
}
.app-header {
  position: relative;
  @include simplegradient((lighten($red, 5), darken($red, 10)));
  background-color: $red;
  color: #fff;
}
.app-header .button {
  position: absolute;
  top: 8px;
  width: 24px;
  height: 24px;
  border: 2px solid lighten($red, 5);
  border-radius: 4px;
  @include simplegradient((darken($red, 2), darken($red, 10)));
  cursor: pointer;
}
.app-header .button:hover {
  @include simplegradient((lighten($red, 2), darken($red, 10)));
}
.open-foldmenu {
  left: 8px;
}
.open-foldmenu:before { // faux icon
  content: '';
  position: absolute;
  top: 5px;
  left: 4px;
  display: block;
  width: 16px;
  height: 2px;
  background: #fff;
  box-shadow: 0 6px, 0 12px;
}
.open-search {
  right: 8px;
  text-align: center;
  line-height: 24px;
}
.app-category {
  text-align: center;
  font-size: 20px;
  line-height: 44px;
  text-transform: uppercase;
}
.item-header {
  position: relative;
  overflow: hidden;
  height: 259px;
  border-bottom: 1px solid #ccc;
  box-shadow: inset 0 0 16px #ccc;
}
.item-image:before {
  content: '';
  position: absolute;
  top: 2px;
  left: 56px;
  display: block;
  width: 208px;
  height: 208px;
  border-radius: 50%;
  box-shadow: inset 0 0 8px #ccc;
}
.item-image:after {
  content: '';
  position: absolute;
  top: 6px;
  left: 60px;
  display: block;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  @include simplegradient((rgba(#000, 0.2), rgba(#000, 0)));
}
.item-image img {
  display: block;
  margin: 16px auto;
  border-radius: 50%;
  box-shadow: inset 0 0 8px #ccc;
}
.item-header h1 {
  margin: 0;
  color: $bluegray;
  font-size: 18px;
  font-weight: 600;
  text-align: center;
  text-transform: uppercase;
}
.item-header p {
  margin: 0;
  color: $red;
  font-size: 14px;
  text-align: center;
}
.item-header p:before {
  content: '( ';
}
.item-header p:after {
  content: ' )';
}
.item-info {
  height: 62px;
  border: dashed #ccc;
  border-width: 1px 0;
  margin: 2px 0;
}
.item-info ul {
  padding: 0;
  margin: 0;
  list-style-type: none;
}
.item-info-item {
  float: left;
  width: 64px;
  height: 62px;
  color: $red;
  font-size: 14px;
  font-weight: 600;
  text-align: center;
  text-transform: uppercase;
}
.item-info-item [class^="icon-"] {
  display: block;
  width: 52px;
  height: 52px;
  margin: 2px auto -12px;
  border-radius: 50%;
  @include simplegradient((#ccc, #fff 60%));
  color: #777;
  font-size: 24px;
  line-height: 52px;
}
.item-additional-info {
  height: 31px;
  border-top: 1px solid #ccc;
  color: $bluegray;
  font-size: 14px;
  line-height: 32px;
  text-align: center;
  box-shadow: inset 0 0 16px #ccc;
}
.app-footer {
  background-color: $bluegray;
  color: #fff;
}
.appmenu-item {
  float: left;
  width: 106px;
  height: 54px;
  margin: 1px 0 0 1px;
  @include simplegradient(($bluegray 10%, lighten($bluegray, 5) 25%, darken($bluegray, 5)));
  background-color: $bluegray;
  font-size: 14px;
  text-align: center;
  text-transform: uppercase;
  cursor: pointer;
}
.appmenu-item:first-child {
  margin-left: 0;
}
.appmenu-item:hover {
  @include simplegradient(($bluegray 10%, lighten($bluegray, 10) 25%, darken($bluegray, 5)));
}
.appmenu-item [class^="icon-"] {
  display: block;
  width: 1em;
  height: 1em;
  margin: 8px auto 2px;
  font-size: 16px;
}
.appmenu-item .icon-help:before {
  content: '?';
  display: block;
  width: 1em;
  height: 1em;
  border-radius: 50%;
  background: #fff;
  color: $bluegray;
}

.foldmenu {
  position: absolute;
  top: 0;
  right: 100%;
  width: 112px;
  height: 448px; // that's 460px including bottom border
  border-bottom: 12px solid #fff;
  line-height: 1;
}
.foldmenu-header {
  overflow: hidden;
  position: relative;
  width: 112px;
  height: 112px;
  background: #fff;
  color: $bluegray;
  font-weight: 600;
  text-transform: uppercase;
  cursor: pointer;
}
.foldmenu-header:before { // faux box-shadow gradient
  content: '';
  position: absolute;
  top: 24px;
  left: 24px;
  display: block;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  @include simplegradient((#ccc, #fff));
}
.foldmenu-header-icon {
  position: relative;
  box-sizing: border-box;
  display: block;
  width: 56px;
  height: 56px;
  border: 4px solid #ccc;
  border-radius: 50%;
  margin: 28px auto;
  $gradient: center top, circle farthest-side, #eee 50%, #ccc 50%;
  background-image: -webkit-radial-gradient($gradient);
  background-image: -moz-radial-gradient($gradient);
  background-image: -ms-radial-gradient($gradient);
  background-color: #eee;
  font-size: 32px;
  line-height: 48px;
  text-align: center;
  transition: all 0.2s ease;
}
.active .foldmenu-header-icon {
  border-color: rgb(122, 34, 12);
  $gradient: center top, circle farthest-side, rgb(169, 114, 100) 50%, rgb(122, 34, 12) 50%;
  background-image: -webkit-radial-gradient($gradient);
  background-image: -moz-radial-gradient($gradient);
  background-image: -ms-radial-gradient($gradient);
  background-color: rgb(169, 114, 100);
  color: rgb(212, 184, 177);
}
.foldmenu-header-caption {
  position: absolute;
  bottom: 0;
  width: 100%;
  line-height: 24px;
  text-align: center;
}
.foldmenu-sub {
  overflow: hidden;
  height: 0;
}
.foldmenu-sub-item {
  display: block;
  border-width: 1px 0;
  border-style: solid;
  border-color: lighten($bluegray, 2) transparent darken($bluegray, 2);
  background: $bluegray;
  color: #ccc;
  line-height: 32px;
  text-align: center;
  text-shadow: 0 0 4px darken($bluegray, 80);
  text-decoration: none;
}
:first-child > .foldmenu-sub-item {
  border-top: none;
  box-shadow: inset 0 8px 8px -8px #000;
}
:last-child > .foldmenu-sub-item {
  border-bottom: none;
  box-shadow: inset 0 -8px 8px -8px #000;
}
.foldmenu-sub-item:hover {
  background: lighten($bluegray, 2);
}

.credits {
  color: #333;
  font-family: 'Source Sans Pro', sans-serif;
  text-align: center;
  
  a {
    color: #000;
    &:hover {
      color: #333;
    }
  }
}

/**
 * JavaScript generated classes
 */

.foldmenu-perspective {
  perspective: 200px;
}
.foldmenu-fold__top, .foldmenu-fold__bottom {
  overflow: hidden;
  width: 112px;
  height: 56px;
}
.foldmenu-fold__top {
  transform-origin: center top;
  transform: rotateX(0);
}
.foldmenu-fold__bottom {
  transform-origin: center bottom;
  transform: rotateX(0);
}
.foldmenu-fold__bottom .foldmenu-header {
  top: -56px;
}
              
            
!

JS

              
                /**
 * Based on http://dribbble.com/shots/796696-Coral-Reference-Guide-iPhone-App-Submenu
 */


/*
 * RequestAnimationFrame polyfill by Erik Möller
 */
(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelAnimationFrame=window[c[a]+"CancelAnimationFrame"]||window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());

$(function() {
  // duplicate headers so we can fold them
  $('.foldmenu-header').each(function() {
    var $this       = $(this),
        perspective = $('<div class="foldmenu-perspective"></div>'),
        foldTop     = $('<div class="foldmenu-fold__top"></div>'),
        foldBottom  = $('<div class="foldmenu-fold__bottom"></div>');
    $this.replaceWith(perspective);
    
    perspective.append(foldTop);
    perspective.append(foldBottom);
    
    foldTop.append($this);
    foldBottom.append($this.clone());
  });
  
  var items = $('.foldmenu-item'),
      status = {
        action: 'none', // action in ['none', 'expand', 'collapse']
        current: null, // current in [null, 0, 1, 2, 3] - index of currently expanded item
        next: null, // next in [null, 0, 1, 2, 3] - index of next item to expand
        time: 0 // 0 <= time <= 1
      },
      el = {
        sub: null, // currently expanding/collapsing submenu 
        top: null, // currently folding elements
        bottom: null // currently folding elements
      };
  
  var $app = $('.app'),
      foldmenuOpen = false;
  
  // click events
  $('.open-foldmenu').on('click', function() {
    (foldmenuOpen = !foldmenuOpen) ? $app.css({left: 112}) : $app.css({left: 0});
  });
  
  $('.foldmenu').on('click', '.foldmenu-perspective', function() {
    if (status.action !== 'none')
      return;
    
    var item = $(this).parents('.foldmenu-item'),
        index = items.index(item);
    
    // set animation status
    if (status.current === null) {
      status.action = 'expand'; // nothing to collapse
      el.sub = $('.foldmenu-sub:eq(' + index + ')');
      el.top = $('.foldmenu-fold__top:not(:eq(' + index + '))');
      el.bottom = $('.foldmenu-fold__bottom:not(:eq(' + index + '))');
    } else {
      items.eq(status.current).removeClass('active');
      
      status.action = 'collapse'; // collapse current first
      el.sub = $('.foldmenu-sub:eq(' + status.current + ')');
      el.top = $('.foldmenu-fold__top:not(:eq(' + status.current + '))');
      el.bottom = $('.foldmenu-fold__bottom:not(:eq(' + status.current + '))');
    }
    if (status.current !== index)
      status.next = index; // expand next (after collapsing current, if any)
    // start animation
    status.time = 0;
    requestAnimationFrame(animate);
  });
  
  // animation loop
  function animate() {
    // increase timer
    status.time += 0.07;
    if (status.time > 1) {
      status.time = 1;
    } else {
      requestAnimationFrame(animate);
    }
    
    // ToDo: DRY!
    
    if (status.action === 'expand') {
      var margin = fold(60 * status.time);
      el.sub.css('height', 3 * margin + 'px');
      
      if (status.time == 1) {
        status.action = 'none';
        status.current = status.next;
        status.next = null;
        status.time = 0;
        
        items.eq(status.current).addClass('active');
      }
    } else if (status.action === 'collapse') {
      var margin = fold(60 * (1 - status.time));
      el.sub.css('height', 3 * margin + 'px');
      
      if (status.time == 1) {
        if (status.next !== null) {
          el.sub = $('.foldmenu-sub:eq(' + status.next + ')');
          el.top = $('.foldmenu-fold__top:not(:eq(' + status.next + '))');
          el.bottom = $('.foldmenu-fold__bottom:not(:eq(' + status.next + '))');
          
          status.action = 'expand';
          
          requestAnimationFrame(animate);
        } else {
          status.action = 'none';
        }
        
        status.current = null;
        status.time = 0;
      }
    }
  }
  
  function fold(deg) {
    var gap = Math.ceil((1 - Math.cos(deg * Math.PI / 180)) * 112);
    
    el.top.css({
      marginBottom: -gap + 'px',
      transform: 'rotateX(' + -deg + 'deg)',
      opacity: 1 - 0.0017 * deg
    });
    el.bottom.css({
      transform: 'rotateX(' + deg + 'deg)'
    });
    
    return gap;
  }
  
  // trigger initial click
  setTimeout(function() {
    $('.open-foldmenu').click();
  }, 500);
  setTimeout(function() {
    $('.foldmenu-perspective:eq(0)').click();
  }, 1000);
  
  // update time
  $time = $('.phone-time');
  function updateTime() {
    var current = new Date();
    $time.text(current.toTimeString().slice(0, 5));
    setTimeout(updateTime, (60 - current.getSeconds()) * 1000);
  }
  updateTime();
});
              
            
!
999px

Console