Text Size Slider with AngularJS

Recently, my coworker Rick was working on some wires using a UI control to decrease/increase text size. He asked me about any technical risks of using a slider on mobile/desktop, as opposed to the usual click/tap on plus/minus to increase decrease text size and this is what I came up with by using: AngularJS, HTML5 and CSS3.

Demo

See the Pen Text Size via HTML5 Slider by Alex Castillo (@alexandercastillo) on CodePen.

Using the AngularJS Directive

Reference the javascript module on your page:

<script type="javascript" src="/lib/angular-text-slider.min.js"></script>

Add 'textSizeSlider' as a dependency on your main module:

angular.module('myApp', ['textSizeSlider']);

And include the directive on your view:

<text-size-slider min="12" max="24" unit="px" value="18"></text-size-slider>

The attributes are self explanatory but here's their definition:

  • min (int): minimum font size value
  • max (int): maximum font size value
  • unit (string): font size value unit (px, pt, %, em, rem, vw, vh, etc)
  • value (int): default font size value

* All attributes are required.

Creating the AngularJS Directive

angular.module('textSizeSlider', [])
  .directive('textSizeSlider', ['$document', function ($document) {
    return {
      restrict: 'E',
      template: '<div class="text-size-slider"><span class="small-letter" ng-style="{ fontSize: min + unit }">A</span> <input type="range" min="{{ min }}" max="{{ max }}" ng-model="textSize" class="slider" value="{{ value }}" /> <span class="big-letter" ng-style="{ fontSize: max + unit }">A</span></div>',
      scope: {
        min: '@',
        max: '@',
        unit: '@',
        value: '@',
      },
      link: function (scope, element, attr) {
        scope.textSize = scope.value;
        scope.$watch('textSize', function (size) {
          $document[0].body.style.fontSize = size + scope.unit;
        });
      }
    }
  }]);

The implementation of this directive is simple. We define an Angular Directive. Specify a template containing an input type range (HTML5's native slider). Add an ngModel to the slider. Then, we watch the ngModel of the slider for changes, and we set the body's font size to the current value of the slider's ngModel.

Styling the slider with CSS

http://www.hongkiat.com/blog/html5-range-slider-style/

A native input type range HTML element will have different default style depending on the browser used. Luckily, we can change the default appearance of sliders with CSS3. The code below was targeted for Webkit browsers (Chrome, Opera nad Safari) specifically. For Firefox and IE, please visit see this tutorial.

/**
 * Text Slider Directive - CSS  
 **/

.text-size-slider {
  line-height: 100%;
  font-size: 14px;
}

.text-size-slider .small-letter,
.text-size-slider .big-letter {
  font-weight: bold;
}

.text-size-slider .slider {
  -webkit-appearance: none;
  margin: 0 8px;
}

.text-size-slider .slider:focus {
  outline: none;
}

.text-size-slider .slider::-webkit-slider-thumb {
  border: none;
  cursor: pointer;
  -webkit-appearance: none;
  background-color: white;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  margin-top: -6px;
}

.text-size-slider .slider::-webkit-slider-runnable-track {
  width: 100%;
  height: 2px;
  cursor: pointer;
  background: white;
  border: 0;
}

Browser Support

There are 2 main parts of this component where browser support should be considered:

  1. AngularJS 1.4.x (IE9+)
  2. HTML5's Input Type Range (IE10+)

According to caniuse.com there is 88.8% browser support for the input type range (#2).