<html lang="en" ng-app="emvsrem" ng-controller="AppCtrl" style="font-size: {{html_fontSize}};">

<body>
  
  <header class="header">

<pre class="code-container"><span class="token-selector">html</span> { <span class="token-property">font-size</span>: <span class="token-function" contenteditable ng-model="html_fontSize" ng-bind="html_fontSize"></span> <span class="token-comment" ng-show="!htmlIsPx"> /* ({{html(html_fontSize)}} * 16px) = {{html_fontSize_px = html(html_fontSize) * 16}}px */ </span> }</pre>
    
  </header>

  <main class="main" style="font-size: {{main_fontSize}};">
    
    <p class="help">Play with values!</p>

    <section class="card-holder">

<pre class="code-container"><span class="token-selector">.main</span> { <span class="token-property">font-size</span>: <span class="token-function"  contenteditable ng-model="main_fontSize" ng-bind="main_fontSize"></span> <span class="token-comment" ng-show="!mainIsPx"> /* ({{main(main_fontSize)}} * {{html_fontSize_px}}px) = {{main_fontSize_px = main(main_fontSize) * html_fontSize_px}}px */</span> }</pre>


      <div class="flex-container">
        <article class="card card--em">
          
          <h2 class="card__title" style="font-size: {{em_fontSize}}; padding: {{em_pad}};">EM</h2>

<pre class="code-container"><span class="token-selector">.em</span> { 
  <span class="token-property">font-size</span>: <span contenteditable ng-model="em_fontSize" class="token-function" ng-bind="em_fontSize"></span>; <span class="token-comment"> /* ({{makeItLookGood(em_fontSize)}} * {{main_fontSize_px}}) = {{em_fontSize_px =  roundMeUp(makeItLookGood(em_fontSize) * main_fontSize_px)}}px */</span>
&nbsp;&nbsp;<span class="token-property">padding</span>: <span contenteditable ng-model="em_pad" class="token-function" ng-bind="em_pad"></span>; <span class="token-comment"> /* ({{makeItLookGood(em_pad)}} * {{em_fontSize_px}}) = {{roundMeUp(makeItLookGood(em_pad) * em_fontSize_px)}}px */</span>
}</pre>

        </article>

        <article class="card card--rem">
          
          <h2 class="card__title" style="font-size: {{rem_fontSize}}; padding: {{rem_pad}};">REM</h2>

<pre class="code-container"><span class="token-selector">.rem</span> { 
  <span class="token-property">font-size</span>: <span contenteditable ng-model="rem_fontSize" class="token-function" ng-bind="rem_fontSize"></span>; <span class="token-comment"> /* ({{makeItLookGood(rem_fontSize)}} * {{html_fontSize_px}}) = {{roundMeUp(makeItLookGood(rem_fontSize) * html_fontSize_px)}}px */</span>
&nbsp;&nbsp;<span class="token-property">padding</span>: <span contenteditable ng-model="rem_pad" class="token-function" ng-bind="rem_pad"></span>; <span class="token-comment"> /* ({{makeItLookGood(rem_pad)}} * {{html_fontSize_px}}) = {{roundMeUp(makeItLookGood(rem_pad) * html_fontSize_px)}}px */</span>
}</pre>

        </article>
      </div>

    </section>

  </main>
</body>
</html>
html {
  box-sizing: border-box;
}

html *,
html *:after,
html *:before
{
  box-sizing: inherit;
}

html {
  height: 100%;
}

body {
  background-color: #363F45;
  height: 100%;
}

.header {
  background-color: #3e464c;
  padding: 16px;
}

.main {
  padding: 1em;
}

.card-holder {
  padding: 22px;
  border: 2px dashed #fff;
}

.flex-container {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-around;
  padding: 50px 0;
}

.card {
  flex-basis: 250px;
  margin-top: 50px;
  margin-bottom: 50px;
  max-width: 100%;  
}

