csswg-drafts
csswg-drafts copied to clipboard
[css-conditional] Make CSSSupportsRule expose whether its condition is met
You currently can't tell directly from a CSSSupportsRule whether the condition is actually fulfilled or not. To do that you have to use CSS.supports(cssSupportsRule.conditionText)
.
Therefore I suggest to add a getter to CSSSupportsRule (or rather to CSSConditionRule which is overwritten by the derived interfaces) that returns whether the condition is met or not, e.g supported
or fulfilled
.
Sebastian
Sounds reasonable to me
I think that's a very straight-forward addition. So, setting Agenda+ to discuss it in a call.
Sebastian
Maybe .isTrue
or something else more generic? I think it would make sense to add this to CSSConditionRule generically, not just to CSSSupportsRule.
MediaQueryList
has .matches
, maybe that's good enough?
(as a name, I mean)
But on CSSConditionRule
it's a bit tricky, because container rules need the element as an input too, to know whether the condition matches.
With the changes for CSSContainerRule
discussed in #7033, this can stay a simple getter because the query container is determined by the container name and query.
Sebastian
matches
rather refers to matching elements, though in case of CSSSupportsRule
this is not the case. isTrue
sounds a little too generic to me regarding the derived rules. Maybe isConditionMet
or something? Anyway, I don't have a strong opinion on the name.
Sebastian
Maybe met
?
But regardess of naming yes, I think we should have such a getter
The CSS Working Group just discussed CSSSupportsRule should expose bool
, and agreed to the following:
-
RESOLVED: Add .matches to CSSMediaRule and CSSSupportsRule
The full IRC log of that discussion
<TabAtkins> Topic: CSSSupportsRule should expose bool<faceless> present- (got to dash)
<TabAtkins> github: https://github.com/w3c/csswg-drafts/issues/4240
<astearns> ack chris
<TabAtkins> chris: Perfectly reasonable to have a getter to know whether the condition matches
<TabAtkins> chris: Most discussion is bikeshedding the name, not whether it shoudl exist or not
<TabAtkins> chris: Interested if there's arguments against
<fantasai> TabAtkins: Definitely should exist, could recreate by running it through existing APIs
<astearns> ack dbaron
<emilio> q+
<TabAtkins> dbaron: agree it shoudl exist. At some point when I drafted the IDL I made a common base class for supports and media. Might not exist now, but if we make a bool like this we should make it common between the rules
<astearns> ack fantasai
<TabAtkins> STrong agree
<TabAtkins> fantasai: Yeah, suggest putting it on CSSConditionRule superclass, which does exist
<TabAtkins> fantasai: emailio pointed out it's tricky on @container rules since they rely on the element being matched as well
<TabAtkins> fantasai: But we should have consistent naming even if it's individual methods on each subclass
<astearns> ack emilio
<TabAtkins> emilio: Yeah, superclass is tricky because CQs shouldn't have it
<TabAtkins> emilio: I think the API for CQs would look a bit different, would be a function that takes an element, and it would force layout, etc
<TabAtkins> emilio: So I think it should exist, but not on the superclass
<TabAtkins> TabAtkins: I suggest we just define a getter on the subclasses it makes sense for, yeah
<fantasai> ...
<fantasai> TabAtkins: .matches works, already on MQlist
<fantasai> TabAtkins: meaning carries over well
<TabAtkins> emilio: fwiw, "matches" is what we use internally in Gecko
<TabAtkins> chris: .met would work, but okay with .matches too
<TabAtkins> fantasai: Happy to go with .matches since MQList already has it
<chris> fine with matches
<fantasai> s/.../fantasai: Sure, but what's it called?/
<TabAtkins> astearns: So proposed resolution to add .matches to the relevant conditional rules
<TabAtkins> dholbert: Q about subclasses vs superclass
<TabAtkins> dholbert: Can we put in an intermediate superclass so it's shared?
<fantasai> TabAtkins: IDL supports this, but it is an observable change
<chris> emilio could you propose some IDL in the issue?
<fantasai> TabAtkins: we thought it would be useful for ConditionalRule, but less clear if it's worth it for this
<fantasai> astearns: Which rules are affected?
<emilio> chris: sure, `readonly attribute boolean matches;` on the two individual rules?
<fantasai> TabAtkins: @media and @supports
<TabAtkins> yeah, that's the IDL
<TabAtkins> RESOLVED: Add .matches to CSSMediaRule and CSSSupportsRule
Late regrets that I couldn't make it to the call!
emailio pointed out it's tricky on
@container
rules since they rely on the element being matched as well
Unfortunately, my answer to that wasn't discussed on the call. And I think it would really be best if we added this to the CSSConditionRule
superclass instead. So all classes deriving from it have it available.
As mentioned in my previous comment, with the changes to CSSContainerRule
discussed in #7033 the related element is determined by the other attributes of that interface. So .matches
could be exposed as a simple getter there as well.
Sebastian
@SebastianZ how do you get the query container? The container rule can be matched against different containers, I don't understand how that can work magically.
As mentioned in my comment there. The CSSContainerRule
would have two attributes reflecting the name and the query. Using those, matches
can be a getter there as well.
So, matches
will give you the information whether the container query matches a query container at the time of execution. It doesn't tell you whether it matches against a specific element or which query container it matches.
Sebastian
Btw. matching a container query against a specific element is covered by #6205.
Sebastian
As mentioned in my comment there. The
CSSContainerRule
would have two attributes reflecting the name and the query. Using those,matches
can be a getter there as well.
Can you elaborate how that would work? Given a name + query pair you can't get an element, since container names are not guaranteed to be unique, which container you choose depends on which element are you styling.
I totally disregarded that @container
rules are special in that whether they match depends on the elements matched by the style rules' selectors within them.
So you're right, @emilio, a .matches
getter isn't possible that way, sadly.
Sebastian
While looking into this, I realized that CSSMediaRule.matches
isn't quite easy either... A media rule might be disconnected from a document, accessed from another document, etc.
So at least we need to define what document we match against. The incumbent (caller) document? The document that the media rule is on, if any?
So that at least needs a spec clarification + test (easiest way to test this would be a same-origin iframe calling into CSSMediaRule.matches
on a stylesheet originally from the parent document or vice-versa).
@tabatkins thoughts?
I wonder whether that's enough of a non-edge-case to say that we should just abandon this idea and recommend window.matchMedia(mediaRule.mediaText)
instead.
I'd say .matches
should always work in the context the related at-rule is in. I.e. if a media rule is disconnected from a document, conditions requiring a document to properly evaluate like (width > 1000px)
would always return false
. (Or it might even return undefined
as that is what it is, but then it wouldn't have a clearly boolean return value.) Though preference-based conditions like (prefers-reduced-motion)
would still evaluate normally.
If it's attached to a document, it is always evaluated against that document, even when accessed from another document. In other words, it should behave the same as its @media
counterpart.
Though I wonder what the use cases are for checking whether a media rule matches when it or the stylesheet it is in is disconnected.
CSSSupportsRule.matches
has a much clearer use case in that case.
Sebastian
Proposed edits, @SebastianZ and @emilio let me know if this works okay:
diff --git a/css-conditional-3/Overview.bs b/css-conditional-3/Overview.bs
index 35f48ca58..9324b8637 100644
--- a/css-conditional-3/Overview.bs
+++ b/css-conditional-3/Overview.bs
@@ -793,6 +793,7 @@ The {{CSSMediaRule}} interface represents a ''@media'' at-rule:
[Exposed=Window]
interface CSSMediaRule : CSSConditionRule {
[SameObject, PutForwards=mediaText] readonly attribute MediaList media;
+ readonly attribute bool matches;
};
</pre>
@@ -808,6 +809,14 @@ js/CSSConditionRule.html
for the list of media queries specified with the ''@media'' at-rule.
<wpt title=".media returns a MediaList matching the @media condition."></wpt>
+ <dt><code>matches</code> of type {{bool}}, readonly
+ <dd>The <code>matches</code> attribute returns true
+ if the rule is in an stylesheet attached to a document
+ whose {{Window}} matches this rule’s {{CSSMediaRule/media}} [=media query=],
+ and returns false otherwise.
+
+ ISSUE: Stylesheet attached to a document isn't a well-defined concept right now.
+
<dt><code>conditionText</code> of type <code>CSSOMString</code> (CSSMediaRule-specific definition for attribute on CSSConditionRule)
<dd>The <code>conditionText</code> attribute (defined on the <code>CSSConditionRule</code> parent rule),
on getting, must return the value of <code>media.mediaText</code> on the rule.
@@ -827,6 +836,7 @@ The {{CSSSupportsRule}} interface represents a ''@supports'' rule.
<pre class='idl'>
[Exposed=Window]
interface CSSSupportsRule : CSSConditionRule {
+ readonly attribute bool matches;
};
</pre>
@@ -836,6 +846,10 @@ js/CSSConditionRule.html
<wpt title="CSSSupportsRule represents an @supports rule."></wpt> -->
<dl class='idl-attributes'>
+ <dt><code>matches</code> of type {{bool}}, readonly
+ <dd>The <code>matches</code> attribute returns the evaluation of
+ the [=CSS feature query=] represented in {{CSSConditionRule/conditionText}}.
+
<dt><code>conditionText</code> of type <code>CSSOMString</code> (CSSSupportsRule-specific definition for attribute on CSSConditionRule)
<dd>The <code>conditionText</code> attribute (defined on the <code>CSSConditionRule</code> parent rule),
on getting, must return the condition that was specified,
@fantasai looks good to me.
Totally missed your comment, @fantasai. Sorry! It also looks good to me.
Sebastian