Skip to content

[css-contain-3] What container features can be queried? #5989

Closed

Description

@mirisuzanne

This relates to #5796, adding Container Queries to Contain Level 3.

Since container queries resolve against a contained ancestor element, rather than the viewport, we've discussed the ability to use actual/computed font sizes when resolving container dimensions in font-relative units:

html { font-size: 24px; contain: size layout; }

/* resolves against browser default font size - often 16px  */
@media (width > 30em) { /* applies above 480px viewport */ }

/* resolves against container font size - in this case 24px  */
@container (width > 30em) { /* applies above 720px container */ }

Would we be able to query other computed values on the container? A few quick examples:

/* custom properties */
@container (var(--color-mode) = dark) {
  a { color: plum; }
}

/* background-color */
@container (background-color = black) {
  h2 { color: white; }
}

/* background-color */
@container (font-style = italic) {
  em { font-style: normal; }
}

Some of the use-cases here might overlap with #5624.

If they are possible, would these queries require the same size/layout/style containment that we need for dimensional queries?

Activity

  1. matthew-dean commented on Feb 13, 2021

    @matthew-dean

    It's a fascinating idea. I think to do this, though, you'd have to define what values mean in terms of equality, less than, greater than, etc. As in, say an author did this:

    @container (font-weight >= normal) {
    /* ... */
    }

    Is that valid? If so, are we converting normal to its numerical value? I mean, it seems intuitive that you would, but I think such conversions for the purposes of queries would have to describe those behaviors. I'm not sure the spec is specific enough for types in order to clearly communicate to vendors what > < = should automatically mean for every single CSS property as it might be compared to every possible value. Or what should happen to the entire query for a type mismatch. Although I've been wrong before lol.

    Inevitably, someone will look at the above keyword query and then try something like:

    @container (display >= flex) {
    }

    Which seems silly but is it automatically invalid? Or does it match if it has an exact value of flex?

    My instinct would be to limit it to layout (height / width), get container queries implemented and everyone used to them, with the knowledge that the types of queries will likely be expanded / further defined in the future.

  2. ausi commented on Feb 13, 2021

    @ausi

    In the container query polyfill I created a while ago, querying other properties is possible too (demo).

    From what I learned, the number of useful properties to query against seems to be quite limited.

    If they are possible, would these queries require the same size/layout/style containment that we need for dimensional queries?

    I think containment is only required for properties relating to layout/dimensions. But which parent should get selected as the “container” should be defined on a per property basis. For background-color the first ancestor that has a non-transparent background should probably be the “container”. Inherited properties can use the direct parent as the “container”.

    I also think it would make sense to limit it to layout at first. Or at least to a limited set of properties that are supported like background-color, color, font-size and text-align.

  3. andruud commented on Feb 15, 2021

    @andruud
    Member

    Querying standard properties (background-color etc) might introduce too much complexity (not sure), but custom properties seems doable. I guess we can use @property to define what <, <=, (etc) means.

  4. mirisuzanne commented on Feb 16, 2021

    @mirisuzanne
    ContributorAuthor

    I'd want to be real careful about changing the meaning of a "container" based on what is queried. Assuming we keep that definition of an "ancestor with containment", maybe the question is "what else might be useful to query about those existing container elements?"

  5. argyleink commented on Feb 22, 2021

    @argyleink

    if more than properties and values can be queried, it'd be amazing to have things like :stuck, :overflow, :snapped, :on-screen, :wrapping, :ellipsing, etc. these are more like browser internal states or do they fit the question?

  6. mirisuzanne commented on Feb 23, 2021

    @mirisuzanne
    ContributorAuthor

    @argyleink That's an interesting idea. I feel like it would need some clarifying syntax - since the default is a computed value comparison, and this is something new… Maybe like:

    @container state(stuck) { … }
    @container (min-width: 30em) and not state(overflow) { … }
  7. argyleink commented on Feb 23, 2021

    @argyleink

    I like that, sure reads nice

    @container state(stuck) {
      nav {
        --box-shadow-y-distance: 15px;
      }
    }
    @container state(in-view) {
      section {
        animation: reveal .5 ease forwards;
      }
    }
  8. una commented on Apr 28, 2021

    @una
    Contributor

    I really really love the idea @argyleink mentioned above of being able to query "in-view" and "stuck". Not sure what the best syntax solution would be but this would save a lot of JS.

  9. argyleink commented on Jun 10, 2021

    @argyleink

    What about being able to query number of children nodes? similar to this request #4559

    I was just building breadcrumbs and a container query that could make smart decisions about it's layout based on container width AND number of crumbs, would be awesome. The use case I had is, I want to show only icons if there's a lot of crumbs and not a lot of width available. conversely, if there's 1 or less crumbs and not a lot of width available, still show the labels with the icons.

  10. mirisuzanne commented on Jun 11, 2021

    @mirisuzanne
    ContributorAuthor

    @argyleink so pseudo-code…

    @container (width < 30em) and (nodes > 3) {
      .crumb-label { /* hide */ } 
    }

    Is that what you mean? I feel like the node-count would be more powerful if you could use it in a selector, without the limitation of needing to query a distinct container. Then you could still combine it with queries, but it wouldn't rely on them. More pseudo-code:

    @container (width < 30em) {
      .breadcrumb:nodes(>3)  .crumb-label { /* hide */ } 
    }

    I don't know if that's viable, but I don't think that should require a container for any reason?

  11. mirisuzanne commented on Sep 24, 2021

    @mirisuzanne
    ContributorAuthor

    I think we can close this out as a general question, and open specific issues for features we would like to query (such as the issues opened for style & state queries).

  12. pnkapadia64 commented on Mar 10, 2022

    @pnkapadia64

    @mirisuzanne When we use a rule mentioning the viewport height /width, and having a container as a parent, is it possible to use the container's height/width instead of the viewports?

    .parent {
        contain: size layout;
    }
    .child {
       font-size: 2vw;
    }
    

    I want the child's font-size as per parent's width and not the viewports.

  13. mirisuzanne commented on Mar 10, 2022

    @mirisuzanne
    ContributorAuthor

    Yes, see the Container Relative Units section of the spec. Replace the v in any viewport unit with cq (so for example instead of 3vw, you can use 3cqw).

  14. pnkapadia64 commented on Mar 10, 2022

    @pnkapadia64

    Yes, see the Container Relative Units section of the spec. Replace the v in any viewport unit with cq (so for example instead of 3vw, you can use 3cqw).

    @mirisuzanne Hey, I tried that out but Chrome Canary doesn't identify cqw/cqh/cqi. Am I missing any flag to enable except the main Container Queries one on chrome?
    Example

  15. mirisuzanne commented on Mar 10, 2022

    @mirisuzanne
    ContributorAuthor

    The Chrome prototype might not be up to date. The first draft just used eg qw. I imagine that will get updated soon, but you can try dropping the c for now, in order to test it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions