skip to Main Content

I am making these two shapes with dots within them. One is a rectangle, the other a circle. Within these shapes I have made some dots, and I want these dots to render within and relative to the shapes. I cannot figure out why the dots inside the circle are outside instead. And how do I make them closer together vertically, and yet act relative to the shapes?

The purpose is to use input from the user where they decide the width and height of the shapes, and for the dots closer to the middle inside each shape.

JSFiddle Link: https://jsfiddle.net/kqgv6m94/1/

.rectangle {
  width: 200px;
  height: 100px;
  background: gray;
  position: relative;
}


.oval {
  width: 200px;
  height: 100px;
  background: gray;
  border-radius: 50%;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
}

.bolt:before,
.bolt:after {
  content: "";
  position: absolute;
  height: 100%;
  width: 30%;
  top: 0px;
  background-image: radial-gradient(circle at center, red 5px, transparent 5px), radial-gradient(circle at center, black 5px, transparent 5px);
  background-size: 20px 20px;
  background-position: top center, bottom center;
  background-repeat: no-repeat;
}

.bolt:before {
  left: 0px;
}

.bolt:after {
  right: 0px;
}
<div id="rectangle" class="rectangle">
  <div>
    <div class="bolt">

    </div>
  </div>
</div>
<hr>
<div>
  <div id="oval" class="oval">
    <div class="bolt">

    </div>
  </div>

I tried to use flexbox, but to no avail.
I then tried to create the dots in their own containers in hopes of inheriting properties.
I also tried to ‘force’ the dots into place, but if I change window size / new height and weight values I get new dot-positions.

5

