Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thick dynamic borders in table cause visual glitches in Chrome?

I have a simple dynamic border that seems to work fine in IE and Firefox but in Chrome it sometimes seems to get an odd double-thick border. I can't see any difference in CSS and I can't seem to hone in on what exactly is causing that particular border to go double-thick but I have managed to create a CodePen that demonstrates the issue. Any idea if this an issue with Chrome or am I doing something wrong with my CSS?

In the pen, if you follow the directions then you should get a cell with a double thick border on top like this:

messed up border

CodePen

    angular.module("myApp", []);
(function() {
  "use strict";

  angular.module("myApp").controller("demoController", demoController);
  demoController.$inject = ["$scope"];
  function demoController($scope) {
    $scope.model = {selected: []};
    $scope.select = function(id) {
      $scope.model.selected[id] = !$scope.model.selected[id];
    };
  }
})();
  tr.border-selected > td:not(:first-child) {
  border-top-color: #4182c2;
  border-top-width: thick;
  border-bottom-color: #4182c2;
  border-bottom-width: thick;
}
tr.border-selected > td:nth-child(2) {
  border-left-color: #4182c2;
  border-left-width: thick;
}
tr.border-selected > td:last-child {
  border-right-color: #4182c2;
  border-right-width: thick;
}

th {
  text-align: center;
}
<div ng-app="myApp">
  <div ng-controller="demoController">
    <h2 class="page-header">Chrome border glitch</h2>
      <div class="bs-callout bs-callout-info">
        <h4>Overview</h4>
        <p>Adjust the bottom frame until it has a vertical scrollbar and then click on 1009 and you'll see how chrome seems to bungle the borders in the "Opened by" column. If another row is then selected (by clicking on it) then it seems to work correctly.</p>
      </div>
    <div>
      <table class="table table-condensed table-bordered table-striped">
        <thead>
          <tr>
            <th>#</th>
            <th>Theme</th>
            <th>Opened by</th>
            <th>Updated</th>
          </tr>
        </thead>
        <tr ng-class="{'border-selected': model.selected[1010] === true}">
          <td ng-click="select(1010)">
            1010
          </td>
          <td ng-click="select(1010)">
            404 of "paper.html" and "header.html" when rendering ng-table
          </td>
          <td ng-click="select(1010)">
            329530588
          </td>
          <td ng-click="select(1010)">
            Jul 13, 2017 2:47:23 AM
          </td>
        </tr>
        <tr ng-class="{'border-selected': model.selected[1009] === true}">
          <td ng-click="select(1009)">
            1009
          </td>
          <td ng-click="select(1009)">
            ReferenceError: NgTableParams is not defined
          </td>
          <td ng-click="select(1009)">
            weiwanying
          </td>
          <td ng-click="select(1009)">
            Jul 12, 2017 9:48:30 PM
          </td>
        </tr>
        <tr ng-class="{'border-selected': model.selected[1008] === true}">
          <td ng-click="select(1008)">
            1008
          </td>
          <td ng-click="select(1008)">
            ng-table fixed header and scroll not working
          </td>
          <td ng-click="select(1008)">
            Ramlanka7
          </td>
          <td ng-click="select(1008)">
            Jul 11, 2017 11:05:27 AM
          </td>
        </tr>
        <tr ng-class="{'border-selected': model.selected[1007] === true}">
          <td ng-click="select(1007)">
            1007
          </td>
          <td ng-click="select(1007)">
            Accessibillity and wcag violation: filter input field form element don't have any label
          </td>
          <td ng-click="select(1007)">
            QuBaR
          </td>
          <td ng-click="select(1007)">
            Jul 7, 2017 2:47:13 AM
          </td>
        </tr>
        <tr ng-class="{'border-selected': model.selected[1006] === true}">
          <td ng-click="select(1006)">
            1006
          </td>
          <td ng-click="select(1006)">
            does not reload filter data in NgTableParams
          </td>
          <td ng-click="select(1006)">
            gaurav2086
          </td>
          <td ng-click="select(1006)">
            Jul 11, 2017 8:09:03 AM
          </td>
        </tr>
      </table>
    </div>
  </div>
</div>

Edit: Removed ng-table parts from pen to simplify the JavaScript.

like image 676
Mel Clemens Avatar asked Nov 08 '22 19:11

Mel Clemens


1 Answers

I had to play around around the client width a bit to see what you're describing, but yeah, it happens. Chrome is having to readjust row size on the fly due to CSS, and is probably not noticing that it needs to a full repaint of the cell after all the sizing adjustments required due to the added thickness. I vaguely recall once noticing a similar weird issue in Chrome where Chrome didn't realize it needed to repaint the backgrounds of some table cells of mine in a new spot, after some CSS changes above the table pushed down cells.

Note that if you flip on off and back on some not very directly related CSS statements in DevTools (like the TH vertical-align) the triggered repaint corrects the visual glitch, so I think it qualifies as a Chrome bug -- whatever rendering chrome finally does after such toggles should be what it does to begin with.

In general, it's probably not ideal to be causing such an adjustment to the row size by changing the border, but I can see you may have a lot of good choices, given the styling options for tables. (What would really be ideal is if there was outline-top, outline bottom, etc. and an outline-collapse for tables, so that this could be extended to add non-position-affecting outlines that eclipse arbitrary cell borders. )

There may be a few things you might do to mitigate the glitch:

  1. Setting row height to something a little extra, like td,th{height:35px} seems to solve it in my testing of your example in Chrome. I'm not sure why, since the cell vertical positioning is still getting changed on click. I guess somehow Chrome gets some cue to do a bit more repainting.
  2. Set the table to border-collapse:separate. Not ideal, I know.
  3. Wrap each cells contents in an interior div whose borders you style. This also suffers from some of the downsides of border-collapse:separate, namely the blue outline getting broken up by the regular lines, and doubled outlines on consecutively selected lines.
like image 121
Jacob C. Avatar answered Nov 15 '22 12:11

Jacob C.