Container Queries based on height not working
Asked Answered
H

3

16

I would want to use the new CSS container queries in modern Safari/Chrome browser. (Safari 16.3, Google Chrome 113.0)

However container queries based on height are not working as expected.

Expected result: as soon as the outer container turns blue (500px screen height or below) I would expect the pink square (50vh of 500px container) to turn red.

Current result: The square stays pink and does not turn pink. The example works if the implementation is width relative.

Did I do anything wrong in my implementation or is it just not jet implemented in Webkit engine? Any other solutions (without Javascript) to solve the problem, if in the final product the container will be resizeable by the user?

body {
    margin: 0
}

.container {
    height: 50vh;
    container-type: inline-size;
}

.test {
    width: 250px;
    height: 250px;
    background-color: hotpink;
}
            
@container (max-height: 250px) {
    .test {
        background-color: red;
    }
}
            
@media screen and (max-height: 500px) {
    .container {
        background: blue;
    }
}
<div class="container">
    <div class="test"></div>
</div>
Hydro answered 10/5, 2023 at 19:27 Comment(0)
J
14

inline-size is the width not the height. You have to use size

inline-size

the query will be based on the inline dimensions of the container. Applies layout, style, and inline-size containment to the element. ref

body {
    margin: 0
}

.container {
    height: 50vh;
    container-type: size;
}

.test {
    width: 250px;
    height: 250px;
    background-color: hotpink;
}
            
@container (max-height: 250px) {
    .test {
        background-color: red;
    }
}
            
@media screen and (max-height: 500px) {
    .container {
        background: blue;
    }
}
<div class="container">
    <div class="test"></div>
</div>
Jerri answered 10/5, 2023 at 19:48 Comment(0)
B
4

Also with container queries it's not sufficient to write only min-height

.container {
  container-type: size;
  min-height: 50vh; /* doesn't work */
}

height has to be specified explicitly.

.container {
  container-type: size;
  height: 50vh;
}

Only then can you query the container

@container (max-height: 200px) {
  .child {
    background: red;
  }
}

Bonspiel answered 9/1 at 19:50 Comment(8)
I don't get it. Does that mean, we can't use container for elements with dynamic heights? For example I want to style a child of a textbox depending on the amount of text in it - e.g. make it smaller when there is a line break. Alway when I set the container type to "size" all the heights of my Textbox seem to be reduced to zero - which results in all the sibling textboxes to overlap.Trierarch
Yes I'm afraid that's the case. At least I could only get it to work when the height is specified explicitly on the reference container.Bonspiel
Doesn't this make height-based queries pointless? Since you already know the height of the thing you're querying because you have to set it explicitly?Knossos
Exactly. This behaviour indeed renders height-based container queries less useful for elements with dynamic content, because the very nature of dynamic content means that its dimensions aren't known until the content is rendered. I wonder if this is just a bug or bad API design.Bonspiel
Ok, this is by design to prevent infinite loops: #73976389Bonspiel
This is useless to me then. I have a container and its behaviour must be altered based on the height it dynamically occupies. What a waste.Hairline
not useless, if you are using relative units such as vh. 100vh for your <body> for example, and a container query of (height < 800px) to target tablets or some such. The point being made is a height property must be set on the container for 'height' query to work.Hypesthesia
yes, but that's maybe < 1% of the use cases. And you could also use @media queries here in case of body. Most of the time when you want to use container queries, e.g. to shift the layout of a card inside a grid, and in such cases you don't have an explicitly defined size on the container.Bonspiel
L
-1

Yours could have worked if your container is absolute. I haven't tested below code but I believe it should work as you wished it should

.container {
  container-type: size;
  position: absolute;
  inset: 0;
}
.parent-of-container {
  position: relative;
}

The container will take the dimension of its parent dynamically. You do not need to specify its height at all. This approach worked for me. I think the reason is because it will never cause infinite loop since the height of the container no longer depends on the total height of its children.

Luigiluigino answered 27/6 at 12:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.