Skip to content

Allow applying style rules to the container itself (especially with style querries) #10744

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

Open
LcsGa opened this issue Aug 15, 2024 · 10 comments

Comments

@LcsGa
Copy link

LcsGa commented Aug 15, 2024

Like :scope in @scope blocks or also :host in web components, adding a :container in @container especially with style querries would be an amazing addition. It would let us style a container itself based on any style rule/ custom properties applied to it without the need for wrapping it inside of another component that would be needed only for that.

Sorry, I couldn't find any related label/existing issue about it. I hope I didn't mess up 😅

@LcsGa LcsGa changed the title Allow applying style to the container itself with style querries Allow applying style rules to the container itself with style querries Aug 15, 2024
@LcsGa LcsGa changed the title Allow applying style rules to the container itself with style querries Allow applying style rules to the container itself (especially with style querries) Aug 15, 2024
@romainmenke
Copy link
Member

This has some overlap with my proposal to add an @element at rule.

I agree that needing to create otherwise useless elements in markup, purely for style queries is an anti-pattern.

Maybe even both proposals are useful for subtly different cases?

@element

@element style(--color: pink) {
  .foo {
    background-color: pink;
  }
}

.foo matches elements with class .foo and a custom prop --color with value pink

:container

@container style(--color: pink) {
  :container {
    background-color: pink;
  }
}

:container matches containers with a custom prop --color with value pink

@LcsGa
Copy link
Author

LcsGa commented Aug 16, 2024

Indeed, that looks pretty similar (btw, sorry about that I couldn't find it)!
About your @element use case where you wanna select elements that match your style querry + has the .foo class, I guess you could also achieve the same result like this:

@container style(--color: pink) {
  :container.foo {
    background-color: pink;
  }
}

@romainmenke
Copy link
Member

romainmenke commented Aug 16, 2024

Correct :)

The subtle differences I was referring to are more with this kind of case:

<div class="parent" style="--color: pink">
  <div class=child>
    hello
  </div>
</div>
@container style(--color: pink) {
  :container {
    background-color: rgb(from pink r g b / 0.3);
  }
}

Would :container match both the .parent and .child elements?
I would expect it to.


<div class="parent" style="--color: pink">
  <div class=child>
    hello
  </div>
</div>
.parent {
  container-name: a-container;
}

@container a-container style(--color: pink) {
  :container {
    background-color: rgb(from pink r g b / 0.3);
  }
}

Here it should only match .parent, right?


With @element this nuance doesn't exist.
It would always match any element with --color: pink;

In that way a :container pseudo might be a better approach?

@LcsGa
Copy link
Author

LcsGa commented Aug 16, 2024

In your case I would expect only the parent to be selected as, currently (if I'm not wrong) @container sort of "scopes" the CSS declarations on the matching containers.
The thing I'm not sure about is if the child also matches the query as it inherits the custom prop from its parent.

@LcsGa
Copy link
Author

LcsGa commented Aug 16, 2024

I cannot test properly my theory (the @container sort of "scoping" the css declaration to the container directly matching the querry) but, in my opinion, :container should only match the containers that directly match the query.
Thus, it should select only the parent in your example (at least, that's what I would find the most logical)

@mirisuzanne
Copy link
Contributor

I don't think it's viable for :container to be a selector, because that confuses the order in which things happen.

Unlike @scope, the @container rule does not have any impact on selector matching. Containers are discovered by first matching the selectors inside the conditional rule, and then each matched element has to find a relevant ancestor container to query. The query – eg style(--color: pink) – is applied as a conditional test after selector matching is complete.

There is no way to select elements based on their styles, since selection has to happen in order to style the elements. So at the point where we would try matching :container elements, we don't yet know which elements are containers. And we can't find containers until we know what elements are looking for a container to query.

But styles are resolved outside-in – parent styles have to resolve in order for inheritance on child elements – so it is possible (after selection) to make a child style conditional on a parent/ancestor style.

This is why container queries didn't use a selector syntax in the first place.

@PupilTong
Copy link

@mirisuzanne
If UAs implement if() #10064
Seems it's possible to do the same things just like styling elements based on computed value of custom properties

@mirisuzanne
Copy link
Contributor

@PupilTong I'm not saying it would be impossible to have a self-styling feature - that is what if() does – but that it can't be a new selector in a container rule. The if() function relies on resolving the value late, and makes properties Invalid at Computed Value Time. That is to say: selection has already finished, the entire cascade has completed, and other values set for the property have been discarded. Any fallback values need to be explicit. It's clear how to do that property-by-property in a function (we already have var() as prior art) but it's less clear how that would be handled at a block level.

@PupilTong
Copy link

@mirisuzanne Thanks! Now I understood the reason about it.

Actually What we need (#10190) is something like selecting the direct children of a container. Will a :container-style(--var:val) selector be more reasonable for Selector System?

@PupilTong
Copy link

In addition, we could still do this:

@container style(--use-bg-color: true) {
  * {
   background-color: var(--bg-color);
  }
}
@container not style(--use-bg-color: true) {
  * {
   background-color: initial;
  }
}

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

4 participants