Hexagon grid shapes (via transform) produces glitc

2019-04-14 15:26发布

问题:

I need a flexible, big hexagon grid, ideally

  • in pure CSS (no pre-processing or JS shenanigans)
  • hexagon dimensions in percent, so everything is nice and responsive

The solution I hacked together from this great answer is elegant and all, but produces really ugly glitches in Safari (10.1 on macOS 10.12.4), when zooming in our out (via pinch to zoom or CMD +/-). The edges are all screwed up, and it takes a while to clear up, sometimes it doesn't clear up at all.

html,
  body {
    margin: 0;
    padding: 0;
  }

  #grid {
    /*otherwise there's some stuff running over to the right corner */
    /*TODO this stuff really should not be there*/
    overflow: hidden;
    background-color: lightgrey;
    width: 100vw;
    height: 100vh;
    position: relative;
    /*other gradients: #2196f3, #f44336 or: #d3959b, #bfe6ba (best) or: #5fc3e4, #e55d87*/
    background: -webkit-linear-gradient(left, #bfe9ff, #ff6e7f);
    /* For Safari 5.1 to 6.0 */
    background: -o-linear-gradient(left, #bfe9ff, #ff6e7f);
    /* For Opera 11.1 to 12.0 */
    background: -moz-linear-gradient(left, #bfe9ff, #ff6e7f);
    /* For Fx 3.6 to 15 */
    background: linear-gradient(left, #bfe9ff, #ff6e7f);
    /* Standard syntax (must be last) */
  }
  /**
   Hexagon Construction
   hexagons are here constructed by https://codepen.io/elbarto84/pen/wrcob
   For more reasons / alternatives, see here: https://github.com/maxheld83/accio/issues/84
   */

  .hex {
    position: relative;
    float: left;
    overflow: hidden;
    padding: calc(100% / 6.5 / 2);
    -webkit-transform:  rotate(0deg)
                        skewY(30deg)
                        scaleX(0.866025403784439); /* sqrt(3)/2 */
    -ms-transform:      rotate(0deg)
                        skewY(30deg)
                        scaleX(0.866025403784439); /* sqrt(3)/2 */
    transform:          rotate(0deg)
                        skewY(30deg)
                        scaleX(0.866025403784439); /* sqrt(3)/2 */
    margin-top: calc(100% / 6.5 / 1.732050807568877 * -1/6.5); /* sqrt(2) */
    opacity: 0.4;
  }

  .hidden {
    visibility: hidden;
  }

  .hex:before, .hex:after {
    position: absolute;
    /* 86.6% = (sqrt(3)/2)*100% = .866*100% */
    top: 6.7%;
    right: 0;
    bottom: 6.7%;
    left: 0; /* 6.7% = (100% -86.6%)/2 */
    -webkit-transform:  scaleX(1.154700538379252) /* 1.155 = 2/sqrt(3) */
                        skewY(-30deg)
                        rotate(-30deg);
    -ms-transform:      scaleX(1.154700538379252) /* 1.155 = 2/sqrt(3) */
                        skewY(-30deg)
                        rotate(-30deg);
    transform: scaleX(1.154700538379252) /* 1.155 = 2/sqrt(3) */
               skewY(-30deg)
               rotate(-30deg);
    background-color: white;
    content: '';
  }

  .hex-row {
    position: relative;
  }

  .hex-row:first-child {
    /*this weirdly acts only on first row and moves it down again to normal position*/
    margin-top: calc(100% / 6.5 / 1.732050807568877 * 1/6.5); /* sqrt(2) */
  }

  .hex-row:nth-child(even) {
    left: calc(100% / 13);
  }
<body>
  <div id="grid">
    <div class="hex-row">
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
    </div>
    <div class="hex-row">
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex hidden"> </div>
      <div class="hex"> </div>
    </div>
    <div class="hex-row">
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
    </div>
    <div class="hex-row">
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
    </div>
    <div class="hex-row">
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
      <div class="hex"> </div>
    </div>
  </div>

</body>


Is this somehow salvageable or is something fundamentally wrong with this design?

I can basically use whatever design I want, I'd just prefer a single-div solution, and the design needs to be responsive (ideally in percent).