Responsive Div that Resizes Proportionally within Parent Container

Having a div element that adjusts its height based on width to maintain aspect ratio, I aim to place this div within another while maximizing available space vertically and horizontally without any cropping. It seems that object-fit: contain, typically used for images, may be the closest option.

The goal is to ensure the div covers the maximum height and width possible while still adhering to the aspect ratio, with no crop in either vertical or horizontal directions.

Can this be achieved using CSS alone? If so, how?

Want more insight? Check out this informative article.

Code snippet (or any alternate solution):

html,
body {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
}

.container {
  position: relative;
  width: 100%;
}

.container:before {
  content: "";
  display: block;
  width: 50%;
  padding-top: 50%;
}

.embed {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: red;
}
<div class="container">
  <div class="embed">
    this should accommodate all the available space and maintain aspect ratio, no crop when width is too wide
  </div>
</div>

https://i.stack.imgur.com/rs95z.png

Answer №1

Learn about aspect-ratio and how it can be used with overflow:hidden in Chromium 88 to create visually pleasing designs.

Update for January 2023:

A new container query @container (aspect-ratio > X) is now required for Firefox version v110.0b2, Safari, and Chromium browsers. Make sure to update your code accordingly.

You can find the updated code snippet below and also view a demo on jsitor by visiting this link.

html,
body {
  display: flex;
  justify-content: center;
  align-items: center;

/* Rest of the CSS code omitted for brevity */
}
<div class="container">
  <div class="embed">
    <div>1:1</div>
  </div>
</div>

Answer №2

After exploring various options, it appears that a CSS-only solution may not be feasible for this particular challenge. For those who are curious, I have developed a custom React component that addresses the issue (Expect tests and an improved README in the near future).

This component encapsulates its content within a div, utilizing JavaScript to determine the dimensions of the containing element so that it can adjust accordingly while maintaining the desired aspect ratio. Essentially, it adjusts the container size until one side reaches its maximum limit.

LATEST UPDATE: A recent breakthrough has led to the discovery of a potential CSS-based solution!

Answer №3

One way I found to work around this issue is by enclosing the child element within an svg's foreignObject tag:

const container = document.getElementById('container');
document.getElementById('btn').addEventListener('click', () => {
  container.style.height = container.style.height === '100px' ? '200px' : '100px';
});
body {
  margin: 1rem;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

button {
  margin-bottom: 1rem;
}


#container {
  background-color: #ffceaf;
  width: 400px;
}

svg {
  background-color: #b8d6ff;
  height: auto;
  width: auto;
  max-width: 100%;
  max-height: 100%;
  overflow: hidden;
}

#content {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  border: solid;
}
<button id="btn">Change parent height</button>

<div id="container" style="height: 100px;">
  <svg width="15000" height="5000">
    <foreignObject width="100%" height="100%">
      <div id="content">
        content content content content content content content
        (...continued)
      </div>
    </foreignObject>
  </svg>
</div>

However, there are some drawbacks to this approach:

  • Limited browser compatibility (IE/Edge do not fully support foreignObject)
  • It may not be considered best practice. Introducing elements from a different XML namespace could lead to potential issues(?).

Considering these factors, using JavaScript might be a more reliable option in this scenario.

Answer №4

Check out this CSS-only solution I came up with:

View Codepen Demo or you can run the demo below ⬇

.resizable-container {
  resize: both;
  overflow: scroll;
  border: 1px solid black;
  padding: 3px;
  height: 140px;
  width: 330px;
}
.container {
  height: 100%;
  box-sizing: border-box;
}
.aspect-thing {
  aspect-ratio: 16/9;
  border: 2px red solid;
  box-sizing: border-box;
  max-width: 100%;
  max-height: 100%;
  margin: auto;
}
<div class="resizable-container"> 
  <div class="container">
    <div class="aspect-thing">
    </div>
  </div>
</div> 
<p>You can resize me ^</p>

https://i.stack.imgur.com/7HOQA.gif

Answer №5

This solution utilizes pure CSS with nested flexboxes. The outer container has a flex-direction: row property, while the inner container has a flex-direction: column property. It is crucial that the inner container's aspect-ratio is set to 1/1 and the height of the inner container is defined, along with the width of the pseudo-element inner:before.

<div class="outer">
  <div class="inner"></div>
