Search code examples
htmlcssbordertransform

How to fix "border around a border" bug while using css transform (translate or/and scale) and values with floating points?


I encountered this bug (see bug/expected image) while trying to use css transformation with float arguments for a div element with a border. It looks like a "border around a border", this extra border has the same color as an element background. The bug obviously related to how browsers works with float values, because when I use just transform: translate(10px, 10px), everything is ok. One interesting thing, some float arguments works ok, but other does not.

I tried different advices from various resources related for example to blurry border or bugs with floating values, But unfortunately, nothing works. Here is a list of things I tried:

  • add will-change: transform to element
  • backface-visibility: hidden
  • -webkit-filter: blur(0px)
  • -webkit-font-smoothing: antialised
  • use only odd/even numbers for translate

Possible workarounds:

  • Add border-radius: 1px (it was unexpected)
  • Remove border + wrap in another bigger div + center it

Code to reproduce (try different float arguments in transform):

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  <style>
    .item {
      transform: scale(1.07);
      background-color: red;
      border: 10px solid white;
      width: 50px;
      height: 50px;
    }
  </style>
  <body>
    <div class="container">
      <div class="item"></div>
    </div>
  </body>
</html>

Link to codesandbox


Solution

  • This seems to be a rendering bug in the browser. The best solution (assuming there are no other constraints to this problem) would be to add background-clip: content-box; in the .item CSS block.

    This clips the background of the element to the element's content box, instead of its border box, which in practice means that the background is not rendered under the border of the element, thus most likely it won't bleed over the border with sub-pixel rendering.