w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.49k stars 660 forks source link

[css-conditional] testing support of properties and values with partial implementations #3559

Open rachelandrew opened 5 years ago

rachelandrew commented 5 years ago

There are a few places where @supports is unable to help authors as the property and value they want to test for is supported by the user agent, but not in the context they want to use it.

The obvious one (and where it keeps coming up at the moment) is testing support of any of the gap properties column-gap, row-gap or gap. I can test for support of column-gap and every browser will tell me it has support, however if I then try to use it in flexbox, I will only get a gap in Firefox, as that is the only user agent to have an implementation right now.

This means authors can't create a nice fallback with margins, then removing the margin on testing for support. It is likely that other box alignment properties - perhaps as browsers start to implement them for block layout, will have the same issue.

Other places this might be an issue are for fragmentation, I might want to test if fragmentation properties are available in a certain context.

It feels as if we need a way to ask for support of, for example, column: gap in display: flex. I don't know if that is even feasible in implementations, but it seems that this is likely to continue to be an issue as specs become more modular.

I found an older issue which also refers to partial implementations not being testable: https://github.com/w3c/csswg-drafts/issues/1167

AmeliaBR commented 5 years ago

This also comes up all the time when dealing with properties from SVG that are crossing over into CSS box layout & vice versa. For things like filter we have had browsers that support one syntax for SVG elements only, and a different syntax for everything except SVG elements, and both syntaxes would pass an @supports test.

(Aside: I really wish the spec for gap had strongly encouraged browsers not to support the generic property name until they implemented support for the generic feature. I was rather disappointed when browsers rushed to ship the easy parser implementation of the synonym before addressing their layout code, for this reason. But the broader issue still remains.)

nigelmegitt commented 5 years ago

Perhaps the request should be that, in the absence of finer granularity queries, @supports should return false unless the implementation support exists in all usage contexts.

rachelandrew commented 5 years ago

"Perhaps the request should be that, in the absence of finer granularity queries, @supports should return false unless the implementation support exists in all usage contexts."

That might be a bit more useful, however then there is a property and value that the author knows is supported, but seems to be returning false. At that point we are asking them to understand all possible contexts in which that property vould be used.

The fragmentation properties are probably better to look at here than gaps, which are likely to be implemented - say if we did a specific masonry layout or something.

At the moment a property like break-before: avoid is specified for multicol, paged media, and regions. Assuming a wonderful world in which the property was supported in multicol and paged media, regions is a long way off, and probably won't happen in the current form. Which would mean that testing for break-* properties would be useless for the foreseeable future, as we don't have Regions so it can't be implemented in them. Most authors aren't even going to know about Regions and therefore why the property is returning false.

tabatkins commented 5 years ago

There's no good solution to this that doesn't break the fundamental value proposition of @supports, which is that, since it's based purely on "does it parse", it requires no special table of return results in the browser, which history has shown us is destined to become some combination of stale and lies. I'm strongly against anything that tries to get "special-case" answers like this that aren't backed by a simple "try to parse it" mechanism.

