1

I have a project developed using AngularJS and Bootstrap. The system should support all languages, and all the labels should switch whenever the user selects a different language.

This is working ok except for one thing: The same sentence displays different length in different languages. As a result, some labels exceed the allocated width and spoil the way things are being display.

Due to the structure of the page, I cannot use wrapping.

I would like to detect whenever a label's length exceeds the allocated space and automatically reduce the font size till it fits (you can see an example in Google Translate).

Any suggestions how this can be done?

Thanks.

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
FDavidov
  • 3,505
  • 6
  • 23
  • 59
  • Do you mean that you want to change the `class` grid? Like in default, the label is `.col-xs-2` and if the text is longer you want to change it to `.col-xs-3` for example? – Mosh Feu Mar 20 '16 at 09:48
  • Nope. I cannot change the width within which the label is being displayed. I want to change the size of the font (reduce it) if it does not fit within the pre-defined width. Take a look at Google Translate: When you write a sentence that exceeds certain length, the font size is reduced. – FDavidov Mar 20 '16 at 09:54

1 Answers1

2

It's a little tricky and not so generic but it's definitely direction. Of course that you will need to do some fine tunings for your needs.

I was created a directive for this based on (with my fixes) this answer.

Read the comments in the code:

angular.module('myApp', []).
controller('ctrl', function(){}).
directive('label', function() {
  function resize_to_fit(element) {
    // check the font-size. In the second time it will return the value with "px" so we need to remove it.
    var fontsize = element.css('font-size');
    if (fontsize.length) {
      fontsize = fontsize.replace('px', '');
    }
    // check the current height 
    var orgHeight = element.css('white-space','normal').height();
    // check the height it should be in one line
    var singleLineHeight = element.css('white-space','nowrap').height();

    // check if the element have 1 line or more
    if(orgHeight > singleLineHeight) {
      // reduce the font size in 1
      element.css('fontSize', parseFloat(fontsize) - 1);
      resize_to_fit(element);
    }
    else {
      // finally remove the "white-space" - you can remove this line if you don't need it.
      element.css('white-space','normal');
    }
  }

  return {
    link: function(scope, element) {
      resize_to_fit(element);
    }
  }
});
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<div ng-app="myApp" ng-controller="ctrl" class="container">
  <label class="col-xs-1">Lorem Ispum</label>
</div>

http://jsbin.com/dokuwew/edit?html,css,js

Community
  • 1
  • 1
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
  • Thank you @MoshFeu. If I understand correctly, you allow wrapping and, if wrapped, you decrease the font size by one, right? The question is if it will work dynamically when changing language (I have things like `{{Labels.Username}}` and `Labes` is re-populated whenever the user changes language.) – FDavidov Mar 20 '16 at 10:28
  • I don't know how your code looks like but if you [`$broadcast`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$on) the language changed event, you can listen to this and run the `resize_to_fit` function again. [A relevant answer](http://stackoverflow.com/questions/19446755/on-and-broadcast-in-angular) – Mosh Feu Mar 20 '16 at 10:32
  • Yes, I'm using `$broadcast`. Thanks for your suggestion. Will give it a try. – FDavidov Mar 20 '16 at 10:50