4

When i use transform:skew it results in a gap between divs in Firefox but not Chrome.

Edit: I've animated the height of the divs to make the gap more visible, because it's not visible at all values.

Firefox left, Chrome right

enter image description here

@keyframes test {
  0% { height: 50px; }
  100% { height: 100px; }
}

div {
  background: black;
  width: 100px;
  height: 50px;
  transform: skew(10deg);
  animation: test 4s infinite;
}
<div></div>
<div></div>

Failed solutions so far: backface-visibility: hidden outline: 1px solid transparent border: 1px solid transparent, negative margins and scale: 1.01 <- This one works in the example but breaks in my Project, just like margins.

DvdRom
  • 738
  • 4
  • 13

1 Answers1

1

I think this is related to how browsers round the fractions while rendering. If the value gets rounded down then the div will be rendered 1px shorter. So there will be 1px gap. For more details refer:
Sub-pixel problems in CSS
How do browsers deal with non-integer values for height and width?


Workaround: We can put a pseudo child behind it which will be 1px bigger:
body {
  padding: 1rem;
}

@keyframes test {
  0% {
    height: 50px;
  }
  100% {
    height: 100px;
  }
}

div {
  background: black;
  width: 100px;
  height: 50px;
  transform: skew(10deg);
  animation: test 4s infinite;
  
  position: relative;
}

div::before {
  content: '';
  position: absolute;
  inset: -1px;
  background-color: inherit;
}
<div></div>
<div></div>

Old Attempt: One workaround could be to use drop-shadow or box-shadow:

@keyframes test {
  0% { height: 50px; }
  100% { height: 100px; }
}

div {
  background: black;
  width: 100px;
  height: 50px;
  transform: skew(10deg);
  animation: test 4s infinite;
  
  /*filter: drop-shadow(0 -1px 1px black);*/
  box-shadow: 0 0px 1px 1px black, inset 0 0px 1px 1px black;
}

body {
 padding:1rem;
}
<div></div>
<div></div>

Here we are dropping 1px shadow on top side of the div. So it'll cover the gap with same color.

Note: there is a difference between drap-shadow() and box-shadow. Use whichever suits your scenario.

the Hutt
  • 16,980
  • 2
  • 14
  • 44
  • Thanks, but it's not just a problem with animations. The gap is appears even when the height of the element has an integer number as it's `height`. [Here](https://i.imgur.com/UGhEo7W.png) you can see that the calculated height is 50px without fractions, but as @Julia mentioned in a comment, there's a fine gap between the divs. – DvdRom Mar 08 '22 at 08:12
  • 1
    Even if set value is 50px in CSS, when you zoom in/out, the browser has to calculate height for rendering enlarged element. The CSS and javascript will still give you crisp 50px in the code, but on zoom the rendered height is different. You can set 1px shadow all around to such elements `box-shadow: 0 0 1px 1px black;`. – the Hutt Mar 08 '22 at 09:04
  • The gap is present even at 100% zoom. And yes, with zoom/animation it's just more visible because of the sub-pixel rendering you mentioned, but that doesn't change the fact that at 100% there shouldn't be one. Regardless, apparently box-shadow isn't working either. [Screenshot](https://i.imgur.com/a41dwTf.png) there are gaps all around. – DvdRom Mar 08 '22 at 13:03
  • ohh. So the gap is happening at the border. We can put a pseudo child behind the div which will be 1px bigger. See the updated solution. – the Hutt Mar 08 '22 at 13:37
  • Sadly i'm already using the pseudo-elements for something else :( – DvdRom Mar 08 '22 at 15:23