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.

            
              <html ng-app="test-app">
  <head>
    <meta charset="UTF-8">
  </head>
  <body ng-controller="myCtrl">

    <nav mfb-menu position="{{pos}}" effect="{{chosenEffect}}" label="hover here" active-icon="ion-edit" resting-icon="ion-plus-round" ng-repeat="pos in positions">
      <a mfb-button icon="{{button.icon}}" label="{{button.label}}" ng-repeat="button in buttons"></a>
    </nav>             

    <section id="panel" class="panel">
      <header>
        <h1>
          Angularjs Material Floating Buttons
        </h1>
        <span id="showcode" class="showcode">
          <i class="ion-eye icon-yepcode"></i>
          <i class="ion-eye-disabled icon-nocode"></i>          
        </span>
      </header>
      <article>
        <p>
          Customizable, semantic Material floating action button implemented as an Angularjs directive. Also available in vanilla html. <br>  
          <span class="striked">Shamelessly</span> Openly inspired by Google Inbox, Evernote and Path.           
        </p>
        <p>
          Click on the <strong>yellow button</strong> here above for a code preview or choose an effect from the <strong>dropdown</strong> below and hover over any button on the corners of the screen.           
        </p>
        <p>
          <select id="selections" ng-model="chosenEffect">
             <option value="{{effect.value}}" ng-disabled="{{!effect.value}}" ng-repeat="effect in effects">{{effect.name}}</option>
          </select>          
        </p>        

        <div class="code">
          <p>
            To add Material Floating Buttons to any project just download the files from here below or clone the repo from Github. <br>
          </p>
          <pre>git clone https://github.com/nobitagit/ng-material-floating-button.git</pre>
          <p>
            After referencing the styles in your header drop the MFB markup in your HTML like so:
          </p>
<pre>&lt;nav mfb-menu position="{{pos}}" effect="{{chosenEffect}}" 
        label="your main button text here" 
        active-icon="ion-edit" resting-icon="ion-plus-round"&gt;
  &lt;a mfb-button icon="icon-class" label="child button text"&gt;
  &lt;/a&gt;
&lt;/nav&gt;</pre>  
          <p>
            The attributes provide the element configuration for position, labels and icons used. All the other styles and configurations are just css.
          </p>        
          <p>
            The best way to customise the styles is to build them directly from the source as the scss file is filled with customizable variables. From there choose your favorite colors and sizes and then compile the css.
          </p>
          <p>
            If you use <a href="http://gruntjs.com/">Grunt</a> and have cloned the repo run <code>npm init</code> and then <code>grunt build</code> or <code>grunt watch</code> to have automatic compilation.
          </p>
        </div>

      </article>    
      <footer>
        <a href="https://github.com/nobitagit/ng-material-floating-button"
        >
          <button class="actions">
            <i class="ion-social-github"></i> View on Github
          </button>        
        </a>
        <a href="https://twitter.com/share?text=Check this material floating button directive for Angularjs!&url=https://nobitagit.github.io/ng-material-floating-button/&hashtags=material,design,button,angularjs,directive">
          <button class="actions">
            <i class="ion-social-twitter"></i> Share on Twitter
          </button>           
        </a>         
      </footer>
    </section>
 


  </body>
</html>
            
          
!
            
              @import "compass/css3";

/*------------------------------------*\
    #SETTINGS | Variables
\*------------------------------------*/

/* COLORS ----------------------------*/

// the main/primary color
$main-color: #E40A5D;
// aka the white text
$bright-text: rgba(255, 255, 255, 0.8);

/* SPEEDS ----------------------------*/

// the speed of the inflation of each button after hovering on the main button
$delay-staggering-inflate: 0.1s;
// when hovering on the main button the child buttons slide into view
$slide-speed: .5s;
// the labels disappear at this speed on mouse out
$label-hover-off: .5s;
// the labels appear at this speed on mouse over
$label-hover-on: .3s;

/* SIZES -----------------------------*/

// main button diameter
$main_button_size: 56px;
// main button diameter
$child_button_size: 56px;
// the distance of the main button from the closest corners of the screen
$border-distance: 25px;
// font-size for labels
$labels-font-size: 13px;
// top & bottom padding for the labels
$labels-padding-vertical: 4px;
// left & right padding for the labels
$labels-padding-horizontal: 10px;

/* OTHER VARIABLES -------------------*/

// how many child buttons does the component have
$number-of-child-buttons: 4;

/*------------------------------------*\
    #BASE | Raw styles
\*------------------------------------*/

/**
 * The very core styling of the button.
 * These styles are shared by every instance of the button.
 * Styles placed here should NOT care about placement in the screen,
 * options chosen by the user or state of the button.
 */

