What is the best way to place a square inside a rectangle?

I've been experimenting with fitting a square into a rectangle using max-width, max-height, and aspect-ratio. However, I encountered an issue where it only works in portrait mode, but fails in landscape mode. Here is how Firefox renders it:

https://i.sstatic.net/V2IHB.png https://i.sstatic.net/V2AdQ.png

This serves as an example of the problem.

function adjustPortrait() {
  document.body.style.width = "10em";
  document.body.style.height = "14em";
}

function adjustLandscape() {
  document.body.style.width = "14em";
  document.body.style.height = "10em";
}

document.getElementById("button0").addEventListener('click', adjustPortrait);
document.getElementById("button1").addEventListener('click', adjustLandscape);

adjustPortrait();
html, body {
  margin: 0;
}
#page {
  height: 100%;
  box-sizing: border-box;
  border: 1ex solid blue;
  display: grid;
  grid-template-rows: auto min-content;
}
.square {
  max-width: 100%;
  max-height: 100%;
  aspect-ratio: 1 / 1;
}
canvas {
  box-sizing: border-box;
  border: 1ex solid red;
  display: block;
  width: 100%;
  height: 100%;
}
buttons {
  box-sizing: border-box;
  border: 1ex solid green;
  width: 100%;
}
<div id="page">
  <div class="square">
    <canvas width="100" height="100">
    </canvas>
  </div>
  <div class="buttons">
    <input id="button0" type="button" value="Works"/>
    <input id="button1" type="button" value="Fails"/>
  </div>
</div>

Any suggestions on how to properly fit the red and green boxes into the blue box?

Answer №1

Through the use of container-type, I have successfully managed to make it work. There are convenient container units known as cqmin and cqmax. Cqmin serves as the minimum size for inline and block containers, which proves useful when dealing with changing aspect ratios. By defining the square as a container and utilizing the size value instead of inline-size, setting the canvas width to 100cqmin allows it to fill either the height or width of the grid item based on the smaller container size (as the size value considers both block and inline lengths). Fortunately, it appears that container queries enjoy widespread support.

function portrait() {
  //To ensure the body and #page div sizes were as specified, I switched these from em to px.
  document.body.style.width = "250px";
  document.body.style.height = "300px";
}

function landscape() {
  document.body.style.width = "300px";
  document.body.style.height = "250px";
}

document.getElementById("button0").addEventListener('click', portrait);
document.getElementById("button1").addEventListener('click', landscape);

portrait();
* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
}

#page {
  height: 100%;
  border: 1ex solid blue;
  display:grid;
  grid-template-rows: 1fr auto;
}

.square {
  container-type: size; /* ensure compatibility for both inline and block dimensions */
}

canvas {
  border: 1ex solid red;
  display: block;
  width: 100cqmin; /* the key element here */
  aspect-ratio: 1/1;
}

buttons {
  border: 1ex solid green;
  width: 100%;
}
<div id="page">
  <div class="square">
   <canvas width="100" height="100"></canvas>
  </div>
  <div class="buttons">
    <input id="button0" type="button" value="Works"/>
    <input id="button1" type="button" value="Works!!!!"/>
  </div>
</div>

Answer №2

Explore utilizing orientation and the @container rule! Check out MDN Documentation here

Note: To adjust based on real page size, switch from @container to @media

function portrait() {
  document.body.style.width = "10em";
  document.body.style.height = "14em";
}

function landscape() {
  document.body.style.width = "14em";
  document.body.style.height = "10em";
}

document.getElementById("button0").addEventListener('click', portrait);
document.getElementById("button1").addEventListener('click', landscape);

portrait();
html, body {
  margin: 0;
}
#page {
  height: 100%;
  box-sizing: border-box;
  border: 1ex solid blue;
  display: block;
  container-type: size;
}
#wrapper {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  height: 100%;
}
.square {
  aspect-ratio: 1 / 1;
}
@container (orientation: landscape) {
.square {
  flex: 1;
  margin: auto;
  }
}

@container (orientation: portrait) {
.square {
   width: 100%;
  }
}
canvas {
  box-sizing: border-box;
  border: 1ex solid red;
  display: block;
  width: 100%;
  height: 100%;
}
buttons {
  box-sizing: border-box;
  border: 1ex solid green;
  width: 100%;
}
<div id="page">
  <div id="wrapper">
    <div class="square">
      <canvas>
      </canvas>
    </div>
    <div class="buttons">
      <input id="button0" type="button" value="Works"/>
      <input id="button1" type="button" value="Fails"/>
    </div>
  </div>
</div>

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

Click here to view the latest Poll Results!

I have implemented AJAX to display poll results on the same page without requiring a refresh. An issue I am facing is that the poll section occupies about three times more space than the results. This causes an inconvenience for users who vote, as they ma ...

Using Angular 2 to position a md-fab button with 'position: fixed' inside an inner component

Utilizing the md-fab-button from the initial angular2 material-framework has presented a challenge for me. I am attempting to set the md-fab-button(for adding a new entity) with position: fixed, but my goal is to position the button within an inner compone ...

