Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
mirisuzanne opened this issue Feb 13, 2021 · 15 comments
Closed

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

mirisuzanne opened this issue Feb 13, 2021 · 15 comments

Comments

@mirisuzanne
Copy link
Contributor

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?

@matthew-dean
Copy link

matthew-dean commented Feb 13, 2021

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.

@ausi
Copy link

ausi commented Feb 13, 2021

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.

@andruud
Copy link
Member

andruud commented Feb 15, 2021

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.

@mirisuzanne
Copy link
Contributor Author

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?"

@argyleink
Copy link
Contributor

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?

@mirisuzanne
Copy link
Contributor Author

@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) { … }

@argyleink
Copy link
Contributor

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;
  }
}

@una
Copy link
Contributor

una commented Apr 28, 2021

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.

@argyleink
Copy link
Contributor

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.

@mirisuzanne
Copy link
Contributor Author

@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?

@mirisuzanne
Copy link
Contributor Author

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).

@pnkapadia64
Copy link

@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.

@mirisuzanne
Copy link
Contributor Author

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).

@pnkapadia64
Copy link

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

@mirisuzanne
Copy link
Contributor Author

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
Projects
None yet
Development

No branches or pull requests

7 participants