.mfb-component{
  box-sizing: border-box; // A better box-sizing 
  margin: $border-distance;
  position: fixed;
  white-space: nowrap;
  z-index: 30;
  // this padding is needed really only if the element is an <ul>
  // otherwise it can probably be ditched.
  padding-left: 0;
  list-style: none;
}

// make sure that everything inside this component 
// inherits the same box-sizing
.mfb-component{
  *, *:before, *:after {
    box-sizing: inherit;
  } 
}


/*------------------------------------*\
    #BASE | Modifiers
\*------------------------------------*/
/**
 * These styles depends on the placement of the button.
 * Styles can be:
 * 1. Top-left:  modified by the " --tl " suffix.
 * 2. Top-right: modified by the " --tr " suffix.
 * 3. Bottom-left:  modified by the " --bl " suffix.
 * 4. Bottom-right: modified by the " --br " suffix.
 */

.mfb-component--tl{
  @extend .mfb-component;
  left: 0; top: 0;
}
.mfb-component--tr{
  @extend .mfb-component;  
  right: 0; top: 0;
}
.mfb-component--bl{
  @extend .mfb-component;  
  left: 0; bottom: 0;
}
.mfb-component--br{
  @extend .mfb-component;  
  right: 0; bottom: 0;
} 


/*------------------------------------*\
    #BUTTONS | Base
\*------------------------------------*/  

.mfb-component__button{
  background-color: $main-color;
  display: inline-block;
  position: relative;
  border: none;
  border-radius: 50%;
  box-shadow: 0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28);
  cursor: pointer;
  outline: none;
  padding: 0;
  position: relative;
  -webkit-user-drag: none;
  font-weight: bold; 
  color: #f1f1f1;       
}

/**
 * This is the unordered list for the list items that contain 
 * the child buttons.
 *
 */ 
.mfb-component__list{
  list-style: none;
  margin: 0;
  padding: 0;
  &>li{
    display: block;
    position: absolute;
    top: 0;

    padding: 10px 0;
    margin: -10px 0;    
  }
}

/**
 * This is the basic styles for all the icons inside the main button
 */ 
.mfb-component__icon{
  position: absolute;
  font-size: 18px;
  text-align: center;
  line-height: 56px;
  width: 100%;   
}

.mfb-component__wrap{
  // this double declaration adds some padding to the main button
  // to expand the area that triggers the hover state. The equal, negative
  // margin evens out the distance form the borders so that the button
  // does not shift out of position.
  padding: $border-distance;
  margin: -$border-distance;
}
.mfb-component:hover{
  .mfb-component__icon {
    -webkit-transform: scale(1) rotate(0deg);    
    transform: scale(1) rotate(0deg);    
  }
}


/*------------------------------------*\
    #BUTTONS | Modifiers
\*------------------------------------*/  

.mfb-component__button--main{
  @extend .mfb-component__button;
  height: $main_button_size;
  width: $main_button_size;  
  z-index: 20;
}
.mfb-component__button--child{
  @extend .mfb-component__button;
  height: $child_button_size;
  width: $child_button_size;  
}
// the icons for the main button
.mfb-component__main-icon--active,
.mfb-component__main-icon--resting{
  @extend .mfb-component__icon;  
  -webkit-transform: scale(1) rotate(360deg);
  transform: scale(1) rotate(360deg);
  -webkit-transition: -webkit-transform 150ms cubic-bezier(.4,0,1,1);
  transition: transform 150ms cubic-bezier(.4,0,1,1);   
}
// the icons for the main button
.mfb-component__child-icon,
.mfb-component__child-icon{
  @extend .mfb-component__icon;  
}
.mfb-component__main-icon--active{
  opacity: 0;
}
.mfb-component:hover{
  .mfb-component__main-icon{
    -webkit-transform: scale(1) rotate(0deg);    
    transform: scale(1) rotate(0deg);    
  }
  .mfb-component__main-icon--resting{
    opacity: 0;
  }
  .mfb-component__main-icon--active{
    opacity: 1;
  }
}

/*------------------------------------*\
    #BUTTONS | Animations
\*------------------------------------*/ 

/**
 * FOUNTAIN
 * When hovering the main button the child buttons
 * jump into view from outside the viewport
 */

