0

I would like to know if there is a CSS only solution to make sure that a relatively positioned div would be exactly square under any circumstances; I have a script that would allow a user to upload an image which would apply it to the background image property.

The problem is that the system needs to support images of all sizes, so I can't just set a specific height and width.

ONDoubleB
  • 320
  • 1
  • 10
  • Can't you set width and height of div and then set image as background with `banckground-size: cover;` or something like that? – Karmalakas Jul 17 '14 at 15:02
  • also the other question is what browser support is required. background-size will not render properly on older browsers. Have a look at this post here http://stackoverflow.com/questions/4885145/ie-8-background-size-fix – eg_dac Jul 17 '14 at 15:12
  • I'm not sure this can be done with a CSS only approach. – Christopher Harris Jul 17 '14 at 15:12
  • you will need some javascript to manipulate the the css properties after images are uploaded. – eg_dac Jul 17 '14 at 15:13

1 Answers1

1

Step 1

Simply give the div padding-bottom of 100% to create an intrinsic ratio, which means the div will always be square, no matter the width. Then use position: relative/absolute to position a child element that strechtes the whole container.

This is a common CSS only technique to embed videos at certain aspect ratios, but it's not limited to that specific content type.

I created a fiddle to see it in action. Please note: I used SuitCSS' flex embed component here, but you are in no way bound to using it.

http://jsfiddle.net/mlnmln/tfm6q/1/

HTML:

<div class="FlexEmbed FlexEmbed-ratio">
  <div class="UserImage FlexEmbed-content"></div>
</div>

CSS:

/*
 * FlexEmbed component from suit-css. 
 * @see: https://github.com/suitcss/components-flex-embed/blob/master/lib/flex-embed.css
 * @see: http://suitcss.github.io/components-flex-embed/test/
 * @see: http://alistapart.com/article/creating-intrinsic-ratios-for-video
 */ 

.FlexEmbed {
  display: block;
  overflow: hidden;
  position: relative;
}

/**
 * The aspect-ratio hack is applied to an empty element because it allows
 * the component to respect `max-height`. Default aspect ratio is 1:1.
 */

.FlexEmbed-ratio {
  display: block;
  padding-bottom: 100%;
  width: 100%;
}

/**
 * Fit the content to the aspect ratio
 */

.FlexEmbed-content {
  bottom: 0;
  height: 100%;
  left: 0;
  position: absolute;
  top: 0;
  width: 100%;
}

Step 2

Find a method to resize image to fit/fill its container. I would suggest the following solutions.

  1. Backend: Crop the image through an image manipulation library like GDlib or ImageMagick. That way users will only have to download the data they need.

  2. CSS: Use background-size: cover if your don't care about legacy browser support and don't have access to server side image manipulation.

    .UserImage { background-size: cover;
    background-image: url(http://placekitten.com/200/400); }

3: JS: Position and crop the image container using DOM manipulation. This is basically the same Math as using a server-side image library, with the disadvantage that you place the load on the client (bandwidth and processing).

Hoping to help.

mlnmln
  • 575
  • 2
  • 10