Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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="[email protected]" 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="{{item.class}}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

  <ul>
    <li class="{{item.class}}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

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

</body>

</html>

Update

Coming back to this about a year later it appears Google has fixed the rendering bug that caused this, although I'm not sure exactly which release included the fix. I no longer see this issue on Chrome v56.0.2924.87.

like image 594
NanoWizard Avatar asked Dec 28 '15 22:12

NanoWizard


People also ask

How do I make bullet points the same color?

Click a bullet or number in a list. All the bullets or numbers in the list are selected. On the Home tab, in the Font group, make the changes that you want. For example, click the arrow next to Font Color, and then click the color that you want.

How do I change the color of a bullet in constant contact?

You will have to click on the Design tab located on the left side of the screen when you are editing your campaign. Once you click on that tab you will want to scroll a little bit down until you see a section that says "Fonts". Then, you will click on the "A" that has a color bar underneath it and select a new color.

How do I change the color of a bullet in HTML without CSS?

The easiest thing you can do is wrap the contents of the <li> in a <span> or equivalent then you can set the color independently. Alternatively, you could make an image with the bullet color you want and set it with the list-style-image property.


1 Answers

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="[email protected]" 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="{{item.class}}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

  <ul>
    <li class="{{item.class}}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

  <ul>
    <li ng-class="{'good': item.class==='good', 'warning': item.class==='warning', 'danger': item.class==='danger'}" ng-repeat="item in items">{{item.value}}</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="[email protected]" 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="{{item.class}}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

  <ul>
    <li class="{{item.class}}" ng-repeat="item in items">{{item.value}}</li>
  </ul>

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

</body>

</html>
like image 80
Josh Crozier Avatar answered Sep 23 '22 00:09

Josh Crozier