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

[selectors] Should :active apply to dialogs? #7258

Open
plinss opened this issue May 6, 2022 · 19 comments
Open

[selectors] Should :active apply to dialogs? #7258

plinss opened this issue May 6, 2022 · 19 comments
Labels
selectors-4 Current Work

Comments

@plinss
Copy link
Member

plinss commented May 6, 2022

Now that we have :modal, we have the situation where there can be multiple open modal dialogs, but only one of them can be considered active at a time. Should we distinguish the active modal dialog with the :active selector?

e.g. The currently active modal dialog can be selected via :modal:active.

@bramus
Copy link
Contributor

bramus commented May 6, 2022

Would love to see this, but conflicts with the current use/definition of :active, which also works on non-links

The :active pseudo-class applies while an element is being activated by the user. For example, between the times the user presses the mouse button and releases it.

@Loirooriol
Copy link
Contributor

Example of what bramus said: https://software.hixie.ch/utilities/js/live-dom-viewer/saved/10287

@tabatkins
Copy link
Member

Yeah :active already has a defined meaning on all elements, we can't reuse it for something different now.

@plinss
Copy link
Member Author

plinss commented May 6, 2022

Two points:

  1. regardless of what it's called, we need a pseudo-class to distinguish the currently active dialog, since multiple dialogs can be open and modal at the same time and there's no other way to distinguish the active one.

  2. I don't believe the :active pseudo-class is defined in such a way as to prohibit it's use here. It is defined to mean 'being activated by the user' not 'has the mouse down on it'. The 'mouse down' trigger of activation state was an example only meant to have meaning on buttons (or other clickable elements, and for elements that don't have a clickable behavior, maybe :active on mouse down should only apply when there's a 'click' or 'mousedown' event handler). The fact that browsers get this wrong can be considered a bug, and I don't see why we can't tighten up the definition of 'being active' on specific elements, especially those that have a well defined 'active' state, like modal dialogs (tho that would belong in HTML). In fact, in @Loirooriol's example on iOS the dialog only has the active state when text is selected inside the dialog.

@tabatkins
Copy link
Member

Changing the definition of :active when it's been widely implemented as it currently is for many years doesn't seem wise or likely to be web compatible.

The use-case we had for the pseudo-class in the first place was distinguishing modal from non-modal dialogs so we could style them differently in the UA stylesheet (and we figured authors might have some use for it). Do you have a use-case for styling the active modal differently from modals that are currently "further down" the modal stack?

@plinss
Copy link
Member Author

plinss commented May 6, 2022

I'm not talking about redefining :active for everything here*, but only defining it to have a different behavior for a single, new, element. I don't see that breaking existing content (unless someone really did something when a dialog is being clicked on).

