Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS: keep aspect ratio without overflowing content

I am using CSS and I want to create a box with a certain ratio that is kept no matter the size of the box. But also I want the box to grow if there is more content in it.

To summerize in order words:

  • CSS only (if possible)
  • preserve given aspect ratio
  • allow box to grow if there is more content (with ratio)

In those techniques I've tried so far the content of the box is not able to make the box grow. Instead my only options are overlapping or clipping the content.

  1. Padding-ratio Hack
  2. Viewport based units
  3. Replaced Element Scale Hack

The first and the third method are preoccupying the space inside of a wrapper and the content is place on top of that using absolute position. Since the content is absolutely positioned it is removed from the document flow. Therefore it is unable to expand the wrapping element.

The Second Option is using a fixed height, which doesn't allow the content to grow beyond it either.

Here is a demo using the second option. (based on viewport units)

* {margin: 0; padding: 0;}
div{
  width: 50vmin; height: 50vmin;

  font-size: 30px;
  background: #ccc;
  margin: auto; 
  padding: 3%;
}
<div>
 <p>If you scale your window, you will see that the text does not fit into the box at some point, and therefore the text will be overlapping the box.<p>
</div>

Further Methods I partially tested:

  • object-fit positioning
  • flexbox

Object-Fit only affects replaced-elements as far as I know. I am unable to get any effect on my div/p-elements with this properties.

Flexbox is not practical either for my scenario. According to my current level of knowledge flexbox does not help here very well. Since its mostly about establishing relationships between multiple items. But I am not sure about that. Maybe there is something in flexbox that I am not aware of yet.

like image 629
Type-Style Avatar asked Mar 02 '16 16:03

Type-Style


1 Answers

Update

OP is now emphasizing the importance of text, so here's my take:

  • Using a background-image and background-size:contain.
  • figure has the background-sized background-image
  • figcaption is holding the text.
  • This particular png is 800x600 AR 4:3 which it maintains admirably.
  • The text flows well between resizes and the inevitable overflow of text is cutoff, but never breaches the borders.

Plunker

Snippet

@font-face {
  font-family: EraserRegular;
  src: url(http://glpjt.s3.amazonaws.com/so/font/EraserRegular.ttf);
}
html {
  box-sizing: border-box;
  font: 500 16px/1.428'EraserRegular';
  height: 100vh;
  width: 100vw;
}
*,
*:before,
*:after {
  box-sizing: inherit;
  margin: 0;
  padding: 0;
}
body {
  position: relative;
  font-size: 1rem;
  line-height: 1;
  height: 100%;
  width: 100%;
  overflow-x: hidden;
  overflow-y: scroll;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
h1,
h2,
h3,
h4,
h5,
h6,
legend {
  font-variant: small-caps;
  margin-bottom: 15px;
}
h1 {
  font-size: 1.5rem;
}
h2 {
  font-size: 1.4rem;
}
h3 {
  font-size: 1.3rem;
}
legend {
  font-size: 1.35rem;
}
p {
  margin: 0 5px 15px;
}
img {
  display: inline-block;
  width: 25em;
  height: auto;
  margin: 20px 0;
}
a {
  color: #Fc0;
  text-decoration: none;
  margin: 10px 20px;
  display: inline-block;
}
a:hover {
  color: #CCC;
}
button {
  font: inherit;
  line-height: 1.5;
  padding: 1px 3px;
  border-radius: 8px;
  border: 1px solid #fc2;
}
.noSel {
  -moz-user-select: none;
  -webkit-user-select: none;
  user-select: none;
}
code * {
  font: 100 1rem/1.5'Consolas';
  color: #6F3;
  background: #777;
  border: 2px inset #CCC;
  margin: 10px 10px 15px 15px;
}
.board {
  width: 100%; padding-bottom: 75%; height: 0; position: relative; background: url(http://i.imgur.com/gUobVE5.png) center center no-repeat;  background-size: contain; }
  figcaption {
    font-size: 100%;
    color: white;
    text-align: left;
    position: absolute;
    z-index: 1;
    max-width: 100%;
    max-height: 100%;
    padding: 40px 30px;
  }
<figure class="board">
  <figcaption>TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST
    TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST
    TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST
    TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST
    TEST TEST TEST TEST TEST TEST TEST</figcaption>
</figure>

Two properties come to mind is object-fit: contain and background-size:contain in conjunction with background-image The value contain invokes a certain behavior:

background-size / -image

figure {
    background: url(https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png) center center no-repeat;
    -moz-background-size: contain;
    background-size: contain;
    width: 9em;
    height: 9em;
}
code { font: 400 14px/1.3 'Consolas'; background: #ccc; }
<figure></figure>
<figcaption><code>background-image</code> and <code>background-size:contain</code> also maintains it's AR;<br> fixed lengths are not required; <br>this is for replaced objects like images and videos</figcaption>

Multiple background-images

section { width: 100vw; height: 100vh; display:table; }
.shirley_lenna {
  background: url(http://4.bp.blogspot.com/_xyCeswQjRbc/TTTtaB5t2vI/AAAAAAAACCc/lc_kHPTSnSg/s1600/Shirley+02.jpg) left center no-repeat, url(https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png) right center no-repeat;
  background-size: contain;
  width: 100vw;
  min-height: 20em;
  display: table-cell;
}
<section>
<figure class="shirley_lenna"></figure>
  
  </section>

object-fit

img {
    width: 140px;
    height: 140px;
    border: solid 1px white;
    object-fit: cover;
}

code { font: 400 14px/1.3 'Consolas'; background: #ccc; }
<figure>
<img src="https://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png">
<figcaption><code>object-fit</code> maintains AR;<br> must use fixed width and height;<br> for replaced objects like img, video, etc.</figcaption></figure>
like image 137
zer00ne Avatar answered Oct 23 '22 06:10

zer00ne