.card__title {
  margin: 0 0 20px 0;
  color: #fff;
  background-image: linear-gradient(#C2185B, #C2185B), linear-gradient(#E91E63, #E91E63);
  background-clip: content-box, border-box;
  box-shadow: 0 3px 10px rgba(0,0,0,0.23),0 3px 10px rgba(0,0,0,0.16);
  text-align: center;
  transition : 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all;  
}

.code-container {
  display: table;
  position: relative;
  font-size: 16px;
  background-color: #272822;
  overflow-x: auto;
  overflow-y: hidden;
  margin: 0 auto;
  padding: .5em;
  color: #F8F8F2;
  text-align: left;
  line-height: 1.5;
  text-shadow: 0 1px rgba(0, 0, 0, 0.3);
  font-family: Consolas, Monaco, 'Andale Mono', monospace;
}

.code-container:before {
  position: absolute;
  bottom: 100%;
  left: 0;
  right: 0;
  margin: auto;
  content: '';
  display: block;
  height: 20px;
  width: 0;
  border: dashed #fff;
  border-width: 0 1px 0 1px;
}

.token-property {
  color: #F92672;
}

.token-function {
  color: #E6DB74;
}

.token-selector {
  color: #a6e22e;
}

.token-comment {
  color: slategray;
}

.help {
  font-size: 2em;
  text-align: center;
  color: #fff;
  font-family: cursive;
  margin: .2em auto 1em;
}
var app = angular.module('emvsrem', []);

app
.controller('AppCtrl', ['$scope', function ($scope) {

  $scope.html_fontSize = '16px';
  $scope.html_fontSize_px = null;
  $scope.htmlIsPx = true;

  $scope.main_fontSize = '16px';
  $scope.main_fontSize_px = null;
  $scope.mainIsPx = true;

  $scope.em_fontSize= '1.6em';
  $scope.em_fontSize_px= null;

  $scope.em_pad= '1em';

  $scope.rem_fontSize = '1.6rem';

  $scope.rem_pad='1rem';

  var unitTrim = function(str , unit) {
    if(str.indexOf(unit) > -1) {
      return str.substring( 0, str.indexOf(unit) );
    }

    return null;
  }

  $scope.html = function(val) {

    if(val == '0') {
      $scope.html_fontSize_px = 0;
      return 0;
    }

    else if(val == '') {
      return 1;
    }

    else if(val.indexOf('px') > -1) {
      $scope.htmlIsPx = true;      

      if( unitTrim(val, 'px') == '') {
        return 1;
      }

      else {
        $scope.html_fontSize_px = unitTrim(val, 'px');
      }
    }

    else if (val.indexOf('rem') > -1) {
      $scope.htmlIsPx = false;

      if( unitTrim(val, 'rem') == '') {
        $scope.htmlIsPx = true;
        return 1;
      }

      return unitTrim(val, 'rem');        
    }

    else if(val.indexOf('em') > -1) {
      $scope.htmlIsPx = false;

      if( unitTrim(val, 'em') == '') {
        $scope.htmlIsPx = true;        
        return 1;
      }

      return unitTrim(val, 'em');
    }

    else {
      $scope.htmlIsPx = true;
      return 1;
    }
  }

  $scope.main = function(val) {

    if(val == '0') {
      $scope.main_fontSize_px = 0;
      return 0;
    }

    else if(val == '') {
      return 1;
    }

    else if(val.indexOf('px') > -1) {
      $scope.mainIsPx = true;      

      if( unitTrim(val, 'px') == '') {
        return 1;
      }

      else {
        $scope.main_fontSize_px = unitTrim(val, 'px');
      }
    }

    else if (val.indexOf('rem') > -1) {
      $scope.mainIsPx = false;

      if( unitTrim(val, 'rem') == '') {
        $scope.mainIsPx = true;
        return 1;
      }

      console.log(unitTrim(val, 'rem'));

      return unitTrim(val, 'rem');        
    }

    else if(val.indexOf('em') > -1) {
      $scope.mainIsPx = false;

      if( unitTrim(val, 'em') == '') {
        $scope.mainIsPx = true;        
        return 1;
      }

      return unitTrim(val, 'em');
    }

    else {
      $scope.mainIsPx = true;
      return 1;
    }
  }
  
  $scope.makeItLookGood = function(val) {
    if(val.indexOf('px') > -1) {
      return Math.round(unitTrim(val, 'px') * 10) / 10;
    }

    else if(val.indexOf('rem') > -1) {
      return Math.round(unitTrim(val, 'rem') * 10) / 10;
    }

    else if(val.indexOf('em') > -1) {
      return Math.round(unitTrim(val, 'em') * 10) / 10;
    }

    else {
      return null;
    }
  }


  $scope.roundMeUp = function(val) {
    return Math.round(val * 10) / 10;
  }

  // $scope.rem2px = null;


}])

.directive('contenteditable', function() {
    return {
        require: 'ngModel',
        link: function(scope, elm, attrs, ctrl) {
  
            elm.bind('keyup', function() {
                scope.$apply(function() {
                    ctrl.$setViewValue(elm.html());
                });
            });

  
            ctrl.$render = function() {
                elm.html(ctrl.$viewValue);
            };
        }
    };
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js