.mfb-component--tl.mfb-fountain,
.mfb-component--tr.mfb-fountain{
  .mfb-component__list{
    li{
      transform: scale(0);
    }
    @for $i from 1 through $number-of-child-buttons {
      $distance: -70px * $i;
      li:nth-child( #{$i} ) { 
        transform: translateY($distance) scale(0);
        transition: all $slide-speed;
        // this is the delay at which the buttons start disappearing
        transition-delay: ( $number-of-child-buttons - $i ) * 0.05s;        
      }          
    }     
  }
  &:hover{
    .mfb-component__list{
      @for $i from 1 through $number-of-child-buttons {
        $distance: 70px * $i;
        li:nth-child( #{$i} ) { 
          transform: translateY($distance) scale(1); 
          // this is the delay at which the buttons appear          
          transition-delay: $i * 0.05s;
        }          
      }                
    }
  }
}

.mfb-component--bl.mfb-fountain,
.mfb-component--br.mfb-fountain{
  .mfb-component__list{
    li{
      transform: scale(0);
    }
    @for $i from 1 through $number-of-child-buttons {
      $distance: 70px * $i;
      li:nth-child( #{$i} ) { 
        transform: translateY($distance) scale(0);
        transition: all $slide-speed;
        // this is the delay at which the buttons start disappearing
        transition-delay: ( $number-of-child-buttons - $i ) * 0.05s;        
      }          
    }     
  }
  &:hover{
    .mfb-component__list{
      @for $i from 1 through $number-of-child-buttons {
        $distance: -70px * $i;
        li:nth-child( #{$i} ) { 
          transform: translateY($distance) scale(1); 
          // this is the delay at which the buttons appear          
          transition-delay: $i * 0.05s;
        }          
      }                
    }
  }
}




/**
 * SLIDE IN + FADE
 * When hovering the main button, the child buttons slide out from beneath
 * the main button while transitioning from transparent to opaque.
 *
 */
.mfb-component--tl.mfb-slidein,
.mfb-component--tr.mfb-slidein{
  .mfb-component__list li{
    opacity: 0;
    transition: all $slide-speed;
  }
  &:hover{
    .mfb-component__list{
      li{
        opacity: 1;         
      }
      @for $i from 1 through $number-of-child-buttons {
        $distance: 70px * $i;
        li:nth-child( #{$i} ) { 
          -webkit-transform: translateY( $distance ); 
                  transform: translateY( $distance ); }          
      }                
    }
  }
}

.mfb-component--bl.mfb-slidein,
.mfb-component--br.mfb-slidein{
  .mfb-component__list li{
    opacity: 0;
    transition: all $slide-speed;
  }
  &:hover{
    .mfb-component__list{
      li{
        opacity: 1;         
      }
      @for $i from 1 through $number-of-child-buttons {
        $distance: -70px * $i;
        li:nth-child( #{$i} ) { -webkit-transform: translateY( $distance ); 
                                       transform: translateY( $distance ); }          
      }                
    }
  }
}

/**
 * ZOOM-IN
 * When hovering the main button, the child buttons grow
 * from zero to normal size.
 *
 */

.mfb-component--tl.mfb-zoomin,
.mfb-component--tr.mfb-zoomin{
  .mfb-component__list{
    li{
      transform: scale(0);
    }
    @for $i from 1 through $number-of-child-buttons {
      $distance: 70px * $i;
      li:nth-child( #{$i} ) { 
        transform: translateY($distance) scale(0);
        transition: all $slide-speed;
        // this is the delay at which the buttons start disappearing
        transition-delay: ( $number-of-child-buttons - $i ) * 0.05s;        
      }          
    }     
  }
  &:hover{
    .mfb-component__list{
      @for $i from 1 through $number-of-child-buttons {
        $distance: 70px * $i;
        li:nth-child( #{$i} ) { 
          transform: translateY($distance) scale(1); 
          // this is the delay at which the buttons appear          
          transition-delay: $i * 0.05s;
        }          
      }                
    }
  }
}

.mfb-component--bl.mfb-zoomin,
.mfb-component--br.mfb-zoomin{
  .mfb-component__list{
    li{
      transform: scale(0);
    }
    @for $i from 1 through $number-of-child-buttons {
      $distance: -70px * $i;
      li:nth-child( #{$i} ) { 
        transform: translateY($distance) scale(0);
        transition: all $slide-speed;
        // this is the delay at which the buttons start disappearing
        transition-delay: ( $number-of-child-buttons - $i ) * 0.05s;        
      }          
    }     
  }
  &:hover{
    .mfb-component__list{
      @for $i from 1 through $number-of-child-buttons {
        $distance: -70px * $i;
        li:nth-child( #{$i} ) { 
          transform: translateY($distance) scale(1); 
          // this is the delay at which the buttons appear          
          transition-delay: $i * 0.05s;
        }          
      }                
    }
  }
}



/*------------------------------------*\
    #LABELS | base
\*------------------------------------*/

