Skip to content
Advertisement

It’s possible to inscribed a child with equal width and height, not exceeding it’s parent, using only CSS?

My idea is to get the child object (@example the “.moon”) to have the equal values of height and width, and not exceed the width or the height of the parent (@example the “.sun”).

So when the parent width is bigger than its height, the child’s value for width and height is the smaller one, the parent height.

In the same way when the parent height is bigger than its width, the child’s value for width and height is the smaller one, the parent width.

I mean inscribe an object inside the container but only using CSS.

The “padding-top” trick only works when the parent width is bigger than its height. And the “object-fit” only work for images I guess.

I did reference the circles, just to make it clear that the sides have to have the same value (height and width), also that the child can contain elements.

I know it can be perfectly done with JavaScript getting the parent height and width, comparing the smaller one and set it to the child height and width, I made it with jQuery, but wanna know if its possible to achieve it without jQuery or JavaScript, pure CSS.

Try the example and resizing the screen.

var pw = ""; var ph = ""; var cw = ""; var ch = "";

$( window ).resize(function() { 
  
pw = $('.sun').width();
ph = $('.sun').height();
cw = $('.moon').width();
ch = $('.moon').height();
  if(pw > ph){
  $('.moon').css({
      'width': ph + 'px',
      'height': ph + 'px'
  });
  }
  else {
  $('.moon').css({
      'width': pw + 'px',
      'height': pw + 'px'
  });
  }
});

function mySUNction() {
   
pw = $('.sun').width();
ph = $('.sun').height();
cw = $('.moon').width();
ch = $('.moon').height();
  if(pw > ph){
  $('.moon').css({
      'width': ph + 'px',
      'height': ph + 'px'
  });
  }
  else {
  $('.moon').css({
      'width': pw + 'px',
      'height': pw + 'px'
  });
  }
}
* {
  padding: 0;
  margin:0;
}
.sky {
  position: absolute;
  width: 100%;
  height: 100%;
  background: purple;
  display: flex;
  justify-content: center;
  align-items: center;
}
.sun {
  position: relative;
  width: 33%;
  /*padding-top: 33%;*/
  height: 33%;
  background: yellow;  
  display: flex;
  justify-content: center;
  align-items: center;
}
.moon {
  background: blue;  
  /*object-fit: fill;*/
  /*border-radius: 50%;*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<div class="sky">
<div class="sun">
<div class="moon"></div>
</div>
<div>
<button onclick="mySUNction()">Click me</button>

Advertisement

Answer

If you only want the visual, it can be done with gradient:

body {
  margin:0;
}
.sky {
  height: 100vh;
  background: purple;
  display: flex;
  justify-content: center;
  align-items: center;
}

.sun {
  position: relative;
  width: 33%;
  height: 33%;
  background: 
   radial-gradient(circle closest-side,blue 99%,transparent 100%)
   yellow;
}
<div class="sky">
  <div class="sun">
  </div>
</div>

The same logic you apply with a mask and you can use any background:

body {
  margin:0;
}
.sky {
  height: 100vh;
  background: purple;
  display: flex;
  justify-content: center;
  align-items: center;
}

.sun {
  position: relative;
  width: 33%;
  height: 33%;
  background: 
   yellow;
}

.sun > div {
  width:100%;
  height:100%;
  background:url(https://picsum.photos/id/1074/800/800) center/contain;
  -webkit-mask:radial-gradient(circle closest-side,blue 99%,transparent 100%);
          mask:radial-gradient(circle closest-side,blue 99%,transparent 100%);
}
<div class="sky">
  <div class="sun">
    <div></div>
  </div>
</div>

You can also consider the use of min()/max() like below

body {
  margin:0;
}
.sky {
  height: 100vh;
  background: purple;
  display: flex;
  justify-content: center;
  align-items: center;
}

.sun {
  position: relative;
  width: 33vw;
  height: 33vh;
  background: yellow;
  display: flex;
}

.sun > div {
  margin:auto;
  height:min(100%,33vw);
  width:min(100%,33vh);
  background:url(https://picsum.photos/id/1074/800/800) center/contain;
}
<div class="sky">
  <div class="sun">
    <div></div>
  </div>
</div>

Also like below:

body {
  margin:0;
}
.sky {
  height: 100vh;
  background: purple;
  display: flex;
  justify-content: center;
  align-items: center;
}

.sun {
  position: relative;
  width: 33vw;
  height: 33vh;
  background: yellow;
  display: flex;
}

.sun > div {
  margin:auto;
  display: flex;
  width:min(100%,33vh);
  background:url(https://picsum.photos/id/1074/800/800) center/contain;
}
.sun > div::before {
  content:"";
  padding-top:100%;
}
<div class="sky">
  <div class="sun">
    <div></div>
  </div>
</div>

Related question if you want the circumscribed circle: Make a perfect circle around a div of variable height

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement