2

I'm using flex layout in order to render a container div with 3 evenly sized columns. It works just as I'd expect, until I apply a scale transform. When the container is scaled down, thin gaps appear between the content boxes. The issue happens on MacOS Chrome and Safari, but not Firefox. I believe I'm seeing a rendering bug, but wondering if anyone might have ideas for a workaround.

Here's a greatly simplified example which demonstrates the problem in Chrome:

body {
  background: black;
  margin: 0;
}
.scale {
  transform: scale(0.703125);
}
.container {
  display: flex;
  width: 600px;
  height: 200px;
}
.column {
  flex-grow: 1;
  background:#ff0000;
}
.column:nth-child(2) {
  background: #ff3333;
}
<div class="container scale">
  <div class="column"></div>
  <div class="column"></div>
  <div class="column"></div>
</div>
<div class="container">
  <div class="column"></div>
  <div class="column"></div>
  <div class="column"></div>
</div>
Michael Benjamin
  • 265,915
  • 79
  • 461
  • 583
Ghazgkull
  • 934
  • 1
  • 6
  • 15
  • 1
    For future reference, I reported the scale transform problem to Chrome here: https://bugs.chromium.org/p/chromium/issues/detail?id=733294 – Ghazgkull Jun 15 '17 at 17:57

2 Answers2

1

Consider working around the problem with CSS box shadows.

Here's an example using the spread-radius value of the box-shadow property.

body {
  background: black;
  margin: 0;
}

.container {
  display: flex;
  height: 200px;
}

.column {
  flex-grow: 1;
  background: #ff0000;
}

.scale {
  transform: scale(0.703125);
  overflow: hidden;                 /* new */
}

.scale>div:nth-child(2) {
  box-shadow: 0 0 0 1000px #ff0000; /* new */
}

.column:nth-child(2) {
  background: orange;               /* easier to see */
}
<div class="container scale">
  <div class="column"></div>
  <div class="column"></div>
  <div class="column"></div>
</div>
<div class="container">
  <div class="column"></div>
  <div class="column"></div>
  <div class="column"></div>
</div>

Here's a detailed explanation of how this method works:

Michael Benjamin
  • 265,915
  • 79
  • 461
  • 583
  • Your explanation of the problem isn't accurate, but the idea of working around it with a shadow is a really good one. Can you update your answer to remove the idea about the decimals places being the problem? (Just thinking about anyone hitting this issue in the future. Don't wanna spread false info.) – Ghazgkull Jun 14 '17 at 17:41
  • ...and for what it's worth, a simple 1px shadow seems to be doing the trick. `box-shadow: 0 0 0 1px #ff0000;` – Ghazgkull Jun 14 '17 at 17:42
  • 1
    For anyone playing along, here's a final Codepen showing a more complicated example with this workaround applied: https://codepen.io/Ghazgkull/pen/BZLVmO – Ghazgkull Jun 14 '17 at 17:44
  • Glad it worked for you. Yes, 1px may be sufficient. But with `overflow: hidden` on the container, any excess gets clipped, so any value can work. – Michael Benjamin Jun 14 '17 at 17:46
  • `overflow: hidden` doesn't apply to the box-shadow. So 1000px actually adds a 1000px box-shadow. :) If you're interested, here's an example with the 1000px shadow... if you inspect the columns, you'll see that the box shadow extends far outside them. https://codepen.io/Ghazgkull/pen/vZXrMr – Ghazgkull Jun 14 '17 at 17:55
  • The `overflow: hidden` is supposed to go on the container, not on the child items casting the shadow. As you can see in my answer, it works as described. However, your actual set-up is quite different than the simplified version you posted in your question. Although my exact code may not be transferable, the concept is. So it's all good :-) – Michael Benjamin Jun 14 '17 at 18:19
0

One way around it could be to use a background on that element that matches one of the colors, so the background of the page doesn't show between the elements.

body {
  background: black;
  margin: 0;
}
.scale {
  transform: scale(0.703125);
}
.container {
  display: flex;
  width: 600px;
  height: 200px;
}
.column {
  flex-grow: 1;
  background:#ff0000;
}
.column:nth-child(2), .scale {
  background: #ff3333;
}
<div class="container scale">
  <div class="column"></div>
  <div class="column"></div>
  <div class="column"></div>
</div>
<div class="container">
  <div class="column"></div>
  <div class="column"></div>
  <div class="column"></div>
</div>
Michael Coker
  • 48,577
  • 5
  • 44
  • 50
  • Thanks for the idea. But in my real example, this container is an overlay and I animate the three columns dropping in sequence to reveal content beneath... so the container actually has to be transparent. – Ghazgkull Jun 14 '17 at 16:32
  • Can you show me the actual code you're using? Maybe update your post with it or create a fiddle or codepen of it? @Ghazgkull – Michael Coker Jun 14 '17 at 16:39
  • In terms of this issue with scaling the flex box container, the example code shows the problem. I'm just looking for a workaround to eliminate the gaps that appear between the scaled content divs. – Ghazgkull Jun 14 '17 at 16:50
  • @Ghazgkull did my demo not provide a workaround? Seems to me like you're saying it does with this demo, but not your actual use case. If you're trying to solve the actual use case, I need to see that code. – Michael Coker Jun 14 '17 at 16:55
  • Applying a background color behind the divs hides the problem, but it's doing it in a way that just kind of breaks the demo. I could have set the background to red instead of black, but I'm trying to make sure that the gaps are easily seen. What I'm looking for is a way to eliminate the gaps between the 3 content divs. I can make a more complicated example so you can see why it matters, but ultimately the issue is the gaps between the "columns". – Ghazgkull Jun 14 '17 at 17:13
  • If you're curious, here's a more complicated example that illustrates why changing the semantics of the HTML matters: https://codepen.io/Ghazgkull/pen/awmYpE – Ghazgkull Jun 14 '17 at 17:32