Answers


  1. While the .oval is rounded, it’s box is still the same rectangle as the .rectangle has.

    If you want your dots be inside the circle, make .bolt be a smaller rectangle in that circle

    .shape {
      width: 200px;
      height: 100px;
      background: gray;
      
      display: flex;
        align-items: center;
        justify-content: center;
    }
    
    .bolt {
      outline: 3px solid blue;
      height: 100%;
      width: 100%;
      position: relative;
    }
    .oval > .bolt {
      /* choose your numbers */
      height: 75%;
      width: 75%;
    }
    
    .rectangle {}
    
    .oval {
      border-radius: 50%;
      position: absolute;
    }
    
    .bolt:before,
    .bolt:after {
      content: "";
      position: absolute;
      height: 100%;
      width: 20px;
      top: 0px;
      background-image: radial-gradient(circle at center, red 5px, transparent 5px), radial-gradient(circle at center, black 5px, transparent 5px);
      background-size: 20px 20px;
      background-position: top center, bottom center;
      background-repeat: no-repeat;
    }
    
    .bolt:before {
      left: 0px;
    }
    
    .bolt:after {
      right: 0px;
    }
    width: <input type="range" max="400" calue="200" oninput="document.querySelectorAll('.shape').forEach(e=>e.style.width = event.target.value+'px')">
    height: <input type="range" max="200" value="100" oninput="document.querySelectorAll('.shape').forEach(e=>e.style.height = event.target.value+'px')">
    <hr>
    <div class="shape rectangle">
      <div class="bolt"> </div>
    </div> 
    <hr>
    <div class="shape oval">
      <div class="bolt"> </div>
    </div>
    <hr>
    Login or Signup to reply.
  2. first why the dots inside the circle is outside?

    your point is a background image, its height is 100%, and its width is 30%, so it actually looks like this:enter image description here

    so when add css with .oval with border-radius: 50%, the oval div change to circle. But the dot will not follow the change, stay the same. And dot will look like outside circle.

    If you want to make them closer together vertically, you can change the before and after background-size: 40px 40px, or you can set left and right to make them closer horizontally.
    enter image description here

    Also you can set the .bolt:before, .bolt:after width lager like 50% to get what you want.

    Login or Signup to reply.
  3. The border-radius rounds the corners of an element’s outer border edge, but does not affect the area it takes on DOM. When you apply border-radius it will change the position of border and background but not the content and area taken by element.

    As you have given boder-radius: 50%, it start rounding corners from center, hence the children at the edge goes of the circle.

    To make circle inside the oval, you can update the background-position of :before and after

    .oval .bolt:before,
    .oval .bolt:after {
          background-position: top 25% center, bottom 25% center;
     }
    

    Complete Example :

    .rectangle {
      width: 200px;
      height: 100px;
      background: gray;
      position: relative;
    }
    
    
    .oval {
      width: 200px;
      height: 100px;
      background: gray;
      border-radius: 50%;
      position: relative;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .bolt:before,
    .bolt:after {
      content: "";
      position: absolute;
      height: 100%;
      width: 30%;
      top: 0px;
      background-image: radial-gradient(circle at center, red 5px, transparent 5px), radial-gradient(circle at center, black 5px, transparent 5px);
      background-size: 20px 20px;
      background-position: top center, bottom center;
      background-repeat: no-repeat;
    }
    
    .bolt:before {
      left: 0px;
    }
    
    .bolt:after {
      right: 0px;
    }
    
    .oval .bolt:before,
    .oval .bolt:after {
      background-position: top 25% center, bottom 25% center;
    }
    <div id="rectangle" class="rectangle">
      <div>
        <div class="bolt">
    
        </div>
      </div>
    </div>
    <hr>
    <div>
      <div id="oval" class="oval">
        <div class="bolt">
    
        </div>
      </div>
    Login or Signup to reply.
  4. I understand your issue. The problem is that your current code doesn’t handle the positioning of the dots inside the circle correctly. I have made some changes to your code to fix the issue and to achieve your desired behavior.

    .rectangle {
      width: 200px;
      height: 100px;
      background: gray;
      position: relative;
    }
    
    .oval {
      width: 200px;
      height: 100px;
      background: gray;
      border-radius: 50%;
      position: relative;
    }
    
    .dot {
      position: absolute;
      background-image: radial-gradient(circle at center, red 5px, transparent 5px), radial-gradient(circle at center, black 5px, transparent 5px);
      background-size: 20px 20px;
      background-position: top center, bottom center;
      background-repeat: no-repeat;
    }
    
    .rectangle .dot {
      width: 30%;
      height: 100%;
      top: 0;
    }
    
    .oval .dot {
      width: 15%;
      height: 50%;
      top: 25%;
    }
    
    .dot.left {
      left: 0;
    }
    
    .dot.right {
      right: 0;
    }
    
    <div id="rectangle" class="rectangle">
      <div class="dot left"></div>
      <div class="dot right"></div>
    </div>
    <hr>
    <div id="oval" class="oval">
      <div class="dot left"></div>
      <div class="dot right"></div>
    </div>
    
    Login or Signup to reply.
  5. Assuming that the ellipse is just a stretched circle, the largest rectangle that could be inscribed inside it is a√2 × b√2 where a and b are the lengths of semi-axes (ref).

    Following is a pure CSS solution with no hard coding:

    .oval {
      background-color: gray;
      border-radius: 50%;
      position: relative;
    }
    /* tests */
    .oval-1 {
      width: 200px;
      height: 100px;
    }
    .oval-2 {
      width: 100px;
      height: 200px;
    }
    .oval-3 {
      width: 200px;
      height: 200px;
    }
    /* largest rectangle inside the ellipse */
    .oval::after {
      content: "";
      background-color: rgba(255, 255, 255, .5);
      /* center the div */
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      margin: auto;
      /* use the formula */
      width: calc(50% * 1.4142135623730951);
      height: calc(50% * 1.4142135623730951);
      /* add the dots */
      background-image:
        radial-gradient(closest-side at center, #F00 100%, transparent 100%),
        radial-gradient(closest-side at center, #F00 100%, transparent 100%),
        radial-gradient(closest-side at center, #000 100%, transparent 100%),
        radial-gradient(closest-side at center, #000 100%, transparent 100%);
      background-size: 20px 20px;
      background-position:
        top left,
        top right,
        bottom left,
        bottom right;
      background-repeat: no-repeat;
    }
    <div class="oval oval-1"></div>
    <div class="oval oval-2"></div>
    <div class="oval oval-3"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search