Search code examples
htmlcsscss-transforms

Circle divided by sectors doesn't respect overflow: hidden


I have problem with overflow on the .circle below. I need to rotate it and when angle is 90/180/270/360/450 etc the overflow is broken and some part of skewed <li> are visible.

enter image description here

I've found two workarounds - #1 slightly change angle and #2 slightly change width/height, but I want to understand the origin of issue. Why does this happen and how do I fix this properly without 0.02px/0.01deg hacks?

body {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, 1fr);
  grid-gap: 10px;
}

.circle {
  background-color: #444;
  border-radius: 50%;
  height: 150px;
  overflow: hidden;
  transform: rotate(90deg);
  width: 150px;
  display: inline-block;
  --accent: salmon;
}

li {
  background: var(--accent);
  border: 1px solid #444;
  box-sizing: border-box;
  height: 50%;
  list-style-type: none;
  position: absolute;
  right: 0px;
  top: 0px;
  transform-origin: 0px 100%;
  user-select: none;
  width: 50%
}

li:nth-child(1) {
  transform: rotate(0deg) skewY(-60deg) translate3d(0, 0, 0)
}

li:nth-child(2) {
  transform: rotate(30deg) skewY(-60deg) translate3d(0, 0, 0)
}

li:nth-child(3) {
  transform: rotate(60deg) skewY(-60deg) translate3d(0, 0, 0)
}

li:nth-child(4) {
  transform: rotate(90deg) skewY(-60deg) translate3d(0, 0, 0)
}

li:nth-child(5) {
  transform: rotate(120deg) skewY(-60deg) translate3d(0, 0, 0)
}

li:nth-child(6) {
  transform: rotate(150deg) skewY(-60deg) translate3d(0, 0, 0)
}

li:nth-child(7) {
  transform: rotate(180deg) skewY(-60deg) translate3d(0, 0, 0)
}

li:nth-child(8) {
  transform: rotate(210deg) skewY(-60deg) translate3d(0, 0, 0)
}

li:nth-child(9) {
  transform: rotate(240deg) skewY(-60deg) translate3d(0, 0, 0)
}

li:nth-child(10) {
  transform: rotate(270deg) skewY(-60deg) translate3d(0, 0, 0)
}

li:nth-child(11) {
  transform: rotate(300deg) skewY(-60deg) translate3d(0, 0, 0)
}

li:nth-child(12) {
  transform: rotate(330deg) skewY(-60deg) translate3d(0, 0, 0)
}
<div class="circle">
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</div>

<div class="circle" style="transform: rotate(90.01deg); --accent: lightseagreen;">
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</div>

<div class="circle" style="width: 150.02px; --accent: lightseagreen;">
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</div>

<p>
  original
</p>
<p>
  transform: rotate(90.01deg)
</p>
<p>
  not square - 150.02px x 150px
</p>


Solution

  • It seems to be related to the use of 3D transform. I don't know exactly why but it works fine if you remove (it's also not needed)

    body {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      grid-template-rows: repeat(2, 1fr);
      grid-gap: 10px;
    }
    
    .circle {
      background-color: #444;
      border-radius: 50%;
      height: 150px;
      overflow: hidden;
      transform: rotate(90deg);
      width: 150px;
      display: inline-block;
      --accent: salmon;
    }
    
    li {
      background: var(--accent);
      border: 1px solid #444;
      box-sizing: border-box;
      height: 50%;
      list-style-type: none;
      position: absolute;
      right: 0px;
      top: 0px;
      transform-origin: 0px 100%;
      user-select: none;
      width: 50%
    }
    
    li:nth-child(1) {
      transform: rotate(0deg) skewY(-60deg) 
    }
    
    li:nth-child(2) {
      transform: rotate(30deg) skewY(-60deg) 
    }
    
    li:nth-child(3) {
      transform: rotate(60deg) skewY(-60deg) 
    }
    
    li:nth-child(4) {
      transform: rotate(90deg) skewY(-60deg) 
    }
    
    li:nth-child(5) {
      transform: rotate(120deg) skewY(-60deg) 
    }
    
    li:nth-child(6) {
      transform: rotate(150deg) skewY(-60deg) 
    }
    
    li:nth-child(7) {
      transform: rotate(180deg) skewY(-60deg) 
    }
    
    li:nth-child(8) {
      transform: rotate(210deg) skewY(-60deg) 
    }
    
    li:nth-child(9) {
      transform: rotate(240deg) skewY(-60deg) 
    }
    
    li:nth-child(10) {
      transform: rotate(270deg) skewY(-60deg) 
    }
    
    li:nth-child(11) {
      transform: rotate(300deg) skewY(-60deg) 
    }
    
    li:nth-child(12) {
      transform: rotate(330deg) skewY(-60deg) 
    }
    <div class="circle">
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
    </div>