Customized figcaption formatting separate from the surrounding text

Is there a way to add a "figcaption" with independent settings to images placed alongside paragraphs in HTML? I have the following code snippet, but I'm unsure if I am using the figcaption tag correctly: <p><figure><span class="image ...

Can we link together two separate ngfor loops in any manner?

<div class="gl-w-100 gl-md-w-auto gl-po-rel list"> <div class="signin_wrpr gl-w-100 gl-po-rel gl-d-flex gl-fd-column gl-bg-white gl-lg-w-auto gl-md-w-auto gl-h-100 gl-md-ta-c"> <div class="head g ...

Create shortened class names

Is there a way to abbreviate class names in HTML and CSS files? For example, I currently have the class name: .profile-author-name-upper And I would like to change it to something shorter like: .p-a-n-u or .panu Any suggestions on how to achieve thi ...

Ensuring one div remains in a fixed position relative to another div

I'm struggling to keep my two white divs aligned in relation to the black div in the center. They need to maintain the same distance from the black div even when the page is resized. #halvfjerds { width: 100%; height: 1050px; background-color ...

"Maximize user experience: Eliminate the "#" in your URL by utilizing anchor tags for one-page navigation in

I've created a website with menu tabs including Home, About, Work, and Contact. To make navigation easier, I've used anchor tags for this one-page layout. However, I'm concerned about the URLs updating when clicking on the tabs. I prefer to ...

Adjusting the height of the Owl Carousel div to enhance image hover effects

Seeking help with implementing a hover effect on an img within an Owl Carousel div. I have applied a simple CSS transition to the Owl Carousel container div, but the Carousel is automatically setting a standard height. Images included for reference. I have ...

ng-model causing simultaneous changes to all selects

Check out this jsfiddle link Hello there, I'm encountering an issue with my application. I need to create multiple dropdowns using ng-repeat and have them all populated with the same options. The problem arises when one dropdown is changed, all ot ...

Utilizing CSS3 transformations for a symbol

I'm currently attempting to implement a CSS transformation on an icon (glyph) within a :before pseudo element. My primary objective is to execute a simple "flip" animation on the icon using transform: scale(-1, 1), but I am encountering difficulties ...

- Utilize bullet points to exhibit keywords within a D3.js div by appending them

I'm looking to showcase the comma-separated values from a JSON file as a list in a mouseover tooltip on each node. Here is my current code snippet: div.append("div") .attr("class", "tooltip") .style("opacity", 1) .html("Node name : " + d.NodeName + ...

Instructions on displaying the main page even with just inputting the default directory in the URL

One scenario is when I input file:///C:/xampp/htdocs/At/html/ in the URL. My desired outcome is for file:///C:/xampp/htdocs/At/html/pages-login.php to be displayed instead. How can I achieve this? ...

Ensure the background image is optimized for viewing on screens of any size

I am facing an issue with an image on my website that serves as the background for some elements. The image is wider than it is tall, causing problems for users viewing the site on phones. Is there a way to cut off the sides of the image and ensure it fits ...

The Oracle Apex Login Interface with a Touch of Customized Styling

Currently, I'm working on creating a login page in Oracle APEX. While modifying the icon using CSS code, everything seems to be falling in place except for this one particular line: .t-Login-logo { background-image:url(#APP_FILES#LogoUpdated.jpg); bac ...

JS | How can we make an element with style=visibility:hidden become visible?

HTML: <div id="msg-text"><p><b id="msg" name="msg" style="visibility:hidden; color:#3399ff;">This is a hidden message</b></p></div> JS: $('#url').on('change keyup paste', function() { $('# ...

Spin picture and optimize margins

I need help rotating an image by 90 degrees that is positioned between two boxes. The issue I am facing is that the rotated picture overlaps with the two boxes in this scenario. Example 1: Incorrect formatting CSS: .box{ height:50px; width:200px ...

The updated Bootstrap 4 carousel is only working halfway as expected when attempting to double it up, causing the scroll loop to stop functioning

Discovering a fantastic carousel modification was an exciting find, which can be accessed Here. However, when attempting to place two carousels on one page, issues arose with the scrolling functionality. While I managed to make them operate on the correct ...

`At a loss: jQuery failing to retrieve JSON data`

I'm having trouble with a basic script that is supposed to fetch data from a JSON feed and display it in an alert. Despite having loaded jQuery correctly and checked for common issues, the code doesn't seem to be working. I am using jQuery and ca ...

JavaScript Calculator experiencing difficulty with adding two numbers together

I've been working on developing a calculator using HTML and JavaScript, but I'm facing an issue when trying to add two numbers together. Strangely enough, when attempting to calculate 1 + 0, I get the result of 512, and for 1 + 1, it returns 1024 ...

The React application is experiencing difficulty selecting CSS files through the code

I've encountered an issue with my React app where the button.css file is not rendering properly even though I've kept both the buttn.css and button.js in the same folder. Button.css .Button { background-color: transparent; border: none; ...