CSS Container query (aspect-ratio) not working

201 Views Asked by At

I'm trying to apply some styles based on the aspect-ratio of the container <div> element, but I haven't managed to write the correct Container query code.

If I take the Mozilla docs word on it (assuming I understand it correctly) it should be something possible to achieve, but that page lacks an example of this particular combination (e.g. an example of @container with aspect-ratio descriptor).

I'm using the most recent version of Google Chrome browser, so I assume Container queries are supported out of the box.

I'm trying to make the flex-direction attribute value change based on the container aspect ratio.

Here is the relevant part of my HTML code:

<div class="cont">
  <div class="a">
    A
  </div>
  <div class="b">
    B
  </div>
</div>

and the accompanying CSS code:

.cont {
  container-type: size;
  width: 80vw;
  height: 2rem;
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
}

.a,.b {
  max-width: 1rem;
}


@container (aspect-ratio > 1 / 1) {
  .cont {
    flex-direction: row;
  }
}

Those snippets come from this Codepen of mine. As you can see, the container queries just seem to be ignored by the browser.

I also tried container-type: inline-size;, but that made no difference (not that I expected it to make any, but I tried just in case).

Suspecting problems about display: flex; on the container I tried display: block; instead and used background-color instead of flex-direction, but even that did not work.

This answer to a similar question seems to suggest my code, in the query descriptor part, is correct, or at least I can't spot what mistake I'm doing when comparing my code with that answer.

What am I doing wrong?

2

There are 2 best solutions below

0
On BEST ANSWER

Container query styling doesn't affect the container specifying the container context itself. They do work on elements within the container context, i.e. on elements with an ancestor specifying a container context.

I was able to get your solution working with a small modification by using an inner element as the flexbox. To see it in action, change the container's width of 10rem to 1rem and watch the flex direction change from column to row.

HTML:

<div class="cont">
  <div class="flexer">
    <div class="a">
      A
    </div>
    <div class="b">
      B
    </div>
  </div>
</div>

CSS:

.cont {
  container-type: size;
  width: 10rem;
  height: 2rem;
}

.flexer {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
}

.a,.b {
  max-width: 1rem;
}

@container (aspect-ratio > 1 / 1) {
  .flexer {
    flex-direction: column;
  }
}
2
On

container-type property isn't part of the CSS specification, so using it won't have any effect. Instead, you should use @container queries directly.

CSS:

.cont {
  width: 80vw;
  height: 2rem;
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
}

.a, .b {
  max-width: 1rem;
}

JS:

function updateFlexDirection() {
  const container = document.querySelector('.cont');
  const aspectRatio = container.clientWidth / container.clientHeight;
  
  if (aspectRatio > 1) {
    container.style.flexDirection = 'row';
  } else {
    container.style.flexDirection = 'column';
  }
}

// Initial call to set the flex-direction based on initial aspect ratio
updateFlexDirection();

// Listen for window resize events to update flex-direction
window.addEventListener('resize', updateFlexDirection);