How to always center a flexible square in viewport with pure CSS?

css

Solution

I finally figured it out. The magic ingredients are the view-port units.

Given this html structure:

.l-table
  .l-table-cell
    .square

You can use this css (well actuall its scss, but you get the idea) to make it work

html,
body{
  height: 100%
}
l-table{
  background: orange;
  display: table;
  height: 100%; 
  width: 100%;
}
.l-table-cell{
  display: table-cell;
  vertical-align: middle;
  border: 2px solid black;
}
.square{
  background: red;
  margin: auto;
  @media (orientation:landscape) {
    width: 70vh;
    height: 70vh;
  }
  @media screen and (orientation:portrait) {
    width: 70vw;
    height: 70vw;
  }
}

http://codepen.io/johannesjo/pen/rvFxJ

For those who need it, there is a polyfill.

Problem

I know this question: Height equal to dynamic width (CSS fluid layout) But I want more!! I want a flexible container which has always the aspect ratio of a square but with max-height and max-width of 100% of the page (the window element) and on the top of it is always vertically and horizontally centered. Like this: ``` // Container matches height of the window // container-height = 100%; container-width = absolute-container-height -page/browser-window- - ####### - - #cont-# - - #ainer# - - ####### - --------------------- // container matches width of the window // container-width = 100%; container-height = absolute-container-width --page--- - - - - -#######- -#######- -#######- -#######- - - - - --------- ``` Is it possible to achieve this with pure css (and even better cross-browser)? Edit: I know there is calc() for css3, but due to the poor mobile browser-support, I don't want to use it. Edit2: Seems like, I didn't make myself clear enough. I need height and width of the wrapper to match the height OR the width of the window, depending on which is smaller.The square-container should never exceed the smaller value of the window-height/width. This is, how it would be done with jQuery: ``` // container/#main-wrapper has top: 50%, left: 50%, position: absolute via css $(window).resize(function () { var $ww = $(window).width(); var $wh = $(window).height(); if ($ww > $wh) { $('#main-wrapper').css({ height: $wh, width: $wh, marginTop : ($wh / 2) * -1, marginLeft : ($wh / 2) * -1 }); } else { $('#main-wrapper').css({ height: $ww, width: $ww, marginTop : ($ww / 2) * -1, marginLeft : ($ww / 2) * -1 }); } }); ```

Original source

Related problems