htmlcsscss-position

Concentric rings (similar to a radar) using CSS


I'm doing a flask battleship game. Started with the visuals, and have this HTML/CSS structure:

:root {
  background-color: black;
}

.boards-container {
    display: flex;
    justify-content: space-evenly;
    align-items: center;
}

/* ------------------GAME BOARD----------------------------------------- */

.game-board {
    display: grid;
    grid-template-columns: 50px repeat(10, 50px);
    grid-template-rows: 50px repeat(10, 50px);
    gap: 1px;
    /* position: relative; -------- do I really need it? apparently not unless I have children with position: absolute?*/
    z-index: 1;    
    grid-column: 2 / span 10;
    grid-row: 2 / span 10;
    color: greenyellow;
}

.game-board-corner {
    grid-row: 1;
    grid-column: 1;
}

.game-board-col-label {
    grid-row: 1;
}

.game-board-row-label {
    grid-column: 1;
}

.game-board-grid {
    grid-column: 2 / span 10;
    grid-row: 2 / span 10;
    display: grid;
    grid-template-columns: repeat(10, 50px);
    grid-template-rows: repeat(10, 50px);
    gap: 1px;
}


.game-board-cell {
    background-color: transparent;
    border: 1px greenyellow;
    position: relative;
    overflow: visible;
}

.game-board-cell:hover {
    background-color: greenyellow;
}

/* ------------------RADAR---------------------------------- */
.radar-circle-container {
    grid-column: 2 / span 10;
    grid-row: 2 / span 10;
    width: 100%; 
    height: 100%; 
    position: relative;
    z-index: 1;
}

.radar-circle {
    border: 2px solid greenyellow;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.circle1{width: 100%; height: 100%;}
.circle2{width: 75%; height: 75%}
.circle3{width: 75%; height: 75%;}
.circle4{width: 75%; height: 75%;}
  <main class="boards-container">
    <section class="game-board">
      <!-- game board grid -->
      <section class="radar-circle-container">
        <div class="radar-circle circle1">
          <div class="radar-circle circle2">
            <div class="radar-circle circle3">
              <div class="radar-circle circle4"></div>
            </div>
          </div>
        </div>
      </section>
      <div class="game-board-grid">
        <div class="game-board-cell"></div>
        <div class="game-board-cell"></div>
      </div>
    </section>
  </main>

About the spacing between the rings - it is not quite even (if I understand correctly because the width is then 75% of the direct parent and not of the main container). How can I correct that, and what would be the cleanest way to do this? I'm still not sure about using nested divs - is there a better if all the rings are children of one element?

To clarify, I'm using the radar-circle-container because the main battleship grid is going to be directly on top, leaving out the labeling for rows/columns.

Thanks!


Solution

  • I would suggest: repeating-radial-gradient

    Here's a simple and responsive radar example:

    * { margin: 0; }
    
    .radar-circle {
      --bgColor: #000;
      --lineColor: yellowgreen;
      --lineWidth: 0.65%;
      --lineEvery: 18%;
    
      position: relative;
      overflow: hidden;
      width: 100dvmin; /* Set as desired */
      aspect-ratio: 1;
      border-radius: 50%;
      
      background: var(--bgColor) repeating-radial-gradient(
        circle at 50%,
        var(--lineColor),
        var(--lineColor) var(--lineWidth),
        #0000 var(--lineWidth),
        #0000 var(--lineEvery)
      );
    }
    <div class="radar-circle"></div>

    And here's a demo if you want to animate the radar:

    * { margin: 0; }
    
    .radar-circle {
      --bgColor: #000;
      --lineColor: yellowgreen;
      --lineWidth: 0.65%;
      --lineEvery: 18%;
    
      position: relative;
      overflow: hidden;
      width: 100dvmin; /* Set as desired */
      aspect-ratio: 1;
      border-radius: 50%;
    
      background: var(--bgColor) repeating-radial-gradient(
        circle at 50%,
        var(--lineColor),
        var(--lineColor) var(--lineWidth),
        #0000 var(--lineWidth),
        #0000 var(--lineEvery)
      );
    
      &::after {
        content: "";
        position: absolute;
        inset: 0;
        background: conic-gradient(
          from 0 at 50%,
          #0000 320deg,
          color-mix(in srgb, var(--lineColor), #0000 20%) 360deg
        );
        animation: rotate 6s linear infinite;
      }
    }
    
    @keyframes rotate {
      to { rotate: 1turn;}
    }
    <div class="radar-circle"></div>