Let's say I've got a div that has a width of 50% of the body. How do I make its height equal to that value? So that when the browser window is 1000px wide, the div's height and width are both 500px.
-
it can't be done in straight css. the js solution is simple though. – Ben Lee Apr 08 '12 at 12:40
-
7It can actually be done with CSS alone. See Fadi's answer. – Adam Waite Feb 11 '13 at 22:58
-
Another approach, which also works for setting the width in terms of the height (unlike the padding approach), can be found [here](http://stackoverflow.com/questions/6148012/setting-element-width-based-on-height-via-css) – Kevin Wheeler Jul 11 '15 at 01:11
-
This is not a duplicate of the linked question. This question specifically asks about basing the square on height, not width - a much different problem. – Sandy Gifford Dec 01 '16 at 20:59
-
**Pure JS approach**: `el=document.getElementById('id_div')` `el.style.height=el.offsetWidth+"px"` This will give u a perfect square. Make your JS file execute this code when page loads -- `window.onload` – Aseem Apr 26 '19 at 22:11
-
Assuming 100% of the width of the div in question is the same as 100vw, why not just use vw? Is there a good reason? – John Miller Dec 19 '22 at 03:09
4 Answers
This can actually be done with only CSS, but the content inside the div must be absolutely positioned. The key is to use padding as a percentage and the box-sizing: border-box
CSS attribute:
div {
border: 1px solid red;
width: 40%;
padding: 40%;
box-sizing: border-box;
position: relative;
}
p {
position: absolute;
top: 0;
left: 0;
}
<div>
<p>Some unnecessary content.</p>
</div>
Adjust percentages to your liking. Here is a JSFiddle
-
5I understand that `width: 40%` is 40% of the parent element, but what is the `padding: 40%` in relation to? – Ryan Mar 05 '13 at 16:49
-
1The padding is what gives the box equal width and height. It 'inflates' the inside of the box with padding. – Fadi Apr 25 '13 at 23:44
-
3Firefox seems to have an issue on that method, but it's simple to fix. If you want a 50% box, you need "padding: 25%;". 25% on each side. – jurihandl Aug 15 '13 at 07:39
-
At least in Chrome, the width value is almost unnecessary. It basically needs to be anything that's not 100% - the actual size of the box is set by the padding. (And Chrome exhibits the same behavior as jurihandl mentioned for Firefox.) – Ben Visness Jun 10 '14 at 15:50
-
@BenjaminVisness You're mostly correct in that the width can be any value, but the value can't be left out or the width will default to 100%. – Fadi Jun 23 '14 at 16:43
-
@Fadi That's why I said it was "almost" unnecessary - the value is irrelevant, but it much be present (and not 100%) in order for this to work. – Ben Visness Jun 23 '14 at 18:49
-
-
-
I would say that width must not be more than DOUBLE of padding, as if it was, it would be larger than its padding-computed width. checked in chrome – Rayjax Sep 29 '14 at 13:52
-
97I hate how you can do 3D transforms, shadows, rounded corners, etc easily in CSS, but to have a square div requires a hack... – Jonathan. Sep 29 '14 at 17:45
-
I vote this as the best answer. I need a 4/3 ratio for photos and wanted a purely CSS solution. Much appreciated. (So I'll tweak the padding for my use. padding: 37.5% 50%;) – Andrew Leyva Oct 10 '14 at 15:06
-
3@Ryan the `padding: 40%` is in relation to the width of the element (including padding-top and padding-bottom). Definitely surprised me, there's a good explanation on [another question](http://stackoverflow.com/a/10441480/1314762). – Don McCurdy Jul 07 '15 at 18:54
-
the problem is the width percentage set is not what we expect du to padding acting on it. For example, I couldn't use this technique for three inline-block divs with 33% width... As @implum suggested, setting padding-top instead of padding works better. – TrtG Nov 04 '15 at 11:03
-
-
-
1@DonMcCurdy That is actually incorrect. The `padding: 40%` is in relation to the with of the *containing* element, not the element itself. So if the container is `1000px` wide, and `padding-bottom: 40%` is applied to its direct descendant, the calculated value of padding will be `400px` regardless of the width of the descendant. – Ejaz Apr 29 '20 at 16:05
This can be done with a CSS hack (see the other answers), but it can also be done very easily with JavaScript.
Set the div's width to (for example) 50%, use JavaScript to check its width, and then set the height accordingly. Here's a code example using jQuery:
$(function() {
var div = $('#dynamicheight');
var width = div.width();
div.css('height', width);
});
#dynamicheight
{
width: 50%;
/* Just for looks: */
background-color: cornflowerblue;
margin: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="dynamicheight"></div>
If you want the box to scale with the browser window on resize, move the code to a function and call it on the window resize event. Here's a demonstration of that too (view example full screen and resize browser window):
$(window).ready(updateHeight);
$(window).resize(updateHeight);
function updateHeight()
{
var div = $('#dynamicheight');
var width = div.width();
div.css('height', width);
}
#dynamicheight
{
width: 50%;
/* Just for looks: */
background-color: cornflowerblue;
margin: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="dynamicheight"></div>

- 56,214
- 69
- 228
- 381
-
31You don't need javascript for that. You can do as mentioned below: height: 0px; width: 40%; padding-top: 40%; – Chris Andersson Feb 25 '14 at 08:50
-
As mentioned above using JavaScript is totally unnecessary and presents problems such as FOUC or worse, disabled JS (nothing will happen). Go with the CSS method. – Bill Nov 05 '14 at 14:35
-
1@Billy: "totally unnecessary"? You're forgetting that the CSS method below has some tight restrictions. The Javascript method will work in all scenarios where Javascript is enabled. – Hubro Nov 05 '14 at 14:40
-
-
@Billy: At first glance, the div appears to need a set width and absolutely positioned content. Also, taking a look at the comments, the results appear to vary between browsers – Hubro Nov 05 '14 at 15:06
-
The OP specifically said he wants a div with a set width to have the height reflect that.. The most upvoted answer (which still works without box-sizing: border-box) only uses standard CSS and will work everywhere. No comment on the FF issue though.. :P – Bill Nov 05 '14 at 15:34
<div><p>some unnecessary content</p></div>
div{
border: 1px solid red;
width: 40%;
padding: 40%;
box-sizing: border-box;
position: relative;
}
p{
position: absolute;
top: 0;
left: 0;
}
For this to work i think you need to define the padding to ex. top? like this:
<div><p>some unnecessary content</p></div>
div{
border: 1px solid red;
width: 40%;
padding-top: 40%;
box-sizing: border-box;
position: relative;
}
p{
position: absolute;
top: 0;
left: 0;
}
anyways, thats how i got it to work, since with just padding all arround it would not be a square.

- 231
- 2
- 7
-
Thank you ! The above answer did render a square but it was not 40% width of its parent. – TrtG Nov 04 '15 at 11:08
I made a CSS approach to this that is sized by the viewport width, but maxes out at 100% of the viewport height. It doesn't require box-sizing:border-box
. If a pseudo element cannot be used, the pseudo-code's CSS can be applied to a child. Demo
.container {
position: relative;
max-width:100vh;
max-height:100%;
margin:0 auto;
overflow: hidden;
}
.container:before {
content: "";
display: block;
margin-top: 100%;
}
.child {
position: absolute;
top: 0;
left: 0;
}
Support table for viewport units
I wrote about this approach and others in a CSS-Tricks article on scaling responsive animations that you should check out.

- 24,871
- 12
- 85
- 147