45

I need to create a DIV where width=height, and height=100% of the viewport (which, obviously, is variable).

In other words, a perfectly square DIV that calculates it's dimensions based on the height of the viewport. Elements within that DIV will take their dimensions as percentages of the parent-DIV's height & width.

It seems to me like this should be simple to do in CSS, but I've gotten stuck with it! Any pointers would be much appreciated.

web-tiki
  • 99,765
  • 32
  • 217
  • 249
Ila
  • 3,528
  • 8
  • 48
  • 76

8 Answers8

117

There is a neat trick using pure css that i stumbled upon:

#square {
width: 100%;
height: 0;
padding-bottom: 100%;
}

http://blog.brianjohnsondesign.com/2013/maintain-aspect-ratio-for-html-element-using-only-css-in-a-responsive-design/

starball
  • 20,030
  • 7
  • 43
  • 238
Tomasz Kowalczyk
  • 1,951
  • 2
  • 16
  • 18
  • 5
    Feels super kludgy, BUT seems to be working 100% (ha ha) so far. +1 – demaniak Oct 06 '13 at 18:23
  • 6
    This is useful but does not do what the original question asks for. This will not maximize the height of the element to fill the viewport. – Frug Apr 25 '14 at 01:36
  • 5
    @MKYung This cannot be the accepted answer as it does not answer the question. This answer sets height=width when it was explicitly asked the opposite to set width=height. – BenSwayne Feb 27 '15 at 02:43
  • Too bad it does not work if one wishes to mix it with Bootstrap. – Paweł Mach Aug 11 '15 at 13:37
  • @Werd this isn't the correct answer to the question. The width isn't calculated **according to the height** as the question asks. If you want ways to keep aspect ratio **according to the width** of the element please see [How to maintain the aspect ratio of a div using only CSS](http://stackoverflow.com/questions/1495407/how-to-maintain-the-aspect-ratio-of-a-div-using-only-css) – web-tiki Oct 14 '15 at 14:35
34

CSS only solution : vh units

To make the element resize according to the height of the viewport you can use vh units :

vh : 1/100th of the height of the viewport. [source MDN]


Example:

body{margin:0;}

div{
    background:gold;
    height:100vh;
    width:100vh;
}
<div></div>

Fiddle DEMO

This will make the width and height of the element equal to the height of the viewport.


Bowser support for vh units is IE9+. More info here

web-tiki
  • 99,765
  • 32
  • 217
  • 249
  • 3
    This is exactly what I was looking for! It is a lot less hacky than other CSS solutions and doesn't use JavaScript. – Oliver Cooper Sep 13 '14 at 05:02
  • This is a cool solution so +1 but it has a limitation. For portrait viewports where width is smaller than height, `width: 100vh` will move content out of the screen. It might looks cutting. – Mohammad Usman Dec 30 '16 at 06:34
  • 2
    @MuhammadUsman for your case you can use the vmin unit. It is the smallest between width and height of viewport. – web-tiki Dec 30 '16 at 09:34
17

You can do this with jquery (or pure javascript if you prefer).

With jquery:

<div id="square">
</div>

$(document).ready(function(){
  var height = $(window).height();
  $('#square').css('height', height);
  $('#square').css('width', height);
});
Ant
  • 3,877
  • 1
  • 15
  • 14
  • Oops, hit enter too soon. For anyone else wanting to know, you can also make width a value calculated from height, for instance (height*1.2)- excellent! Now to figure out how to have this degrade gracefully when people don't have javascript enabled! – Ila Jul 20 '11 at 15:42
4

CSS3 has a way of doing this using vw, viewport width, and vh, viewport height. Using these measures, 100vw is the entire width of the viewport, and 100vh is the entire height. More information about relative css3 values and units here.

As of writing this, the only support however is for Internet Explorer 9, so this is probably not what you're looking for, but is something good to keep in mind when future support follows.

Vap0r
  • 2,588
  • 3
  • 22
  • 35
  • And oh boy, did it ever. Now [almost] every major browser supports vw and vh. https://caniuse.com/#feat=mdn-api_css_vw – ilsloaoycd May 22 '20 at 03:23
3

One additional trick I came up with to help partially solve this problem, for anybody who stumbles across this page... Run the following code in your page's onload event:

$('body').css('font-size',$(window).height()/100)

This means the css "em" unit is equal to 100th of your page height- You can now arbitrarily use this in your css file to size any item relative to your viewport height. This is more generic than the other solutions listed here- And most likely you want to size all of the elements of your page to take into account your viewport height. For instance, if you now want to create your square you can just write:

#square{width:100em;height:100em}

Of course, you'll also have to take this into account for any text on your page (since this trick affects the font size)

drcode
  • 3,287
  • 2
  • 25
  • 29
1

This is interesting...

For those who may be looking for a pure CSS way to contain a square div with the maximum dimensions:

The key takeaway here is that you set max-width and max-height while setting width and height to the opposite values.

HTML

<div>
</div>

CSS

html, body {
  margin: 0;
  padding: 0;
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
}

div {
  background-color: red;
  width: 100vh;
  height: 100vw;
  max-width: 100vw;
  max-height: 100vh;
}

Live running example: https://jsfiddle.net/resistdesign/szrv5o19/

Resist Design
  • 4,462
  • 3
  • 22
  • 35
0

I don't know if I'm getting this right, but if you want to set it to 100% oh the height of the viewport, you could easily do this in css:

.stuff {
  background:#DDD;
  display:inline-block;
  height: 100vh;
  width : 100vh;
}

You could check it out here

desto
  • 1,047
  • 3
  • 14
  • 19
0

You could use Javascript and get the screen size. After which you could set width and height accordingly.

window.screen.width, and window.screen.height should work.

You could then use this information and generate a tiny bit of CSS for the page to be displayed accordingly.