/**
 * These are the labels associated to each button,
 * exposed only when hovering the related button.
 * They are called labels but are in fact data-attributes of
 * each button (an anchor tag).
 */

[data-mfb-label]:after {
  content: attr(data-mfb-label);
  opacity: 0;
  transition: all $label-hover-off;  
  background: rgba(0,0,0, .4);
  padding: $labels-padding-vertical $labels-padding-horizontal;
  border-radius: 3px;
  color: $bright-text;
  font-size: $labels-font-size;
  pointer-events: none;
  position: absolute;
  top: 50%;
  margin-top: - ($labels-padding-vertical + $labels-font-size / 2);  
  transition: all $label-hover-off; // the label disappears at this speed     
}
[data-mfb-label]:hover:after {
  content: attr(data-mfb-label);
  opacity: 1;
  transition: all $label-hover-on; // the label appears at this speed
}
/*------------------------------------*\
    #LABELS | Modifiers
\*------------------------------------*/
.mfb-component--br, .mfb-component--tr{
  [data-mfb-label]:after {
    content: attr(data-mfb-label);  
    right: 70px; 
  }
}
.mfb-component--tl, .mfb-component--bl{
  [data-mfb-label]:after {
    content: attr(data-mfb-label);  
    left: 70px; 
  }
}

/*------------------------------------*\
    #DEVELOPMENT | In development
\*------------------------------------*/
/**
 * This part is where unfinished code should stay.
 * When a feature is ready(sh) move these styles to their proper place.
 */



/*------------------------------------*\
    #DEVELOPMENT | Debuggers
\*------------------------------------*/

/**
 * These are mainly helpers for development. They do not have to end up
 * in production but it's handy to keep them when developing.
 */


/**
 * Apply this class to the html tag when developing the slide-in button
 */
html.mfb-slide-in{
  border-top: 5px solid teal; 
}

html.mfb-debug *{
  border: 1px solid red;
}








html, body{
  height: 100%;
  min-height: 100%;  
}
html{
  background: #E9EBEC;
  font-family: 'Raleway', sans-serif;
  font-weight: 200;
}
body{
  display: flex;
  align-items: center;
  justify-content: center;
}
h1{
  margin: 0.2em 0; 
  color: rgba(40, 33, 33, .7);
  color: rgba(124, 98, 152, 1);
  font-weight: 400;
}
header{
  background: #00C8BE;
  padding: 0.3em 1em;
  position: relative;
  z-index: 20;
}
.viewCode header{
  box-shadow: 0px 2px 5px 0 rgba(0, 0, 0, 0.26);
}
.showcode{
  background: rgb(232, 216, 49);
  color: rgba(124, 98, 152, 1);
  width: 40px;
  height: 40px;
  text-align: center;
  position: absolute;
  right: 1em;
  bottom: 0;
  margin-bottom: -15px;
  border-radius: 100%;
  font-size: 16px;
  cursor: pointer;
  box-shadow: 0px 2px 5px 0 rgba(0, 0, 0, 0.26);
  transition: all .3s;
}
.viewCode .showcode{
  transform: rotateX(-180deg);
  box-shadow: 0px -2px 5px 0 rgba(0, 0, 0, 0.26);      
} 
.icon-nocode, .icon-yepcode{
  transition: opacity .3s;
  position: absolute;
  left: 0;
  display: block;
  width: 100%;
  line-height: 40px;      
}    
.icon-nocode{
  opacity: 0;
}
.viewCode .icon-nocode{
  opacity: 1;
}
.viewCode .icon-yepcode{
  opacity: 0;
}     
.panel{
  width: 90%;
  position: relative;
  max-width: 650px;
  box-shadow: 0px 2px 5px 0 rgba(0, 0, 0, 0.26);
  background: #F5F5F5;
  border-radius: 3px;
  overflow: hidden;      
}
article{
  min-height: 180px;
  padding: 1em;
  font-weight: 200;
  line-height: 1.5em;
  position: relative;
}
footer{
  padding: 0.3em 1em 1em;
}
footer a, footer a:active, footer a:visited{
  color: inherit;
}
.code{
  position: absolute;
  top: 0;
  top: 0;
  left: 0;
  right: 0;      
  height: 100%;
  overflow: scroll;
  background: rgba(124, 98, 152, 0.94);
  color: rgba(245, 247, 247, 0.92);    
  padding: 0em 1em; 
  transition: all .4s;
  transform: translateY(-100%);
}
.code p:first-child{
  margin-top: 2em;
}
.code a{
  color: rgba(232, 216, 49, 0.9);
}
.viewCode .code{
  transform: translateY(0);
  box-shadow: 0px 2px 5px 0 rgba(0, 0, 0, 0.36);      
}   
.actions{
  font-weight: 300;
  text-transform: uppercase;
  font-size: 0.8em;
  padding: 1em;
  border: none;
  background: none;
  transition: color .2s;
  cursor: pointer;
}
.actions:hover{
  color: rgb(30, 30, 171);
  background: #F5F5F5;      
  box-shadow: 0px 2px 5px 0 rgba(0, 0, 0, 0.26);
}

