0

I'm looking for a solution where I have a div that grows dynamically depending on the content while maintaining a 1:1 aspect ratio. I've found many solutions where the size of the box is relative to the pages width rather than its content (like this). IE8 compatibility would be a big plus! A JavaScript solution would work too, but I'd prefer a CSS solution.

Thanks a bunch!

johnny
  • 8,696
  • 6
  • 25
  • 36
  • 1
    Do you want to expand the width to match the height, or vice versa? – StackExchange What The Heck Sep 11 '13 at 12:03
  • When you say dynamic content, what are you thinking about, images, text, HTML snippets... – Marc Audet Sep 11 '13 at 12:07
  • @yochannah The wrapper should grow to contain the content (which is mainly text), while maintaining a 1:1 aspect ratio. – johnny Sep 11 '13 at 12:10
  • Why should the example be restricted to a fixed width? The "trick" is all about a padding-top or padding-bottom in percentages, representing the aspect ratio, which in your case will be 100% (based on the width of the element). – Netsurfer Sep 11 '13 at 12:10
  • @MarcAudet Mainly text and a HTML list – johnny Sep 11 '13 at 12:10
  • hmmm, another question - is it a single div, or does it need to apply to multiple elements. If so, do each of the elements need to the the same as each other? – StackExchange What The Heck Sep 11 '13 at 12:13
  • @Netsurfer I should have phrased it differently: The size of the box is defined relative to the pages with rather than the boxes content. – johnny Sep 11 '13 at 12:13
  • @yochannah I don't know, if I fully understand your question, but the div contains a

    and a

      that can differ in size (the "dynamic content")
    – johnny Sep 11 '13 at 12:17
  • If the size of the box width is a % of that of the page, then how is the box to grow dynamically depending on the content? – Marc Audet Sep 11 '13 at 12:17
  • @johnny: The containing box **does not need** an explicit width (or heihgt, as the percentage value of the padding is always based on its width! It is the best/ ideal solution in your case ...! – Netsurfer Sep 11 '13 at 12:18
  • At some point, if you add enough content, the 1:1 will overflow... – Marc Audet Sep 11 '13 at 12:18
  • @MarcAudet I was talking about the linked (wrong) example – johnny Sep 11 '13 at 12:21
  • @johnny: About your edit to your question - if you have a DIV element, it is a block-level element by default, which will take the full width. If you want the width to depend on the content use 'float' (shrink-to-fit) or 'display: inline-block'. But to stretch its height to remain a given aspect ratio, it's still the "padding trick" that will do it! So what is your problem with this solution? – Netsurfer Sep 11 '13 at 12:41
  • I've set in on display-block, but even then the content just runs on, as long as I don't set a width (which I can't since it's correlating with the height). I've updated the fiddle http://jsfiddle.net/B8FU8/3423/ – johnny Sep 11 '13 at 13:00
  • Well, the width is exactly determined by the content and also the height is set with respect to the aspect ratio. It is somehow logical that you cannot have both - the height with respect to the width and at the same time content, which height is a multiple of the width! Marc already mentioned this in his comment above. So you need to use`overflow: auto; max-height: 100%;` I have updated your [jsFiddle](http://jsfiddle.net/B8FU8/3426/) – Netsurfer Sep 11 '13 at 13:17
  • @johnny: Just found a [similiar question](http://stackoverflow.com/questions/18296378/how-to-keep-a-div-contained-within-the-viewport-whilst-maintaining-aspect-ratio?rq=1). As you can see, the solution is quite the same ...! ;-) – Netsurfer Sep 11 '13 at 13:31
  • @johnny. Did I misunderstand your question? It's marked [duplicate](http://stackoverflow.com/q/1495407/383793), but that question is about making a square div with a size relative to its container. I understood you didn't what that, but have the div be the smallest square possible around its contents. Like I did with [javascript](http://stackoverflow.com/a/18746196/383793). I'm really interested in a CSS solution, but that probably won't come on a closed question... – Chris Wesseling Sep 12 '13 at 11:20

2 Answers2

0

So the answer to your question(s) is/ are:

I have a div that grows dynamically depending on the content

Use 'float' (shrink-to-fit) or 'display: inline-block' for the (containing) DIV element.

while maintaining a 1:1 aspect ratio

To achieve this you can use 'padding-top' or 'padding-bottom' with a percentage value representing the desired aspect ratio (in case of 1:1 it will be 100%) on a 'dummy' element, which will be a child of the containing DIV. The second child then will be absolute positioned (remember to relative position the containing DIV).

position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;

And if the height is actually heigher than the height set by the width, you additionally need

overflow: auto;
max-height: 100%;

for your element.

That's it - DEMO

Netsurfer
  • 5,543
  • 2
  • 29
  • 34
0

You can set the element to have a 1x1 ratio using a function like:

function set_1x1_ratio(el){
    //set auto size
    el.width('');
    el.height('');

    var max = Math.max(el.width(), el.height());
    el.width(max);
    el.height(max);
}

And call that whenever you dynamic adding happens. Like this.

Alternatively you could use a mutation observer to call it whenever the element changes. Like this.

Chris Wesseling
  • 6,226
  • 2
  • 36
  • 72