6

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

        });
    }
});
Community
  • 1
  • 1
hugo der hungrige
  • 12,382
  • 9
  • 57
  • 84

4 Answers4

4

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.

hugo der hungrige
  • 12,382
  • 9
  • 57
  • 84
1

EDIT: Since writing the below, I appealed on Twitter and got a response from Brian Johnson. He came up with a solution that isn't 100% perfect semantically, but it's pretty damn good and I'll certainly be using it. He asked that I share it in this discussion. LINK

I'm having the same issue right now and I was just typing out pretty much this exact question, so although I can't answer it, I wanted to share what I've found so far in case it helps anyone come up with the final solution.

To clarify, I need my content to fit into a square which fills 60% of the browser's width if portrait or 60% of the height if landscape.

However, this square must never exceed the width or height of the viewport.

Using the technique found here I've managed to create the fluid square, but it still exceeds the viewport when landscape.

width: 60%;
height:0;
padding-bottom: 60%;

Link to Codepen example

I have tried flipping that technique on it's side for landscape but that doesn't work. (You can see that code in the above example, noted out.)

I can't use a simple max-height property because the height is being worked out by the padding-bottom property.

I've thought about adding an extra div as someone else has suggested (C-Link's post is really interesting) but I can't work out how I'd get it to do what we want it do here.

suryanaga
  • 3,728
  • 11
  • 36
  • 47
  • Thats really cool stuff. I'll try to modify it according to my needs. Thx! – hugo der hungrige Apr 07 '13 at 01:28
  • Did this answer your question? If you could accept it, that would be great :) – suryanaga Apr 10 '13 at 10:25
  • Hey sanjaypoyzer, I'll give it another one or two weeks, as it is quite good, but not perfect (It doesn't work with resizing the page). Also it would be cool, if you could add a little more than a link to your answer or even post a new one. – hugo der hungrige Apr 20 '13 at 00:24
0

How about if you take the earlier concept a step further with a similar div as a container. The container has an added max-height & width. I tried this and the container does not throw a scrollbar at me. It is quite interesting in behavior I must say myself. Does this work for you?

<div id="container">
    <div id="centered">A DIV</div>
</div>

    #container {
    top:0;
    bottom:0;
    right:0;
    left:0;
    margin:auto;
    position:absolute;
    width:200px;
    height:200px;
    max-width:100%;
    max-height:100%;
    background:#00f;
    padding:0;
}
#centered {
    background: green;
    bottom: 0;
    height: 80px;
    left: 0;
    margin: auto;
    position: absolute;
    top: 0;
    right: 0;
    width: 80px;
}

updated fiddle: http://jsfiddle.net/djwave28/mBBJM/96/

Daniel
  • 4,816
  • 3
  • 27
  • 31
0

html

<div id="outer">
<div id="inner">YOUR CONTENTS HERE
</div>
</div>

css

html, body{
height: 100%;
}
#outer{
max-height: 100%;
max-width: 100%; 
position: relative; 
height: 100%;
}
#inner{
position: relative; 
top: 50%; 
margin-top: -50% auto auto auto; 
background: red; 
text-align: center; 
color: yellow;
}

See this fiddle.

Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231