code, pre {
  background: rgba(255,255,255,0.1);
  color:  rgba(232, 216, 49, 0.9);
  font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New",monospace;
  padding: 0.5em;
  border-radius: 3px;
  margin: 1em 0;  
}   
code{
  display: inline;
  vertical-align: middle;
  margin: 0;
}
pre{
  display: block;
}
.striked{
 text-decoration: line-through;  
} 
.mfb-component--tl{
  animation: fromTop 1s 1;
  -webkit-animation: fromTop 1s 1;
}
.mfb-component--tr{
  animation: fromTop 1.3s 1;
  -webkit-animation: fromTop 1.3s 1;
} 
.mfb-component--br{
  animation: fromBottom 1.6s 1;
  -webkit-animation: fromBottom 1.6s 1;
}
.mfb-component--bl{
  animation: fromBottom 1.9s 1;
  -webkit-animation: fromBottom 1.9s 1;
}        
@keyframes fromBottom {
  0% {
    transform: translateY(250px);
  }
  100% {
    transform: translateY(0);
  }
}
@keyframes fromTop {
  0% {
    transform: translateY(-250px);
  }
  100% {
    transform: translateY(0);
  }
}
@-webkit-keyframes fromBottom {
  0% {
    transform: translateY(250px);
  }
  100% {
    transform: translateY(0);
  }
}    
@-webkit-keyframes fromTop {
  0% {
    transform: translateY(-250px);
  }
  100% {
    transform: translateY(0);
  }
}   
            
          
!
            
              /**
 * updated codebase on: https://github.com/nobitagit/ng-material-floating-button
 *
 **/
+(function(window, angular, undefined){

  var mfb = angular.module('ng-mfb', []);

  mfb.directive('mfbMenu', [function(){
    return {
      restrict: 'EA',
      transclude: true,
      replace: true,
      scope: {
        position: '@',
        effect: '@',
        label: '@',
        resting: '@restingIcon',
        active: '@activeIcon'      
      },
      template: '<ul class="mfb-component--{{position}} mfb-{{effect}}">' +
                ' <li class="mfb-component__wrap">' +
                '  <a href="" data-mfb-label="{{label}}" class="mfb-component__button--main">' +
                '   <i class="mfb-component__main-icon--resting {{resting}}"></i>' +
                '   <i class="mfb-component__main-icon--active {{active}}"></i>' +              
                '  </a>' +
                '  <ul class="mfb-component__list" ng-transclude>' +
                '  </ul>' +
                ' </li>' +        
                '</ul>'              
    };
  }]);


  mfb.directive('mfbButton', [function(){
    return {
      require: '^mfbMenu',
      restrict: 'EA',
      transclude: true,  
      replace: true,
      scope: {
        icon: '@',
        label: '@'
      },
      template: '<li>' + 
                ' <a href="" data-mfb-label="{{label}}" class="mfb-component__button--child">' +
                '   <i class="mfb-component__child-icon {{icon}}"' +
                '   </i>' +
                ' </a>' +
                '</li>'
    };
  }]);

})(window, angular);



var app = angular.module('test-app', ['ng-mfb']);

app.controller('myCtrl', function($scope){

  $scope.positions = ['tl', 'tr', 'br', 'bl'];

  $scope.effects = [{
    name: 'Choose an effect here',
  },{
    value: 'slidein',
    name: 'Slide in + fade'
  },{
    value: 'zoomin',
    name: 'Zoom in'
  },{
    value: 'fountain',
    name: 'Fountain'
  }];

  $scope.buttons = [{
    label: 'a link',
    icon: 'ion-paper-airplane'
  },{
    label: 'a link',
    icon: 'ion-paper-airplane'
  },{
    label: 'a link',
    icon: 'ion-paper-airplane'
  },{
    label: 'a link',
    icon: 'ion-paper-airplane'
  }];

  $scope.chosenEffect = 'zoomin';

});

 var panel = document.getElementById('panel'),
    showcode = document.getElementById('showcode');

    showcode.addEventListener('click', _toggleCode);

    function _toggleCode() {
      panel.classList.toggle('viewCode');
    }
            
          
!
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