Search code examples
htmlcsssvgsafaripixel

<1px border issue in Safari 11.1.2


I have come across an odd issue I have never seen before.

I am working with SVGs to create a radial-wipe :hover and :focus effect on a user avatar:

Working in Chrome

Everything I have designed/developed is to an 8px grid. Below is my markup and css.

/* css */
.avatar {
  position: relative;
  box-sizing: border-box;
  display: block;
  padding: 2px;
  border: 1px solid #c9c9c9;
  border-radius: 100%;
}
.avatar:focus {
  outline: 1px dashed #1c1c1c;
}
.avatar--l {
  width: 48px;
  height: 48px;
}
.avatar__ring {
  position: absolute;
  top: -1px;
  left: -1px;
}
.avatar--l .avatar__ring {
  width: 48px;
  height: 48px;
}
.avatar__ring__stroke {
  transform: rotate(-90deg);
  transform-origin: 50% 50%;
  stroke: #11a0ad;
  stroke-width: 1;
  fill: none;
  transition: all 500ms ease-in-out;
}
.avatar:hover .avatar__ring__stroke,
.avatar:focus .avatar__ring__stroke{
  stroke-dashoffset: 0;
}
.avatar--l .avatar__ring__stroke {
  stroke-dasharray: 150.72; /* 48 * 3.14 */
  stroke-dashoffset: 150.72; /* 48 * 3.14 */
}
.avatar__img {
  width: 100%;
  height: 100%;
  border-radius: 100%;
}
<a class="avatar avatar--l avatar--error" href="https://www.example.com" title="Lexis Fulco">
  <svg class="avatar__ring" viewBox="0 0 48 48">
    <circle class="avatar__ring__stroke" cx="24" cy="24" r="23.5"></circle>
  </svg>
  <div class="avatar__img" style="background: url('https://api.adorable.io/avatars/178/[email protected]') center center / cover no-repeat, white;"></div>
</a>

As the example GIF above indicates, this is working fine in some browsers—Chrome 68.0.3440.106 and Firefox 61.0.2, specifically. However, in Safari 11.1.2 I am not getting the desired result:

Not pixel-perfect in Safari

The blue svg ring intermittently aligns with the underlying grey border (notice it's off by 1px on the Y axis and exposing a portion of the grey border at the bottom of the ring).

When I look at the element's Box Model in Safari I get an interesting result:

Safari box model

The element itself, as well as the element's border have values of ~47.99 and ~0.99, which goes against everything I know to be true on the subject: "Browser's smallest unit of measure is ultimately a single pixel (1px)".

Compare the box models in Chrome or Firefox and I get the expected result: all round numbers, adhering to the CSS I declared.

So my questions:

  • Since when can browsers render elements smaller than 1px?
  • Why is this svg disregarding my css declarations in Safari and not wiping from the centre of the element's radius as it is in Chrome and Firefox?

Edit:

Interestingly, I cannot recreate the issue in the snippet I have provided, when viewing this question with Safari. However, other properties have the same floating point imprecision as well:

Strange subpixel rendering


Solution

  • So the only thing more annoying than not solving a development problem, is solving it without having an explanation as to how/why.

    This problem sort of grew as I investigated. When I posted the question, I omitted that I was working in a React.js environment as I didn't think it was relevant (stupid mistake).

    After running some isolation tests, I determined that I couldn't recreate the issue in Safari when working with static code (outside of a React.js environment). It was almost as though floating point values were leaking out of the React.js environment and into Safari's computed CSS.

    After trying almost everything else under the sun, I restarted my machine and now, cannot recreate the issue in Safari in any situation.

    Just goes to show how important it is to ask if "You've tried turning it on and off at the wall?" before conducting any other investigation ;)

    I wish it was possible to put all my hair back in after pulling it out.