</div>
.outer {
  width: 80%;
  height: 80%;
  margin: auto;
  background-color: red;
  padding: 50px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.inner {
  height: 100%;
  aspect-ratio: 1 / 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  overflow: hidden;
}

.inner:before {
  content: '';
  width: 100%;
  aspect-ratio: 1 / 1;
  background-color: blue;
}

Answer №6

Take a look at this refined version of the solution inspired by Ben Winding, which effectively centers the div vertically:

Codepen Link or try out the demo below ⬇

:root {
  --aspect-ratio: 16/9;
  --container-max-width: 90%;
}

.resizable-container {
  resize: both;
  overflow: scroll;
  border: 1px solid black;
  padding: 3px;
  height: 140px;
  width: 330px;
}

.container {
  height: 100%;
  box-sizing: border-box;
  width: 100%; 
  max-width: var(--container-max-width);
  margin: auto; 
  display: flex;
}

.inner-container {
  flex-grow: 1; 
  align-self: center;
  max-width: 100%;
  max-height: 100%; 
  aspect-ratio: var(--aspect-ratio);
}

.aspect-thing {
  aspect-ratio: var(--aspect-ratio);
  border: 2px red solid;
  box-sizing: border-box;
  
  max-width: 100%;
  max-height: 100%;
  margin: auto;
}
<div class="resizable-container"> 
  <div class="container">
    <div class="inner-container">
      <div class="aspect-thing">
      </div>
    </div>
  </div>
</div> 
<p>Resize me ^</p>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using CSS for hover transitions can be glitchy in Safari, especially when trying to keep images centered

After seeing an example on Design Shack, I was inspired to create linkable photos that zoom in slightly when hovered over. To achieve the desired centered animation effect, I had to tweak the top, left, margin-top, and margin-left properties until it worke ...

What methods can I use to visually distinguish external links from those on my website?

Can CSS be used to show users which links are external? ...

Enhance the appearance of the table footer by implementing pagination with Bootstrap Angular6 Datatable styling

I utilized the angular 6 datatable to paginate the data in a table format. https://www.npmjs.com/package/angular-6-datatable Everything is functioning properly, but I am struggling with styling the footer of mfBootstrapPaginator. The items appear stack ...

The styling of Div remains unchanged by CSS

Currently, I am working on a website using HTML and CSS. I have created a division element and applied a class to it called profile_pic. However, when I make changes to this class in the CSS file, it does not reflect on the div. It seems like the styling ...

Seeking help with a Javascript regex inquiry

I am currently utilizing JavaScript regex for the following task: I have gathered the HTML content from a page and stored it within a string. Now, I aim to identify all URLs present on this page. For instance, if the document includes-- <script src = ...

Issue with PHP/HTML header() function not directing to URL page

Situation: In my member database overview, users can click on an 'update member' link in a table that redirects them to a page displaying the data of the selected member. The URL receives the parameter lid.php?lidnummer=4 (or any other ID). On t ...

Apache causes HTML download tag to malfunction

I have an HTML file that includes the following code: <a href="/Library/WebServer/Documents/file.zip" download="file.zip"> Download here </a> When I test this HTML page on Chrome, it successfully allows me to download the file. However, when ...

What is the best method to remove the x and up/down arrow components of an input date field?

My main objective is to have the orange triangle display in the box, but I'm unsure if CSS or another method is needed to remove the two elements on the left side of the triangle. Is there a way to achieve this? Currently, I am using the input type d ...

Arrange flex list items in vertical rows on smaller screens for a more organized layout

Struggling to have CSS flex list stagger text on two lines for smaller screens, but so far, my attempts have failed. I've tried using spans and br at various media queries, but nothing seems to work. Any assistance would be greatly appreciated. This ...

unable to establish a connection to SQL in [PHP]

I'm having an issue with my code and need some help fixing it. The website is supposed to allow users to add, edit, and delete data. However, when I fill out the fields and click "add", it redirects me to a blank page. Here's the code that I have ...

Adjust the tabs to fit perfectly within the container

I am currently facing an issue with my navigation bar. I have placed the <nav> tags within a container set to 100% width. However, when I adjust the height of the container by a certain percentage, the <ul> & <li> elements in the nav ...

What techniques can be used to create logos that adapt and transform seamlessly as the screen size varies?

The way Responsive Logos adjust their image width when you resize the browser is truly impressive. It seems like they are using SVG images, but I'm not entirely sure how they are able to make the image change dynamically. Could it be through the CSS c ...

Basic image slider featuring adjustable heights

I'm currently working on a basic content slider, but I've encountered an issue where the container doesn't expand as new content slides in. It seems to be related to the absolute positioning of the content items. If I don't use absolute ...

How can I use JavaScript to create a drop-down menu that only appears after selecting the previous one?

<div class="row"> <div class="col-md-4"> <label for="selectCustomers">Customer Select</label> <select class="form-control pointer" name="tableCustomers" id=" ...

One column stretching all the way to the window's edge while the other column stays contained within its container

Looking to design a two-column layout where the left column takes up 40% of the container and aligns with it, while the right column expands all the way to the window edge. I managed to achieve this using position:absolute, but I'm curious if there&ap ...

Issues with Node JS app's handling of php mailer code

I've made a basic website using the Node JS framework and included a php mailer for handling the contact form. Unfortunately, I'm facing issues getting it to function properly. Could it be possible that there is an underlying problem with Node JS ...

Foundation Framework sidebar by Zurb

My current dilemma involves the zurb foundation framework, specifically with the .row class being set to a max-width of 61.25em, which is equivalent to 980px in width. The problem I am facing is that when I resize the browser and it reaches 1024px wide, t ...

Incomplete Website Encryption Alert

Currently, I am developing a website called "usborroe.com" and have just set up a GeoTrust Business ID SSL Certificate. However, despite my efforts to ensure full encryption on the site, an error message is indicating that it is not fully encrypted and t ...

Align a button to the left or right based on its position within the layout

On the left side, there is dynamic text and on the right side, a button is displayed as shown below: <div class="dynamic-text"> {{ dynamicText }} </div> <div class="some-button"> < ...

I am currently facing a challenge with Bootstrap, as I am trying to design a webpage for small devices using a 1:4:1 format, but I am struggling to get it right

column 1 and column 3(left and right cols) have successfully passed the test case, but not column 2 (the middle one) that I have commented on in the code. Please help. Thank you. The problem has certain conditions that would have been easier to understa ...