Bullet colors don’t display correctly in Chrome when changed by Angular

Can anyone explain why these bullets will change color correctly in Firefox and IE, but not in Chrome (my current version is 47.0.2526.106)? Why do the bullets in the first ul stay white, but the others change initially?

Note that I get the same behavior whether I bind to class or use the ng-class attribute.

Is there any way to get the colors to update correctly?

Firefox/IE:

FFIE Example

Chrome:

Chrome Example

angular.module('myApp', [])
  .controller('myCtrl', [
    '$scope',
    '$interval',
    function($scope, $interval) {
      var values = ['Hello', 'Oops', 'Uh-Oh...'];
      var classes = ['good', 'warning', 'danger'];
      var nItems = 8;
      $scope.items = [];

      for (var i = 0; i < nItems; i++) {
        $scope.items.push({});
      }

      function updateItems() {
        for (var i = 0; i < $scope.items.length; i++) {
          var item = $scope.items[i];
          var chosen = Math.floor(Math.random() * values.length);
          item.value = values[chosen];
          item.class = classes[chosen];
        }
      }

      $interval(updateItems, 3000);
    }
  ]);
body {
  background: #333;
  color: white;
}
ul {
  display: inline-block;
}
.good {
  color: limegreen;
}
.warning {
  color: yellow;
}
.danger {
  color: red;
}
<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <script data-require="angular.js@1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>
<body ng-controller="myCtrl">
  <ul>
    <li class="" ng-repeat="item in items"></li>
  </ul>
  <ul>
    <li class="" ng-repeat="item in items"></li>
  </ul>
  <ul>
    <li ng-class="{'good': item.class==='good', 'warning': item.class==='warning', 'danger': item.class==='danger'}" ng-repeat="item in items"></li>
  </ul>
</body>
</html>

solution

This is a Chrome rendering bug.

One option is to insert custom bullet points using a pseudo element.

ul {
  display: inline-block;
  list-style: none;
}
ul li:before {
  content: '\2022';
  text-indent: -1em;
  display: inline-block;
}

Here is the updated example:

angular.module('myApp', [])
.controller('myCtrl', [
  '$scope',
  '$interval',
  function($scope, $interval) {
    var values = ['Hello', 'Oops', 'Uh-Oh...'];
    var classes = ['good', 'warning', 'danger'];
    var nItems = 8;
    $scope.items = [];


    for (var i = 0; i < nItems; i++) {
      $scope.items.push({});
    }


    function updateItems() {
      for (var i = 0; i < $scope.items.length; i++) {
        var item = $scope.items[i];
        var chosen = Math.floor(Math.random() * values.length);
        item.value = values[chosen];
        item.class = classes[chosen];
      }
    }


    $scope.getItemValue = function(item) {
      return item.value;
    };


    $interval(updateItems, 3000);
  }
]);
body {
  background: #333;
  color: white;
}
ul {
  display: inline-block;
  list-style: none;
}
ul li:before {
  content: '\2022';
  text-indent: -1em;
  display: inline-block;
}
.good {
  color: limegreen;
}
.warning {
  color: yellow;
}
.danger {
  color: red;
}
<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <script data-require="angular.js@1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>
<body ng-controller="myCtrl">
  <ul>
    <li class="" ng-repeat="item in items"></li>
  </ul>

  <ul>
    <li class="" ng-repeat="item in items"></li>
  </ul>

  <ul>
    <li ng-class="{'good': item.class==='good', 'warning': item.class==='warning', 'danger': item.class==='danger'}" ng-repeat="item in items"></li>
  </ul>
</body>
</html>

Another option is to trigger a repaint event in order to force the browser to update the styling. This is definitely a hackish option, but nonetheless, it works:

function forceRepaint() {
  document.body.style.display = 'none';
  document.body.offsetHeight;
  document.body.style.display = '';
}

Here is the other updated example:

angular.module('myApp', [])
.controller('myCtrl', [
  '$scope',
  '$interval',
  function($scope, $interval) {
    var values = ['Hello', 'Oops', 'Uh-Oh...'];
    var classes = ['good', 'warning', 'danger'];
    var nItems = 8;
    $scope.items = [];


    for (var i = 0; i < nItems; i++) {
      $scope.items.push({});
    }


    function updateItems() {
      for (var i = 0; i < $scope.items.length; i++) {
        var item = $scope.items[i];
        var chosen = Math.floor(Math.random() * values.length);
        item.value = values[chosen];
        item.class = classes[chosen];


        forceRepaint();
      }
    }


    $scope.getItemValue = function(item) {
      return item.value;
    };


    $interval(updateItems, 3000);
  }
]);

function forceRepaint() {
  document.body.style.display = 'none';
  document.body.offsetHeight;
  document.body.style.display = '';
}
body {
  background: #333;
  color: white;
}
ul {
  display: inline-block;
}
.good {
  color: limegreen;
}
.warning {
  color: yellow;
}
.danger {
  color: red;
}
<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <script data-require="angular.js@1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>
<body ng-controller="myCtrl">
  <ul>
    <li class="" ng-repeat="item in items"></li>
  </ul>
  <ul>
    <li class="" ng-repeat="item in items"></li>
  </ul>
  <ul>
    <li ng-class="{'good': item.class==='good', 'warning': item.class==='warning', 'danger': item.class==='danger'}" ng-repeat="item in items"></li>
  </ul>
</body>
</html>