ONDoubleB
ONDoubleB

Reputation: 330

Make a relatively positioned div square with CSS

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.

Upvotes: 0

Views: 621

Answers (1)

mlnmln
mlnmln

Reputation: 595

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.

Upvotes: 1

Related Questions