(I definitely feel the pain, but it's not solveable here without making things overall worse.)

ghost commented 5 years ago

Is it feasible to have @supports defined in the context of another selector? Something like:

body {
display: flex;
margin: 2rem;

  @supports(column:gap) {
  margin:0;
  column: gap;
  }
}

This way, the parsing stays simple and uses basic 'does it parse' logic.

jonjohnjohnson commented 5 years ago

Related...

Though @supports(position:sticky) currently parses for all major vendors, Blink, which has the largest market share, still doesn't *fully support the value.

@SelenIT https://github.com/w3c/csswg-drafts/issues/2155#issuecomment-410978077

It seems that for some reason Chrome reverted their changes for fixing position:sticky behavior on thead element.

@tabatkins I understand your sentiment about making things worse, but currently the often most efficient ways to deal with false @support scenarios are selector hacks, even if...

@dbaron https://github.com/w3c/csswg-drafts/issues/3051#issuecomment-416084354

Using hacks that assume support for X is equivalent to support for Y is a bad idea if those hacks are targeting current browsers. Such hacks are safe only if the features are implemented in all current browsers and the equivalence holds in the old versions where they're not implemented.

And the resolution in https://github.com/w3c/csswg-drafts/issues/3051 seems to express an opposite stance, getting rid of the ability to use some of these selector hacks.

tabatkins commented 5 years ago

Yup, selector hacks (or other browser-selection mechanisms) aren't great, but again, we already know that manually-maintained lists of support eventually rot, every single time it's ever been tried.

So it's a choice of somewhat encouraging bad individual-author behavior, or speccing bad UA behavior. I think the former does less damage overall.

simlawr commented 5 years ago

Given, gap properties already exist for grid i.e. grid-gap, grid-column-gap, grid-row-gap, aliases for gap properties could also be added for Flexbox. This would enable detection for gap support specifically in Flexbox using the existing Feature Query syntax. For example:

@supports (flex-gap: 10px) {
  div {
    display: flex;
    gap: 10px;
  }
}

@supports not (flex-gap: 10px) {
  div {
    display: flex;
    margin: 10px;
  }
}

I'm not sure however, how appropriate this approach would be regarding other properties.

It certainly seams that as there is greater cross-pollination between specifications, this kind of situation is likely to become more prevalent and a sustainable solution would be nice.

SebastianZ commented 4 years ago

@simlawr That solution would somewhat cleanly solve the current issue regarding the -gap properties, as authors can easily understand it. Though I believe it doesn't scale because it means that for every new property that is shared between different contexts, there needs to be an alias introduced only for the purpose of feature detection. That burdens authors, as they have to remember the aliases when doing feature detection, implementors, as they have to implement the aliases only applying in certain contexts, spec. authors because they will have to remember to add those aliases when the property is used in different contexts, and documentation writers because they will also have to cover those aliases.

Unfortunately, I don't have a better solution for this. There is probably no automated way of doing this kind of feature detection.

Sebastian

Dan503 commented 4 years ago

I really like Rachel's original suggestion although I would change it to "with" rather than "in" because you are more looking for a generic relationship between the 2 rather than a parent/child relationship.

@supports (gap: 1px) with (display: flex) {
   /* css code */
}

It doesn't sound that impossible for the computer to recognise.

The browser would need to check if both of the following conditions are true:

If not then it returns false.

I am probably grossly simplifying the problem though. 😅

foolip commented 4 years ago

In the case of flex gap specifically, is there any workaround for web developers to detect support for it? It's only recently shipped in Chrome and even more recently landed in Safari Technology Preview, and without feature detection people will need to wait for another 3 years or so to be able to simply assume it will work.

Dan503 commented 4 years ago

In the case of flex gap specifically, is there any workaround for web developers to detect support for it?

Yes, there is but you have to use JS to detect it.

The following is based on this blog post: https://ishadeed.com/article/flexbox-gap/

// Set up a cache to prevent a DOM element from getting created for every use of the function
let isSupported;

function checkFlexGapSupport() {
        // Use the cached value if it has been defined
    if (isSupported !== undefined) {
        return isSupported
    }

    // Create a flex container with row-gap set
    const flex = document.createElement('div')
    flex.style.display = 'flex'
    flex.style.flexDirection = 'column'
    flex.style.rowGap = '1px'
    flex.style.position = 'absolute'

    // Create two, elements inside it
    flex.appendChild(document.createElement('div'))
    flex.appendChild(document.createElement('div'))

    // Append to the DOM (needed to obtain scrollHeight)
    document.body.appendChild(flex)

        // Flex container should be 1px high due to the row-gap
    isSupported = flex.scrollHeight === 1

        // Remove element from the DOM after you are done with it
    flex.parentNode.removeChild(flex)

    return isSupported
}
foolip commented 4 years ago

Thanks @Dan503! I guess what people then typically to do is set a class on the body element and use that instead of @supports?

tremby commented 4 years ago

That used to be very common, don't know if it still is these days. Often people would use a tool like Modernizr to do that.

marcebdev commented 3 years ago

Is there any development on doing this either through an alias or an improvement to @supports? Using gap in the context of Flexbox is virtually non-existent to me since it's not checkable.

I've stumble upon the above modified Modernizr check. For simple cases it might actually be easier to use a mixin through some CSS framework to "mask" gap so for instance calling a mixing gap(value) to something like the over-simplified snippet below for demonstration purposes. After all, a fix for browsers still not supporting gap would be needed.

& > :not(:last-child) {
  margin-right: value;
}

BUT you do have to account for Flexbox direction and wrapping, so something more like flex-layout(value, direction, wrap) to make it more generic which can quickly make it a real pain vs using JS & DOM manipulation.

Resorting to either DOM manipulation or ignoring the feature I do hope there's some mediation without having to wait maybe another few years until gap is pretty safe. It seems following how @supports works generics, such as gap will simply need case-specific aliased names or they won't be able to be implemented correctly. It'd be quite unfortunate to see Modernizer forced to evolve into a bandaid of sorts.

koller18 commented 2 years ago
@supports not (image-orientation: from-image) {
    .flexbox {
        margin: 0.5em auto;
    }
}
WebMechanic commented 2 years ago

@koller18 how's your code sample related to the subject? 🙄 It's not even a hack to "assume" parallel flexbox+gap support for any browser past + present.

SebastianZ commented 2 years ago

I just had an idea for a solution to this: Custom @supports rules.

Similar to script-based custom media queries, we could introduce custom @supports rules. Those would allow to register some JavaScript worklet executing code like the one suggested by @Dan503.

The big advantage would be that authors could use @supports in their CSS context. The only part in JS would be the check for the support. Another advantage would be the great flexibility allowing authors to create any kind of check, possibly even beyond CSS related things. The downsides of this proposal are that executing that code can slow down CSS evaluation and worklets generally don't have access to the DOM. Though I'd say the slow-down in evaluation is neglectable because the script only has to be executed once when parsing the CSS. The bigger issue which I didn't give much thought yet is probably the DOM access. I assume the access probably needs to be restricted somehow to avoid performance and/or privacy problems.

Sebastian

SebastianZ commented 2 years ago

To make my previous post a bit clearer, here an example for how I imagine this to work:

JS:

// gapInFlexboxSupport.js
class GapInFlexboxSupport {
  name: '--gap-in-flexbox',
  check: () => {
    // Create a flex container with row-gap set
    const flex = document.createElement('div');
    flex.style.display = 'flex';
    flex.style.flexDirection = 'column';
    flex.style.rowGap = '1px';

    // Create two, elements inside it
    flex.append(document.createElement('div'), document.createElement('div'));

    // Append to the DOM (needed to obtain scrollHeight)
    document.body.append(flex);

    // Flex container should be 1px high due to the row-gap
    return flex.scrollHeight === 1;
  }
}

registerSupportCheck(GapInFlexboxSupport);

// In document
CSS.supportsWorklet.addModule('gapInFlexboxSupport.js');

CSS:

@supports (--gap-in-flexbox) {
  .flex {
    display: flex;
    gap: 8px;
  }
}

Regarding performance and especially privacy concerns, we could create a worklet-specific document. (This is also what I expect in my example code.) So there is no relation to the actual document. Though this would, of course, also limit the possibilities for this feature.

Of course this also requires a way to check whether custom @supports rules are supported, i.e. #6966.

Sebastian

romainmenke commented 2 years ago

In the case of flex gap specifically, is there any workaround for web developers to detect support for it? It's only recently shipped in Chrome and even more recently landed in Safari Technology Preview, and without feature detection people will need to wait for another 3 years or so to be able to simply assume it will work.

Much longer than this :/ 2 years have past since this statement and at work we still do not allow gap (in flex elements) because we can not write fallbacks. We typically support 5-8 years of browser versions.

If @supports (flex-gap: 1px) {} was available in the next version of each browser we could start using it.

We don't care that there are some versions with native support that would get the fallback. We do care about the browsers without native support.


That it is the 4th most searched for feature on caniuse shows how big a problem this is for stylesheet authors :/

Screenshot 2022-08-19 at 19 37 02
SebastianZ commented 2 years ago

Agenda+ to discuss my suggestion to add custom @supports checks and also the other suggestions mentioned here.

Sebastian

romainmenke commented 2 years ago

I have some concerns with custom @supports checks. Needing a sub resource to check if a single property is usable in a single context can quickly escalate.

It requires authors to work around more issues instead of directly solving the issue at hand.

In my opinion this places too much burden on stylesheet authors.

SebastianZ commented 2 years ago

All good questions! But they apply to all features that use worklets, e.g. several Houdini APIs, and the latter three also to external style sheets. And, as mentioned before, the proposed worklet would only need to run once. So at least in comparison to Houdini worklets which run many times consecutively it's cheap regarding performance.

Sebastian

romainmenke commented 2 years ago

For Houdini features I do not mind the tradeoff. The "user story" is straightforward here.

I want to do something browsers normally can't, so I reach for an API which enables custom behaviour.

Custom @supports for native properties are a different case in my opinion. It is not intuitive or obvious that stylesheet authors needs to create a supports worklet and think about the issues listed above when they actually want to use a standard property.


The same however is true for @supports (flex-gap: 1px) or @supports (gap: 1px) in (display: flex).

There is no clear signal to stylesheet authors that @supports (gap: 1px) will sometimes be true when they would expect it to be false.

Linters/build tools could warn when they encounter ambiguous @supports rules to help stylesheet authors.

SebastianZ commented 2 years ago

There is no clear signal to stylesheet authors that @supports (gap: 1px) will sometimes be true when they would expect it to be false.

Yes, authors still need to learn about this context relation and CSS itself cannot change this, unfortunately. So this issue focuses on a way to at least make it possible to detect context related support of features.

As @tabatkins pointed out earlier, user agent creators want to avoid a situation in which they have to maintain a table of context relations. Custom @support checks take away that burden from them and still provide authors with the possibility to check for context related support.

Linters/build tools could warn when they encounter ambiguous @supports rules to help stylesheet authors.

That's definitely true. And I am pretty sure that some of them already do that. But that's out of scope of the specifications, of course.

Sebastian

css-meeting-bot commented 2 years ago

The CSS Working Group just discussed Testing support of partial implementations.

The full IRC log of that discussion <fantasai> Topic: Testing support of partial implementations
<fantasai> github: https://github.com/w3c/csswg-drafts/issues/3559
<fantasai> astearns: Sebastien added some comments, unable to join in person
<fantasai> astearns: he has a specific suggestion ...
<astearns> this comment https://github.com/w3c/csswg-drafts/issues/3559#issuecomment-1114545949
<fantasai> rachelandrew: This came uporiginally because of the gap property
<fantasai> rachelandrew: originally defined for grid layout, later expanded to flexbox
<fantasai> rachelandrew: but can't test within @supports
<fantasai> rachelandrew: so can't e.g. provide a fallback margin
<fantasai> rachelandrew: unsure where it will come up win future, but for specs like alignment which applie to lots of things could come up
<fantasai> rachelandrew: so that's why opened the issue, for testing whether property X roks in context Y
<fantasai> s/roks/works/
<fantasai> rachelandrew: Idk how likely it is to appear in the future
<astearns> ack fantasai
<Zakim> fantasai, you wanted to ask to review use cases and to
<fantasai> fantasai: Another context is alignment properties applying to abspos or block containers
<chris> rssagent, here
<fantasai> fantasai: and fremy had suggested gap applying to tables, so that's another place
<chris> rrsagent, here
<RRSAgent> See https://www.w3.org/2022/09/16-css-irc#T20-38-42
<fantasai> astearns: we have general issue of interactions that are difficult to test
<fantasai> astearns: sebastian had specific suggestion of allowing custom support rules
<fantasai> astearns: that would run author JS to check for a particular thing they wan'ted to test
<fantasai> astearns: sebastian asked whether this is a reasonable way forward, is it possible in browsers
<fantasai> heycam: No real obvious time to run that script
<fantasai> heycam: would want to run it only once
<fantasai> heycam: maybe at the time the stylesheet is loaded could run it?
<fantasai> heycam: it feels weird to have some script run at some point for that
<fantasai> heycam: I do feel like you do want a traditional feature-testing way of checking this
<fantasai> heycam: e.g. test whether gap on table, checking whether it has some effect on the size of the element
<fantasai> heycam: but idk what's a concise way to run that in a query string
<heycam> fantasai: so far most of these are dependent on your formatting context or box type
<TabAtkins> q+
<heycam> ... so it's not that you want to check interactions with other properties, but specifically whether properties apply to specific types of boxes
<astearns> ack TabAtkins
<fantasai> TabAtkins: On subject of well-defined time to run, this is the same problem as wanting custom MQ
<fantasai> TabAtkins: so we could just run it on that
<fantasai> TabAtkins: no difference between writing @media --flex-gap
<fantasai> TabAtkins: which you set at page load
<fantasai> TabAtkins: vs in supports
<fantasai> TabAtkins: if we feel it's needed for usability, maybe separate registry
<fantasai> TabAtkins: but run script once and run well-defined time, already have proposal to solve
<heycam> fantasai: for the usability aspect of it, there's been proposals of a generic if statement
<heycam> ... rather than having custom MQs, you could have a more generic syntax in an if statement
<astearns> ack fantasai
<heycam> ... so you could do it in a MQ, or in an if
<fantasai> s/if statement/@if statement/
<fantasai> astearns: Maybe this is enough feedback to satisfy for now?
<fantasai> astearns: anyone else to weigh in?
<fantasai> dholbert: curious what DOM these queries run in
<fantasai> dholbert: does it persist
<fantasai> TabAtkins: answer is, dependes on what you are talking about
<fantasai> TabAtkins: if you're doing custom MQ, it's whatever you want. YOu're just running JS and updating a map
<fantasai> TabAtkins: that's attached to the document object
<fantasai> TabAtkins: that'll be available to any stylesheets attached to that page
<fantasai> TabAtkins: if doing something else, depends on specifics
<fantasai> astearns: let's leave this issue here, and see if we make more progress in issue itself
laverdet commented 1 year ago

I found inset approximates support for flex gap pretty well. Compare browser comatibility data between the two: https://developer.mozilla.org/en-US/docs/Web/CSS/gap#browser_compatibility https://developer.mozilla.org/en-US/docs/Web/CSS/inset#browser_compatibility

@supports (inset: 0) will not target any browsers which don't support flex gap. The @supports check will also not target some browsers which do support flex gap: Chrome [84, 85, 86], Firefox [63, 64, 65], or Opera [70, 71, 72]. Support in WebKit matches perfectly.

If you're using mdn browser compat data to drop polyfills from your stylesheets it works well to avoid bundling clumsy margin-based polyfills.

Obviously I would love to see a fix for the underlying standards issue but this is a solution we can use today for the flex case.

bramus commented 10 months ago

With align-content on block layout becoming available in browsers, this problem is getting some new life blown into it.

In https://css-irl.info/how-do-you-vertically-centre-an-element-in-css/, @michebarks wrote:

One thing that concerns me, is that this seems to fall into that tricky area where it becomes impossible to test for browser support and provide fallbacks using a feature query — much like gap when it was implemented for flexbox. As align-content is well-supported for Grid and flexbox, the feature query doesn’t help us here.

@supports (align-content: center) {
 /* This will resolve true for any browsers supporting the property in grid or flexbox */
}

It would be great to see some improvements to how feature queries can handle these sorts of situations.

kizu commented 10 months ago

I was recently experimenting with some unrelated things, where I used inline-blocks for a layout, and I really missed the absence of a gap in the normal flow. If we did have an ability to detect partial implementations like this, it could be more likely that we could get it (“normal flow gap”), as well as other similar cases (extending some very specific property to work in different contexts).

The absence of the ability to easily detect the flex + gap support is also a reason why our design system currently has a legacy workaround for the flex “gap” using margins: it is not trivial to migrate to native gap.

I really like the idea of using something like (gap: 1px) with (display: flex) as a way to test how multiple properties & their values interact.

Though I can see the challenge in how that could be defined, and for authors it might be confusing trying to understand which pairs of properties they could use in @supports like that.

We don't have many places like this outside of gap, so I think having a “hardcoded” syntax like @supports (gap: 1px !flex) could work. Maybe not exactly like this, but the idea is for any properties+value pairs that get changes in the specs/implementations that require different type of support detection, to have an explicitly defined “supports flag” which could be used only as a part of @supports.

I do think this case is exceptional enough that not coming up with an abstract “ideal” solution is worth it here, and in this case, it is better to get a working solution sooner rather than later.

dbaron commented 10 months ago

I think @tabatkins's https://github.com/w3c/csswg-drafts/issues/3559#issuecomment-458734231 (which I agree with) was a good explanation of why we don't want a general solution here.

However, I think it might be reasonable to add specific, one-off solutions when we think they're important enough. They'd need to be for significant enough features that we'd be willing to add an extra keyword to CSS for them, and that an implementor wouldn't miss that it needed to be implemented, and that we'd be willing to write specific web-platform-tests to verify and monitor the results closely to make sure the rollout doesn't go wrong. And we could probably choose reasonably verbose keywords.

For example, for the two examples discussed recently we could add something like gap-on-display-flex or align-justify-properties-on-blocks keywords so that it would be possible to write:

@supports feature(gap-on-display-flex) {
  /* ... styles ... */
}

(It's likely too late for the former to be useful at this point, but the latter is something we really could consider now.)

SebastianZ commented 10 months ago

I'm not too happy that we can't find a general solution for that, though I do like this pragmatic approach. This allows us to make progress on this topic and we do have to make fast progress to avoid repeating the same mistake as with gap in Flexbox.

As implementation of align-content for block containers has begun on Gecko and Blink and seems to already be finished in WebKit (@fantasai Is it going to ship, already?), we should decide on this soon and push implementations to ship detection for it along with the feature.

Sebastian

fantasai commented 10 months ago

Even if we're going to do one-off keywords, I think we need a consistent syntax for property-X-applies-to-display-type-Y.

css-meeting-bot commented 9 months ago

The CSS Working Group just discussed [css-conditional] testing support of properties and values with partial implementations, and agreed to the following:

The full IRC log of that discussion <flackr> dbaron: one of the design goals of @supports is we don't want to require impls to maintain large sets of data about what is supported that's separate from the code which supports the thing
<flackr> dbaron: in the past doing this tends to result in them getting out of sync
<flackr> dbaron: so we originally defined it in terms of property syntax being accepted, and is in sync with a certain definition of whether features are supported
<Rossen_> q?
<flackr> dbaron: @supports has not been very effective for certain types of interactions, e.g. a propery that was once only supported on flexbox being supported elsewhere
<flackr> dbaron: people have wanted a syntax for these sorts of interactions in a general way. There's no proposal for a general syntax that satisfies the original design constraint
<flackr> dbaron: The proposal I put in the issue, is that we don't try to solve this generally, but add a solution that we use in rare cases where we feel it's important with one-off keywords
<flackr> dbaron: I propose calling this a feature function where we add a keyword for a particular interaction
<flackr> dbaron: The idea is we'll use this rarely, e.g. 1 per year is okay, 1 per month is probably too much
<florian> q+
<emilio> q+
<flackr> dbaron: I'd like feedback on the general idea, we can bikeshed names
<Rossen_> ack florian
<oriol> q+
<flackr> florian: one of the other reasons for original design constraint is not just that they might eventually get out of sync but could initially be out of sync if the detection is done independently
<flackr> florian: you might do one and forget to do the other
<flackr> florian: this problem remains with the alternate proposal, as you might forget to add the detector
<flackr> dbaron: I agree this is a concern, this is part of the reason we want to do it rarely and have process / tests to make sure we don't forget
<Rossen_> ack emilio
<flackr> emilio: I agree with the concern, but having an escape hatch for this makes sense.
<rachelandrew> q+
<flackr> emilio: the thing florian mentioned has also happened in reverse accidentally, e.g. shipping & selector before nesting support??
<flackr> emilio: having this general one-off escape hatch makes sense
<Rossen_> ack oriol
<flackr> oriol: i'm not a big fan, these features when they're used will assumed to be false initially and become true and authors will stop checking them. But it's something we'll add to the platform and will need to keep these checks even though they're sort of obsolete after a while
<flackr> oriol: this is an ongoing cost needing to keep around
<Rossen_> ack rachelandrew
<bkardell_> q+
<flackr> rachelandrew: I quite like this. In an ideal world we'd have a more general thing, but this doesn't come up often. This feels like a pragmatic solution to an edge case that comes up once in a while.
<flackr> rachelandrew: this gets developers what they need / are asking for.
<flackr> rachelandrew: it's also easy to explain to devs
<bramus> +1 to what rachelandrew said there.
<flackr> bkardell_: it feels pragmatic and easy enough to explain if it's like what dbaron said where we have maybe 1/year. I feel like this is the max. If more, this feels like it's not a good solution and we need to find the more general way
<flackr> bkardell_: i'd really like to find the general solution as this is only a part of the issue
<SebastianZ> q+
<flackr> bkardell_: people want to detect all manner of things
<Rossen_> ack bkardell_
<flackr> bkardell_: e.g. you should be able to do custom media queries
<florian> q+
<Rossen_> ack SebastianZ
<flackr> SebastianZ: when we introduce such keywords we should also make clear these features need to ship together with the keywords, clearly stated in the spec
<Rossen_> ack florian
<noamr> q+
<flackr> florian: I think it's interesting bkardell_ mentioned media queries, this might be the generic solution to not solve it directly, but detect the behavior of the feature
<flackr> florian: we could make all sorts of changes that might need to be tested, and could be exposed through a JS media query
<flackr> florian: there might be a commonly used library which exposes a set of features needed
<bkardell_> q+
<flackr> florian: I am concerned about the ability to become out of sync and start of sync, not objecting though
<iank_> fwiw libraries already use JS tests then add classes on html element to say if a particular feature "works"
<bkardell_> if some of those are _very_ common then a solution like this could still work - so I don't think they are mutually exclusive where we know there is a specific/popular one like this necessarily
<flackr> noamr: custom media queries doesn't add much relative to performing the test and putting a class or data attribute on the root element
<Rossen_> ack noamr
<flackr> noamr: in general if your test is some JS which deals with the document, maybe the whole feature belongs in userspace
<flackr> noamr: the user defines it in their own way and doesn't seem to be a web platform feature
<Rossen_> ack bkardell_
<flackr> bkardell_: I don't think they're mutually exclusive ideas
<flackr> bkardell_: I think we should add a mechanism where people can do this in author space and we can decide to add the occasional extremely common one
<Rossen_> ack dbaron
<flackr> dbaron: responding to using data from what authors are doing, we would be doing the addition too late and it would be out of sync. I see this for cases where we know ahead of time that it's going to be a big deal
<florian> +1 to dbaron
<bkardell_> ok
<flackr> Rossen_: i'm hearing general support with some concerns with how many we'll have, any other comments/concerns?
<chrishtr> q+
<flackr> fantasai: a common pattern is property X adds to display type Y, we should have a consistent pattern for representing these cases to avoid each being slightly diff when introduced
<Rossen_> ack chrishtr
<flackr> chrishtr: The proposed resoltion is dbaron's latest comment, right?
<fantasai> https://github.com/w3c/csswg-drafts/issues/3559#issuecomment-1868169502
<flackr> chrishtr: adding a custom keyword specific to quirk? assuming so, do we know of any case we can put in the spec as a first example?
<flackr> dbaron: I think the first example would be support for alignment property on blocks, as this is a thing we're talking about doing soon that has this concern
<dholbert> q+
<flackr> chrishtr: how about we add this to the resolution with candidate wording?
<SebastianZ> q+
<flackr> fantasai: I think we should have 2 resoluitons, one for keyword based resoluiton and one for align on block
<flackr> fantasai: for align on blocks, i want to make sure we have a consistent pattern
<chrishtr> @supports (align-content-block-flow)
<flackr> dbaron: I'd like to make these two resolutions and have further discussion to bikeshed the names
<Rossen_> ack dholbert
<fantasai> align-content-on-block
<flackr> dholbert: one q, this proposal lets authors opt in to using css alignment on blocks, but i don't know if it fixes some site that sets * { align-content: center; } and that suddenly starts applying to everything
<flackr> dholbert: do we have a similar proposal to address this?
<flackr> dholbert: it seems like we may need both in order for these sorts of changes to be shippable
<iank_> fwiw we've blocked rolling out align-content:center due to some compat issues with large existing sites.
<flackr> dbaron: I agree it doesn't address this problem, we need to find out whether this will be a problem
<Rossen_> ack SebastianZ
<flackr> SebastianZ: I also had a proposal for custom support queries. I'll create a separate issue for this for discussion. I don't want to derail though
<flackr> Rossen_: dbaron can you summarize resolution?
<flackr> Proposed resoluiton: To adopt keyword based feature queries with names to be bikeshedded later.
<flackr> Rossen_: one of the main concerns was how we keep this to a small number, do we want to capture this in the resolution?
<flackr> iank_: FWIW, it'll be clear when this adds value vs not. These will only have value for a couple of years. What most devs use is modernizr library which have queries for e.g. old grid vs new grid
<flackr> iank_: i suspect we can address this on a case by case basis
<flackr> iank_: currently for us we blocked align on blocks due to breaking some sites
<dbaron> s/align/align-content/
<flackr> iank_: i'm okay with general idea. we'll hear from web devs when this will make their lives easier but we shouldn't add this for every sub feature we roll out
<flackr> Rossen_: I propose let's keep a low number and see if we can agree on this
<flackr> florian: I think there's enough people concerned that we won't be tempted to do this too oftenn
<flackr> Rossen_: is 2 the right number?
<dbaron> Proposed resolution: adopt keyword based feature queries, with names to be bikeshedded later, with the expectation that we will use them rarely and test and message their addition carefully
<flackr> RESOLVED: adopt keyword based feature queries, with names to be bikeshedded later, with the expectation that we will use them rarely and test and message their addition carefully
<dbaron> (I think Rossen maybe wanted <2/year in the resolution?)
<flackr> s/with the expectation that we will use them rarely/less than 2 per year
<flackr> RESOLVED: Add a keyword for alignment on blocks, with the specific name TBD
<flackr> Rossen_: SebastianZ please go ahead and open the issue you mentioned and we can open an issue for names
<flackr> dbaron: separate issue?
<flackr> Rossen_: if it's going to turn into a thing it will be helpful
<flackr> dbaron: sure
stof commented 9 months ago

Even if some browsers already support gap in flexbox without this feature detection, it would still be great to add a keyword for it. As @romainmenke pointed out earlier, making existing versions of browser apply the fallback implementation with margins instead of using gap would often be acceptable, while still using gap for newest browsers and supporting a fallback for browsers without support for gap.

WebMechanic commented 9 months ago

so I did not follow all the threads surrounding this or have read all minutes... I would be a user of this feature.

FWIW a syntax like @supports feature(gap-on-display-flex) seem very counter intuitive and artificial in nature. It requires learning a (albeit limited) vocabulary to describe a problem, requires maintenance (in code and documentation) and specific documentation (lists) that would be hard to "guess" where to find. And whomever writes a blog post would also need to mention these magic keywords and all existing documentation on either the main or supplemental feature would be outdated.

Some generic feature test on the other hand like @supports (gap: 1px) with (display: flex) seems more intuitive to me as it describes spot on the query of a problem that needs solving: does this work in the context of that?

Thank you folks for your great work! Have a nice time.

dbaron commented 9 months ago

Some generic feature test on the other hand like @supports (gap: 1px) with (display: flex) seems more intuitive to me as it describes spot on the query of a problem that needs solving: does this work in the context of that?

I think the basic reason not to do this is that there are probably a few thousand different options for the things on either side of the with in your proposal (different CSS properties, plus different generations of values added to those properties over time), which means there are a few million possible with combinations. There's no ready source of data for the answer to those few millions of questions, so we (both the working group and implementors) would need to sit down and decide what the correct answer to each one is, ensure engines implement them correctly, and test them.

If you combine that with the reality that there's a single digit number of these questions that we know are much more interesting than all the others, it seems much more solvable to deal with the single digit number of questions than with a few million questions.

WebMechanic commented 9 months ago

@dbaron Thanks for your reply! I believe this makes sense :-)

My thinking was: the CSS engine should-would eventually know anyway if any property is "valid" within a specific context as it has to render it at some point and decide if it knows what it's about. And we can already have a gazillion warnings abourt invalid / unsupported properties in the console -- like vendor prefixed stuff. But maybe this "path" is too expensive to follow in the initial parser level.

Have a nice time.

JoshuaLindquist commented 9 months ago

Is there a reason the previous suggestions list the display type last? It seems more intuitive to me to have keywords that list the display type first and then follow it with the requested feature.

feature(flex-gap)

Using feature() is not my favorite solution.

Since the current resolution is to implement keywords only on rare occasions (1 a year, per the log) and to make it easy to educate everyone to use with minimal confusion, I think it would be better to use a keyword that screams "this is a very special use case" rather than a generic term like feature(). I think using feature() sets a reasonable expectation that you can check for any set of CSS features, and it will cause confusion when it doesn't work that way.

Even something like case() or keyword() or just key() seems better to me (though I don't love any of those).

yisibl commented 5 months ago

I'm concerned that one-off keywords will greatly increase the burden on the author's memory.

I have a @feature proposal, This is flexible enough to essentially do what JS currently does to create empty elements for detection. But I am not sure it's feasible.

@feature --align-content-on-block {
    display: block;
    align-content: center;
}

@supports --align-content-on-block {
    .foo { /*  do something */ }
}

@feature --detecting-at-rule {
    @container style(--foo: true) {}
}
dbaron commented 5 months ago

I think @yisibl's proposal in https://github.com/w3c/csswg-drafts/issues/3559#issuecomment-2138955279 has the issues described in https://github.com/w3c/csswg-drafts/issues/3559#issuecomment-1915148442 .