The use case is for making the active dialog visually distinctive when the author is using multiple nested modal dialogs, like putting a highlight around it (or dimming the non-active ones). (I also don't see a use case for styling a dialog that's being clicked on, content within the dialog, sure, but not the dialog itself, unless it's being dragged, but that's something else and shouldn't be considered active anyway.)

(*) I did mention that it should only apply to non-clickable elements when there's an event handler present, but that's an entirely separate issue (and not so much a redefinition as an argument to respect the original specified definition), and I accept has web compat concerns.

@tabatkins
Copy link
Member

Even if there is zero code in the wild today styling a dialog with :active, I think it would be a really bad idea to have it mean something different on dialogs when it has a consistent meaning (actively being clicked on) for every other element.

Ignoring the syntax question, tho, what's your use-case for targetting the current active modal with selectors?

@plinss
Copy link
Member Author

plinss commented May 6, 2022

The use case is for making the active dialog visually distinctive when the author is using multiple nested modal dialogs, like putting a highlight around it (or dimming the non-active ones). (I also don't see a use case for styling a dialog that's being clicked on, content within the dialog, sure, but not the dialog itself, unless it's being dragged, but that's something else and shouldn't be considered active anyway.)

@plinss
Copy link
Member Author

plinss commented May 6, 2022

I'll also state the :active pseudo was not meant to mean 'actively being clicked on' it meant 'active', it's just that the things that get active so far have done so by being clicked on. If we meant 'being clicked on' we should have called it :click or :press. The case of the mouse being down was an example not a hard definition.

@nt1m
Copy link
Member

nt1m commented May 11, 2022

Re-using :active would be confusing, given it has a historical meaning for web developers. Fwiw, Firefox has an internal :-moz-topmost-modal-dialog pseudo-class.

Though, I don't find it particularly useful to expose this to web developers, given they control which dialog(s) they show.

@LeaVerou
Copy link
Member

I agree with @tabatkins that re-using :active with an entirely different meaning would be a terrible idea. While I understand that :active was originally defined to be a little vague, the reality is that today it means "pointer is pressed over the element".

I would however support having a pseudo-class for what @plinss is proposing. I don't have any good ideas for what to call it (:active would have been an excellent name if it didn't have baggage).

@chrishtr
Copy link
Contributor

Maybe :modal-active as a name?

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [selectors] Should :active apply to dialogs?, and agreed to the following:

  • RESOLVED: issue of topmost modal dialog to be addressed with a pseudo-class (name TBD)
The full IRC log of that discussion <dbaron> Topic: [selectors] Should :active apply to dialogs?
<dbaron> github: https://github.com//issues/7258
<dbaron> plinss: The sense is that there can be multiple modal dialogs and only one is active. Should have a pseudo class for it. I propose we re-use the :active pseudo class, though what pseudo used is not that important.
<emilio> q+
<ntim> q+
<dbaron> plinss: There was a lot of pushback against using :active. I accept it could be problematic... many people seem to think :active means the mouse is down, but I think it means the thing is active.
<Rossen_> ack emilio
<dbaron> emilio: I was going to echo that... :active applies to all elements when you press the mouse, regardless of whether they're activatible. So I think it would be very confusing to use it for this. Especially because it would trigger when you click something in a dialog, because :active applies to the whole chain of things.
<dbaron> emilio: I don't know that the pseudo is that useful -- can't think of cases where you want different styling for the topmost modal dialog from other modal dialogs.
<dbaron> Rossen_: Is the point you're making that an active modal dialog must always be the topmost one, and ... ?
<dbaron> emilio: I think reusing :active would be a mistake because it already applies to <dialog>, and that I don't think there's a lot of use cases for styling the active (i.e., topmost) dialog versus styling a modal dialog that is not the topmost one.
<dbaron> emilio: We need to do that internally for inertness, but that's just to control inertness of the topmost thing.
<dbaron> plinss: If you have nested dialogs, I can see wanting to differentiate them visually. They may not necessarily be on top of each other or obviously obscuring each other. I think there's a valid use case for it.
<dbaron> emilio: Fair. I guess I think it's something the backdrop usually takes care of.
<dbaron> plinss: Depends on what effect backdrop has and whether it's obvious.
<Rossen_> ack ntim
<dbaron> ntim: I'm also against using :active for this. If you're really targeting the dialog ??? ... that would make it incompatible.
<dbaron> ntim: :active has a historical meaning, so I'm against doing that.
<dbaron> ntim: I also don't see a lot of use cases. But my main pushback was using :active.
<dbaron> ntim: Personally regarding use cases, since modal dialogs are triggered using javascript, you can control which class you put on the topmost one. I don't see a real gain from adding pseudo-class.
<emilio> q+
<dbaron> plinss: You could make that argument about almost every pseudo-class. Let me push back on :active meaning the mouse is down -- I don't think that was original intent. I think it was a mistake -- not sure if it's one we can fix.
<dbaron> ntim: Let's say you have a button inside a dialog, and you're pressing that button. Unexpected that :active would apply, given that :active propagates to parent elements.
<dbaron> plinss: It would already be active if the button is clickable
<dbaron> emilio: not if the dialog isn't modal
<Rossen_> q
<dbaron> emilio: If I understand correctly, this would make a pseudo for the topmost modal dialog. Would be confusing for that pseudo to apply to non-modal dialogs.
<Rossen_> +1 to emilio and :active interop being bad
<dbaron> emilio: Put on queue to say that :active interop is pretty bad. This would make it a lot more confuesing.
<Rossen_> ack emilio
<Rossen_> ack fantasai
<chrishtr> q+
<dbaron> fantasai: I agree we can't use :active given how it's been reinterpreted by implemented. Was never intended to be "while I'm clicking on this element".
<dbaron> fantasai: I can see there might be use cases for having a pseudo-element for the topmost modal. Wish we could use the word active for it, maybe :active-modal or similar.
<dbaron> Rossen: I'd like to break the solution into validating the use case and coming up with a solution, and then the bikeshedding.
<dbaron> Rossen: Would like to validate the use case first.
<dbaron> chrishtr: To the point about developers don't need it because they control the dialogs... it's still convenient because it's very simple to just have to style the frontmost dialog and not have to use script to polyfill the same thing.
<dbaron> Rossen_: I agree with that too.
<Rossen_> q?
<dbaron> Rossen_: sounds like there's more validation to the use case... name of the pseudo TBD.
<dbaron> Rossen_: Would prefer to take bikeshedding back to the github issue.
<dbaron> ntim: If you have a UI that does stacking multiple dialogs... it's not a great UI. This sort of encourages it in some way. I guess the role of CSS isn't how to say how to build UIs.
<tantek> I would like to get input from the OpenUI folks on this
<dbaron> plinss: I agree stacking modal dialogs is a bad pattern... though maybe modal dialogs are a bad pattern to begin with. If we're going to do them we should do them well.
<tantek> I didn't see any in https://github.com//issues/7258
<tantek> q+
<dbaron> plinss: ... goes against my earlier advice about allowing authors to do bad things.
<dbaron> tantek: I'm looking at issue and leaning towards plinss opinion as well. But haven't considered motivating use cases.
<dbaron> tantek: I think OpenUI folks should comment... may have more context of uses cases that would need this pseudo class... or they've considered it and decided they don't need it.
<dbaron> Rossen_: I think the decision of styling the active modal dialog througha pseudo-class is seemingly obvious decision even if we invalidate the use case later.
<dbaron> Rossen_: I'd like to record a decision here....
<fantasai> s/do bad things/do bad things, but arguably modal dialogs in general are a bad idea. If we're going to do them, though, let's do them well./
<dbaron> ntim: Looking at top layer generall, maybe use case is targeting topmost thing in top layer rather than active modal dialog. Look at it from different perspectives as well.
<smfr> plinss: the second one
<dbaron> ntim: How does this fit with other things that use the top layer -- full screen api, popup api.
<dbaron> ntim: How does this pseudo fit with this stuff... and should it be more generic to these things?
<dbaron> ntim: so maybe openUI input would be good.
<dbaron> plinss: Happy to get openUIs input, but would like to take a resolution to have a pseudo-class.
<chrishtr> +1 to resolving to add a pseudoclass now. :modal-active ?
<dbaron> Rossen: Proposed resolution that issue of topmost modal dialog to be addressed with a pseudo-class (name TBD).
<dbaron> RESOLVED: issue of topmost modal dialog to be addressed with a pseudo-class (name TBD)

@plinss
Copy link
Member Author

plinss commented May 18, 2022

I disagree with :modal-active. We got to :modal under the agreement that pseudo-classes should have one meaning, and :modal-active at least implies 'this is modal and it's active' (and makes :modal:modal-active stutter).

I'd be ok with :active-modal (or possibly :active(modal) as a pattern for different flavors of 'activeness') or, better, some synonym of :active that we can use in all cases in the way that :active was originally meant to be used. But I'd rather we take some time and see if we can't reclaim :active under its original meaning. The fact that :active has bad interop makes me hopeful we can tighten it's definition. (If we can't reclaim :active, I propose we add it to our list of mistakes.)

Another possibility would be to make :active care about other pseudo-classes on the same selector, e.g. dialog:active means the mouse is down, but dialog:modal:active (or dialog:active:modal) means the active modal. (I think this is likely somewhat problematic but wanted to throw it out there.)

@tabatkins
Copy link
Member

The fact that :active has bad interop makes me hopeful we can tighten it's definition.

Its interop issues are in terms of precisely what interactions cause it to match, notably for keyboard events. All impls are perfectly consistent on its overall meaning, and especially are consistent in the mouse-down behavior.

(I think this is likely somewhat problematic but wanted to throw it out there.)

Yeah, this isn't doable. ^_^

@gregwhitworth
Copy link
Contributor

gregwhitworth commented May 19, 2022

Open UI just discussed this today since @tantek brought it to the group.

TLDR: There were no usecases in the designs systems/solutions that the group knows about or works on currently. The group wants to wait for concrete use-cases to present themselves before recommending a solution for this

Full IRC Log

tantek: this was discussed in CSSWG, not enough info in CSSWG to make decision, I thought, so wanted to bring it here

tantek: I basically wanted the considerations from this group to be taken into account

gregwhitworth: peter's comment is basically, should you be able to select the active dialog with the active pseudo class?

bkardell_: some people had the concern that it is not intuitive… not sure if that's the big thing, for me the concern is some worry that because :active is used in stylesheets today so you would get false matches when people start using dialog?

link to plinss comment: #7258 (comment)

bkardell_: but maybe that's no problem as those sites don't use dialog now and they can change it when they start using

JonathanNeal: I saw the concern with :active… I use it myself for the 'pressing' state, the point after a spacebar or click begins… I find it to be an underused/poorly defined thing… it does have a meaning that I thinki s different… while I support the idea of this pseudo class I was going to ask if current had been considered?

JonathanNeal: I thought it was supposed to represent the current item to be displayed?

tantek: we did distinguish between functionality and bikesheddding the name of pseudo class

tantek: could this group address this separately?

tantek: so would the functionality tbe useful vs what do we call it and how does it match naming conventions?

masonf: I wanted to ask… was it decided not to combine it, I saw :active-modal , I presume that's off the table?

I see value in knowing the active/current modal.

tantek: I think we were not able to get to the naming in the meaning

I actually meant to ask how the “active modal” was defined. Does it contain focus? focus intent?

masonf: oh I mean… combining the two things in one pseudo class, I don't care about the names as much, but about that :modal and :active are two pseudo classes and not combined into a single one

emilio: imagine you have a popup instead of dialog, like a tooltip, you probably wouldn't want the pseudo class to stop applying to the dialog?

masonf: why not?

masonf: what would you expect if the popup obscures the dialog?

emilio: modal dialogs are special in the sense that only one dialog is not inert…

I also support the general pseudo-class, like :hover, versus a specific pseudo-class like :active-dialog.

masonf: even if there is a popup on top of it and it covers the entire dialog?

emilio: yes because the popup doesn't have modal semantics, doesn't make rest of page inert/

emilio: in Gecko we need a pseucodlass internally to distinuish modal from top most dialog

+1 to emilio's point

emilio: I'm not sure what the distinction brings on something that is a modal… as long as it is not a modal you can just position things differently… can only have one at the time, and not true for any other top layer el

masonf: what does it mean to be top layer if I'm not necessarily on top of everything else, is something I was asked

emilio: the use case is highlighting or styling differently the active dialog, you may not care if it is on top

emilio: imagine a dialog that has a popup like thing… you lose the ability to differentiate the inert from the non inert if you just make the pseudo class the top most thing in the top layer?

emilio: I guess there is also a use case for distinguishing the top most thing?

masonf: that was a compelling example, maybe there is a need for two pseudo classes

tantek: there is the concept of active from UI perspective, and then there is the :active semantic, and they are not the same

tantek: :active is defined in CSS 1, it is something we have to live with… but we can avoid confusing developers

is this purely for "top most" (which sounds presentational) or is this about which modal dialog has the user's focus, in which case perhaps :focus-within https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-within could be combined with :modal?

tantek: the term topmost has been used… I'm not sure if I like that, it's kind of got a presentational framing. Is this about what the user's focus is, maybe something like focus-within could help?

tantek: so what is the actual functionality we are looking for… as opposed to what could we reuse from existing concepts?

JonathanNeal: want to +1 what tantek just said

JonathanNeal: my question is: could someone define this 'active top most' that we could apply to things like and modal and see if we could pair it somehow? JonathanNeal: is there a definition of what that potentially general state is? JonathanNeal: is it the thing that is the top most? masonf: that is what needs to be discussed more… I heard two. One is the non inert dialog, effectively the top most dialog… the other is the one I came to the meeting with, of all the top layer elements, which one is on top of all of them? JonathanNeal: is there a quality to the top most, like it has the focus intent, is there some qualitative thing we can know about? masonf: you can have a topmost element that doesn't have the focus entirely, it is just in the top Maybe :modal:with-intent? emilio: for dialog that is the intention… you can't (@@@) have a hidden dialog in the top layer, I think the intention is that that is the onlly interactive thing tantek: that's why I brought up focus-within, I think that kind of has that notion of interactive Or :modal:intent-within. emilio: I think focus can move outside of the tab, so focus-within might not match anything within the page tantek: what styling are authors trying to do with the top most thing? or is it that folks want to know this is the thing that users must interact with ? emilio: that's fair… in an ideal world, modal dialogs could properly trap focus and you could guarantee there's focus in that +1 to tantek's comment: we need concrete use cases for these things before trying to design how they work. gregwhitworth: what I would recommend based on what I have heard… what if we actioned somebody to find use cases, but I'm not sure what wer're looking for, I don't even know what to ask? gregwhitworth: the pseudo class modal only applies to dialogs Does a modal have focus intent? By focus indent, I am referring to the effect when we click an anchor link? And it would apply even if the modal does not or cannot receive focus? gregwhitworth: so in some scenario something is occurring in some state for dialog… so not sure if we could even task someone with investigating this more as I'm not sure what sort of use case we're looking for here? emilio: I think Peter was the first who brought this up because internally we need to distinguish between dialog is modal and dialog is the top most one that isn't inert https://github.com//issues/7258 emilio: there is a point to get more concrete use cases tantek: I believe what Peter is expressing is that… dialog that the user CAN interact with vs MUST interact with… that's very different from the notion ':active' in CSS so far tantek: so it's about drawing attention to an element in the page I could see using the :not() variant to blur the modals behind the “top-most”. scotto: I was wondering about use cases too and I'm not sure either what we're trying to solve scotto: something like an ARIA modal wouldn't trigger this pseudo class, this seems specifically for dialog and any other custom modal popups that someone might make, I'm not sure how that would apply if it is not defined in the web platform… so yes +1 we need some use cases +1 scotto gregwhitworth: thinking of what we have in Salesforce… a use case I can think of is where a dialog is trying to convey some perceived active state, may be focused, may not be, may even not necessarily be modal gregwhitworth: in a teaching UI scotto: but you probably wouldn't even want a thing in a teaching UI to be modal gregwhitworth: exactly and probably not the pseudo class either, we would be handling it just with popups, wouldn't need active or enter on or others masonf: seems like part of the reason looking at the notes is for this group to look at use cases gregwhitworth: seems to me we want to ask the community in Discord or Twitter tantek: instead of bleeding into the abstract, we are looking for something concrete flackr: with the real use cases, it is possible that focus-within match the expectations flackr: focus does get restored if focus-within gets lost when you switch tabs it is put back, I noticed gregwhitworth: ok cool, so action would be to sum up the request for use cases and share it gregwhitworth: do we even want to? masonf: this seems like something we can add later to the platform and it would still be compatible tantek: probably good feedback for CSSWG, don't need to rush it, wait for use cases to present themselves

@ByteEater-pl
Copy link

How would :modal:active be different from :modal:focus-within?

@plinss
Copy link
Member Author

plinss commented May 28, 2022

How would :modal:active be different from :modal:focus-within?

It applies even if there are no focusable elements in the dialog.

@bramus
Copy link
Contributor

bramus commented Jun 23, 2022

Was thinking about introducing :topmost for this, but then came to realize that a [popup] launched from within that dialog could ruin things: dialog:modal:topmost would no longer select that topmost modal once other elements steal away the :topmost pseudo from the dialog.

Looking back at the selectors we currently have, I think we could solve this with the introduction of a ::top-layer pseudo-element, so that we can query its (virtual) children, combined with :nth-last-child(|An+B| of S)

:nth-last-child(1 of ::top-layer dialog) {
  // topmost modal dialog in the top-layer, yay!
}

It would require that ::top-layer reports the child elements in the order in which they got added to it (instead of their actual DOM order)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
selectors-4 Current Work
Projects
None yet
Development

No branches or pull requests

10 participants