W3C home > Mailing lists > Public > www-style@w3.org > February 2021

[CSSWG] Virtual F2F 2021-02-11 Part II: CSS Cascade 5 [css-cascade-5]

From: Dael Jackson <daelcss@gmail.com>
Date: Wed, 24 Feb 2021 19:29:36 -0500
Message-ID: <CADhPm3vp69R71-VoRQyjghfv2RmRFmKvjRzheF-VJocEAH=54Q@mail.gmail.com>
To: www-style@w3.org
  These are the official CSSWG minutes.
  Unless you're correcting the minutes,
 Please respond by starting a new thread
   with an appropriate subject line.

Cascade 5

  - RESOLVED: Add revert-layer to Cascade 5 (Issue #5793: Do we need a
              keyword similar to `revert`, but for cascade layers?)
  - RESOLVED: Cascade layer imports is done using @import followed by
              URL followed by layer declaration (Issue #5681: Cascade
              layers need an import syntax)
  - RESOLVED: We will allow unnamed cascade layers (Issue #5792:
              Should we allow unnamed cascade layers?)
  - Issue #5853 (Providing an attribute for providing a link to a
      cascade layer) needs consideration by WHATWG and a specific
      proposal to move forward. But <style>@import ...</style> can
      serve the same purpose regardless.
  - RESOLVED: Close this issue for lack of use cases (Issue #5854:
              Providing a syntax for reusing cascade layers across
              encapsulation contexts)


Agenda: https://github.com/w3c/csswg-drafts/projects/14

Scribe: fantasai
Scribe's scribe: TabAtkins

CSS Cascade 5

Do we need a keyword similar to `revert`, but for cascade layers?
  github: https://github.com/w3c/csswg-drafts/issues/5793

  miriam: Cascade layers work like origins in that they stack on top
          of each other, containing specificity
  miriam: With origins, useful to revert to previous origins
  miriam: Suggestion that this might be useful for layers
  miriam: Might be possible also to say which level to revert to
  miriam: but that's the question here
  florian: I think we need at least one
  florian: if people use and need more, can extend further

  argyle: Would be useful
  argyle: Seems likely that I'd want to revert down to a particular
  argyle: Think of Island app want to import their 3 layers
  argyle: Might want to revert down to a particular one
  <argyle> background-color: revert(bootstrap);
  miriam: I'm open to both

  <leaverou> what about revert just reverts to the result of every
             other layer being applied *but* the current layer?
  <fantasai> leaverou, that's * {all: revert} at the start of your
             style sheet
  <leaverou> fantasai: I thought that reverted the entire current

  florian: Behavior is obvious, can spec both and see which ones have
           been implemented
  Rossen: current-level revert is much easier to implement
  dlibby: For revert-to-previous-layer revert, any concerns with
          regards to footgun for authors
  dlibby: if referring to specific layer not applied yet?
  <argyle> `background: revert(bootstrap, 'hotpink');`
  Rossen: Can refer to these as target-revert vs immediate-revert
  fantasai: current-level-revert
  florian: Seems confusing
  florian: Targeted one, doesn't revert a particular layer, reverts
           all layers down to named one
  <astearns> revert(3)
  florian: If there's nothing there, it applies styles from previous

  dlibby: Florian might have answered, but if you didn't have layer
          with particular name / hasn't been applied, seems odd to
          target something might come later in the cascade
  fantasai: My take, let's do the immediate layer revert. It is
            simpler to implement and spec. Say cascade 5 includes this
            and build use cases from there.
  fantasai: Let's keep it simple and start from there
  <florian> +1
  <astearns> perhaps a note with the possible extension and an ask for
             use cases for it?
  <fantasai> sure

  Rossen: Current proposal is go with current-level-revert for
          Cascade 5
  fantasai: Proposed name is revert-layer
  fantasai: If no immediate suggestions to rename, let's go with that

  RESOLVED: Add revert-layer to Cascade 5

  <br duration=10min>

Cascade layers need an import syntax
  scribe: myles
  github: https://github.com/w3c/csswg-drafts/issues/5681

  miriam: We have this in the spec as an option for how you write the
          @layer rule. You can include a URL in the layer. In @layer,
          and it it works similar to an import. But there have been
          questions about whether we should instead extend the
          existing import to allow layer names, or even come up with a
          3rd option.
  miriam: A new import layer rule that is different from @layer or
  miriam: What's in the spec now is @layer can take a URL.
  Rossen: ok.
  Rossen: Is that the current proposed syntax... do you just want
          feedback from the group?
  miriam: Some people had a preference for extending @import. I don't
          have strong feelings on this. I think it works nicely to
          keep it all in @layer. We'll need to allow @layer before
          @import because it's important that layer names are able to
          be established early.
  <bkardell> I also don't have strong feelings, but I like @import'ing
             being import I guess

  Rossen: How does @layer differ from @import?
  miriam: @layer imports a stylesheet into a layer. It allows you to
          add layering while you're importing
  fantasai: @import doesn't establish any layers. It just puts rules
            into the stylesheet as if they are inlined in place.
            @layer creates a layer for things it imports, just like it
            creates a layer for things inside it. In theory, we can
            say @layer can take @import inside the nested block, but
            but then you have to deal with the fact that importing to
            to be the first thing in the stylesheet, so syntax
            restrictions become complex. So the syntax should be "this
            statement creates a layer and imports a stylesheet into it
            as if it was @layer with an @import inside it.
  fantasai: Do we use @import with extra syntax to indicate layering?
            Or do we allow @layer to take a URL instead of a nested
            block of rules?

  florian: Sticking to @layer is better. 3 variants: @layer name;,
           @layer layername {...}, @layer layername url. There is
           symmetry between 3 variants.
  florian: It's self-contained and clean.

  emilio: Would that layer syntax have the same restrictions as
          @import? For appearing before other rules?
  fantasai: Yes.
  emilio: *not* doing that means we have to teach prescanners.
  fantasai: It's defined as it has the same placement restrictions
            as @import.
  emilio: it's ok then

  jensimmons: It's convenient for authors to put it anywhere, though
  fantasai: @layer name {...} can go anywhere. @layer name url can
            only go at the top.
  jensimmons: @layer name url might not need restrictions, which would
              be valuable
  astearns: Maybe we should use @import for that case, then, to make
            the restrictions simpler
  fantasai: We already have precedent for putting @layer anywhere.
            It's just the one with {} can only go after any importing
            rules. I'm leaning to have all 3 have the same syntax for
            consistency. Because otherwise we would have 2 placement
            rules for @layer name;, which would be weird.

  bkardell: I don't understand something.
  bkardell: In "other options" there is @layer reset with a nested
            import. Does emilio's comment mean it's not possible?
  emilio: Please let's make it not possible
  bkardell: Let's remove that as an option then
  bkardell: So the options are using @layer or using @import. That's
  bkardell: I'd like @import to be about importing, and having a
            special version of import which can also create a layer.
            But I don't have strong feelings.

  fantasai: This is a naming discussion.
  Rossen: Yes but it feels like a bit more. @import is already rather
          understood and well-used by the community.
  Rossen: Having yet another mechanism to import seems odd.
  florian: We're having yet another mechanism to import anyway. We're
           just discussing syntax.
  Rossen: Explicitly yes.
  <astearns> either one is fine by me - slight preference for @import

  Rossen: Alright, so. Let's try to move this forward and get to a
          conclusion. Most people were in favor of @layer. A few who
          prefer @import to be used for import: namely: bkardell and
          Rossen  But for me it's just a preference; I can live with
  bkardell: You articulated the way I feel. I feel like people
            understand the limits of @import, and we have machinery to
            do those limits already. Playing into that is good.

  emilio: Another benefit of @import is we don't have to come up with
          OM thing to hold stylesheets. I lean toward re-using @import
  astearns: We need OM changes anyway
  emilio: We need to change the condition. We have a proposal for
          @import-supports. So we need to expose that "import
          condition" or "import layer" but that seems like an easier
          change than exposing a CSS layer rule that may have a URL or
          not, and may have an inner block or not, or inner stylesheet
          or not.
  Rossen: That was the motivation behind my preference as well. They
          have the same behavior from importing POV. In the future,
          when we extend @import, we have to make a parallel change in
          something else too.
  emilio: That's a good point. We have proposals for
          @import-cross-origin to make cross-origin requests. Would be
          good to not duplicate
  TabAtkins: I agree, and am strongly for using @import.

  florian: There are variants. @import layer (name url). Or @import
           url as layername. Which is more readable, but couldn't deal
           with unnamed layer (unless we add a new keyword meaning
           "import as unnamed") which wouldn't mean "import into the
           layer named 'unnamed'" but instead "import into
  Rossen: What are you talking about
  florian: Una suggested something that seems both more readable and
           not working in the unnamed layer case.
  <florian> @import layer reset url(reset.css);
  <florian> @import layer(reset) url(reset.css);
  <florian> @import url(reset.css) as layer;
  <argyle> `@import reset from url(reset.css) as layer;`?

  jensimmons: There are 2: one is to add another keyword or whatever
              it's called to the import statement to say which layer
              it goes to, and the other which is about nesting @layer
              reset (@import url). I keep going back and forth.
              There's something about how clear it is that you start a
              layer, when you define a layer, you import a stylesheet.
              That's appealing. But I also understand the keyword
              would still work well.
  jensimmons: I'm leaning toward nesting.
  Rossen: Now we're swinging the other way.

  fantasai: My preference would be for whatever syntax we choose to
            have the word "layer" in there somewhere. We need a way to
            have unnamed layers for parallelism. Most of the
            parameters for our @import rules come after the @import
            rules (conditions, parsing) is a little bit open-ended. It
            might make more sense to do this before the URL and it
            also brings up to the front and makes it obvious "we are
            making a layer with this URL". So my preference is one of
            the earlier options.

  <Rossen> @import layer reset url(reset.css); @import reset url(
           reset.css) as layer; @import layer(reset) url(reset.css);
  Rossen: I pasted the 3 variants that are in the issue.
  jensimmons: por que no los dos?
  Rossen: <lists the 3 options verbally>
  emilio: Can we add a 4th one? @import url something something
  emilio: reasoning: that's how the extra things to @import work
          already. like media queries.
  fantasai: That would parse as an invalid media query, and it would
            get imported anyway whether or not you support layer
  <Rossen> @import url(reset.css) as layer(reset)
  emilio: We have that issue for the proposed @supports function,
          right. I'd like to have the mandatory parts at the front,
          like @import url, then the optional stuff like the conditions

  Rossen: Where does the supports() go in this case.
  <astearns> what was the 'both' you were asking about, jensimmons ?
  <bkardell> likes `@import url(reset.css) as layer(reset)` if that is
  emilio: I think we resolved on this at the end, but it's not in the
          spec. It goes where the media query goes. Which is weird
          cause your text can mean either
  Rossen: Without dumping the whole issue into this one, wasn't the
          issue to have @supports evaluated so you're not hitting the
          network? The current solution is to have @supports at the
  emilio: Yes. We added a supports() function.
  emilio: With the function syntax it's possible. You just determine
          if it's this function or not, and if it's not, then assume
          it's something else.

  <fantasai> https://www.w3.org/TR/css-cascade-4/#conditional-import
  <fantasai> https://www.w3.org/TR/css-cascade-4/#at-import
  <fantasai> Current syntax is:
             @import [ <url> | <string> ]
                     [ supports( [ <supports-condition> |
                     <declaration> ] ) ]?
                     <media-query-list>? ;

  <jensimmons> Could we do `@import layer(reset) url(reset.css);` AND
               `@import url(reset.css) layer(reset) ;` AND @layer
               reset {
  <jensimmons> @import url(reset.css); }
  jensimmons: What is the precise syntax for naming the layer? I like
              having layer() and reset. That would allow us to use
              layer with 2 parens and no name and leave it blank to do
              what fantasai was mentioning to assign it to a unnamed
              layer without it being too messy. And having the name of
              the layer an argument to a function, it might not matter
              which name comes first
  jensimmons: I also was trying to say, would it be possible to do an
              import statement with a way to name the layer *and* CSS
              does both so authors can pick which ever way they want
              to do it, or and the nested @layer { @import ... }
  fantasai: My concern with the nested one is you'd be tempted to put
            declarations there. In theory you could do that once, but
            then you couldn't put further @import rules. So then you'd
            have @layer blocks which don't include any declarations,
            and if you do, then it becomes invalid, so it will be
            confusing. I don't want to give the author the impression
            they can put rules in the block. They can't do that.
  <TabAtkins> @import currently has a req that it comes first in a
              file, which lets impls pretend that the imported files
              are ordered fully before its importing file (they don't
              have to track nesting of imports for purpose of figuring
              out source order of declarations)
  <TabAtkins> @layer { @import} doesn't impose this restriction.

  florian: Assuming we go with @import, especially for extension
           ability. It shouldn't be after the rule. Because it's
           syntactically ambiguous with media queries. We don't want
           something to parse both as a layer and as a media query,
           that's bad
  emilio: We already do that with supports, right?
  <fantasai> Also, everything after the URL is currently a condition.
             This isn't a conditional.
  emilio: fantasai pasted the supports syntax now. It would only be
          ambiguous if you add a layer() function into media queries.
          But not otherwise
  florian: But supports and layer are conditional things, they belong
           in roughly the same place, so I'm still uncomfortable with
           that, but less so
  emilio: I don't mind much either way. It would be slightly nicer,
          given all browsers have bespoke @import preload parsing, and
          scan for literally "@import string" and then preload that, I
          would be slightly happier if we didn't have to add harder
          parsers, because that code is pretty ugly already.
  emilio: I don't know.
  <fantasai> Wouldn't you want your speculative loader to parse
             conditions on the @import?
  <emilio> fantasai: yeah, that is right (I think right now we just
           don't preload conditional stuff)

  Rossen: Let's try to resolve.
  Rossen: Let's try to record a resolution here. It will be easier to
          revisit the specific syntax of where the layer declaration
          goes if we're not happy with it later, but at least it seems
          we're all leaning toward where the declaration goes with
  Rossen: emilio, your proposal is @import url layerstuff?
  emilio: yes
  Rossen: Is that something we can start working with?
  <jensimmons> @import url(reset.css) [layer stuff];
  <jensimmons> @import url(reset.css) layer(reset) ;

  RESOLVED: Cascade layer imports is done using @import followed by
            URL followed by layer declaration

  <emilio> fantasai: For reference, the bespoke @import parsers:

Should we allow unnamed cascade layers?
  github: https://github.com/w3c/csswg-drafts/issues/5792

  astearns: Does this need discussion?
  florian: Yes.
  TabAtkins: There are great arguments for. I don't like the fact that
             you cannot reopen them. Having to name something you're
             only going to open once... you can never enter it again,
             isn't great. Provides false sense of security from you
             being able to create an unnamed layer and ensure that
             nobody can mess with your stuff. It's not actually
             secure, it doesn't do anything secure.
  TabAtkins: I don't like it much
  jensimmons: Can you make more than one unnamed layer that won't add
              to each other?
  TabAtkins: It's as-if unnamed layers get a secret name.
  florian: I don't understand what you mean about security. If you're
           a framework and you want to organize your internals using
           layers, but it's not something you do to allow external
           users of your framework as an extension point to go inside
           your layers, having an ability to encapsulate a number of
           things is convenient
  TabAtkins: Layers gives you everything you need. Unnamed layers just
             stops other people from breaking you by accident
  TabAtkins: You cannot clash by accident.

  jensimmons: It feels like asking people to have names for everything
              biases the industry toward being organized and planning
              and doing "base" and "component" - hey, you don't have
              to have names, you just have a code, and the cascade is
              bugging you, just wrap it in @layer, I don't know why it
              works, just do it..... we might regret that, but it
              might be great. Maybe a person is the only person
              working on this code and they're just 'cowboy'ing it,
              maybe we don't want to encourage that.
  florian: I'm all for the cowboy style.
  <tantek> or rather, the "don't burden the author with more cognitive
           load" style
  <fantasai> +1 tantek

  florian: If you're not in the cowboy style and you're being
           diligent, and you don't want your users to accidentally
           depend on your internals so you can't refactor yourself
           later, then this encapsulation to protect yourself from
           other people is valuable. Because they can't mess with your
           internals, they can't depend on your internals being a
           particular way
  <fantasai> +1 florian
  TabAtkins: This is CSS. Layers let you organize the cascade, but
             don't let you interact independently of anything. The
             styles after your code has to worry about your code
             exactly as much of whether they're poking into you or not
  fantasai: This stops them from depending on your specificity. The
            specific order of rules does matter, but you no longer can
            have someone outside your stylesheet depending on how
            you've selected the elements. They only depend on what
            properties finally at the end of the cascade of that layer
            end up attached to those elements.
  fantasai: That does provide a meaningful level of encapsulation. So
            I agree with florian and jensimmons. Don't put unnecessary
            cognitive load on the author (as tantek said)
  <tantek> we all know naming things is hard. so don't make authors
           name things unnecessarily
  <fantasai> tantek++

  jensimmons: I don't think people will understand the encapuslation
              use case. It's a very advanced level of understanding of
              what's happening. But a better question to ask is: is a
              name required, if we decide not to do unnamed layers,
              what happens if the name is left off. Are all styles
              inside the block invalid? does everything become valid
              in a secret name for the layer state? that will be
  TabAtkins: It would be a syntax error. the whole block would be
  astearns: It's not great.
  TabAtkins: It's just as not-great as screwing up your media query
  TabAtkins: Worry about syntax is not realistic because you can screw
             up any block.
  TabAtkins: I'm okay with going without named layers, then
  TabAtkins: I withdraw my objection.

  RESOLVED: We will allow unnamed cascade layers

Providing an attribute for providing a link to a cascade layer
  github: https://github.com/w3c/csswg-drafts/issues/5853

  miriam: This might need to to HTML.
  miriam: The idea is if we're able to import into a layer in a
          stylesheet, should be able to do this from a link to a
          stylesheet? Like an attribute. But there are issues.
          Attributes are usually ignored if the browser doesn't
          support them. Then you'd get a different fallback behavior
          than if the browser ignored a layer block
  florian: I don't think that syntax can work. Doing it from HTML
           seems valid. But it probably couldn't be <missed> it would
           have to be something else because of fallback. Maybe
  florian: Other than that, sure, why not
  fremy: There's an attribute for media
  fremy: We can maybe use it in have a special syntax:
  fremy: I dunno, that was a random thought. In browsers which don't
         support layer, it would never match because this media
         doesn't exist
  astearns: I'm not a fan of nesting it in media=
  florian: It would be ugly but it would work.
  astearns: For my clarification: florian, the layer attribute would
            not work, but just not in a link element, or also not in a
            style element
  florian: If you have <link> that loads a stylesheet that's ordinary
           in every respect except it also has a layer attribute, it
           wouldn't work because browsers would do a normal import,
           which isn't compatible behavior.
  astearns: So it would also be a problem in <style>
  miriam: The <style> doesn't need this because you can just put a
          layer inside of it easily.

  fantasai: We should table this until we have a specific proposal
  florian: Or push to WHATWG
  <bkardell> you could <style>@import ... right?
  <fantasai> +1 bkardell, this might not be worth solving in HTML
  TabAtkins: let's open an issue on WHATWG.
  <tantek> sounds reasonable
  TabAtkins: Maybe we can stash it in media= like fremy said. They can
             think about it in WHATWG
  astearns: ok.

Providing a syntax for reusing syntax across cascade layers
  github: https://github.com/w3c/csswg-drafts/issues/5854

  miriam: In order to avoid complexities with shadow dom, we've spec'ed
          layer names in shadow dom encapsulation to not refer to the
          same named layers outside of shadow dom. Layer names don't
          cross shadow dom boundary.
  miriam: Is there any case where it would be useful? I don't know the
          use cases here

  bkardell: I don't have an example I can say, or a solution. But I
            don't know if the current boundary needs something more.
            Where you actually declarative adopt stylesheets. This
            should be part of that conversation
  astearns: Isn't the solution constructable stylesheets?
  bkardell: It's an element, yes. But you can't declaratively do that
  bkardell: You need those concepts first.
  bkardell: There's a big discussion here about how these things work.
            And participate cooperatively under mutual suspicion
  emilio: I was going to ask how would this boundary crossing look
          like exactly? Right now in the shadow tree, the stylesheets
          apply to itself, and maybe host and slotted. But they are
          different cascade levels anyway. So I'm not sure how that
          would even work

  * fantasai proposes deferring this issue until someone comes up with
             a compelling use case

  florian: It would seem to me that from a shadow dom reopening a
           layer that has been opened outside of it to change it is
           probably a foot gun. Not having the ability to do that
           sounds reasonable
  florian: OTOH, the revert layer to a named layer, if we get that,
           doing that from inside the shadow dom does not sound crazy.
           If your components are all assuming the entire page will
           use bootstrap and your design system, and you're inside
           your shadow dom, and you want to revert layer to the design
           system layer, or revert to bootstrap layer, it would be
           nice to call them. For now we don't have this but it's not
  emilio: But the stylesheets inside/outside the style root don't
          interact at all
  astearns: We don't want to add interactions
  TabAtkins: It's because you've imported those layer names as well

  TabAtkins: AFAICT we don't need to do this because shadow dom
             separates styles already. You shouldn't get normal styles
             across anyway. Similar with host or part, those are
             applying styles in either the tree or the outer context,
             which is separate on a higher context already, so I don't
             think there's any place where the styles touch closely
             enough for layer context to matter. So this is nil.
  <bkardell> +1

  fantasai: Let's close this, and if it's a problem later, someone
            will file it again with a use case hopefully
  astearns: Sound good?
  florian: My previous comment made no sense given how things work

  RESOLVED: Close this issue for lack of use cases.

 <br type = 10min>

++ During Break Conversation ++

  emilio: What if we had selectors? If we had selectors in the
          container rule, it would be weird if elements in the shadow
          root were affected by the selectors in the container query
          outside the container rule. But I guess it wouldn't? I don't
  emilio: If they were part selectors, then yeah....
  emilio: You could select an element in a shadow root using a
          container query that had a selector that matches against a
          container inside the shadow root? that would be wrong
  TabAtkins: If it's a selector then you can't cross the boundary
             because you can't see the elements on the other side
  emilio: What about an @rule that has selectors and a container
          query? That's the tricky case because at that point you have
          the shadow dom element you're styling, you have the
          container rule, you have an ancestor chain, ideally you
          don't evaluate the selector in the shadow root, but you
          don't evaluate it outside the shadow root either, because
          ancestor combinators don't work across ancestor boundaries
  TabAtkins: Styling a part element should not do anything at all
             because of the reason you just gave. theoretically, from
             inside the shadow might be able to see the container
             outside, that's possible from encapsulation and host
             context, which can go higher than the host,
  emilio: I think that's bad
  TabAtkins: me too
  TabAtkins: It should just not work. Selectors keep us in a more
             honest world where it's obvious what to select on: the
             elements you can see
  emilio: We could evaluate based on the flat tree ancestor chain,
          which is a bit weird
  emilio: That's what the box tree is, and that's kinda what defines
           the container
  emilio: but.....
  TabAtkins: That's real awkward. unless you do funky hacking that
             would allow you to style a part based on containers in
             the shadow
  emilio: Agreed
  TabAtkins: It's definitely limiting. Inside a shadow do container on
             your host and that's as high as you can go
  astearns: can we open an issue?
  miriam: Yes, if this can be documented
  TabAtkins: The container query pseudo class will have to say it
             matches on host elements. By default nothing matches on
             host elements except :host. It's an extra issue to worry
Received on Thursday, 25 February 2021 00:30:18 UTC

This archive was generated by hypermail 2.4.0 : Monday, 23 January 2023 02:15:16 UTC