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

Change dialog to position:fixed, and remove dialog alignment modes. #5936

Merged
merged 8 commits into from
Nov 3, 2020

Conversation

bfgeek
Copy link
Member

@bfgeek bfgeek commented Sep 22, 2020

Copy link
Member

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty solid. @sefeng211 could you take a look too?

Also please make sure there are tests for the computedStyle of an unstyled dialog matching the spec's UA stylesheet. web-platform-tests/wpt#5625 discusses the general problem and solution space (/cc @zcorpan) but for now some one-off tests would be good.

@@ -57253,8 +57251,6 @@ interface <dfn>HTMLDialogElement</dfn> : <span>HTMLElement</span> {

<li><p>Add an <code data-x="attr-dialog-open">open</code> attribute to <var>subject</var>, whose value is the empty string.</p></li>

<li><p>Set the <code>dialog</code> to the <span>centered alignment</span> mode.</p></li>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So is the intention really that show() and showModal() now have the same visual behavior? That's a bit surprising, but if it's what everyone wants...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is a bit surprising to me too. I was under the impression that all discussions that happened around it were targeting centered alignment mode.

Copy link

@dpogue dpogue Sep 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree this behaviour seems surprising.
It makes sense for showModal() to use position: fixed, but I wouldn't expect that behaviour when calling show().

At risk of this ended up back in the CSSWG, it feels like what would make sense is something like this:

dialog {
  position: absolute;
}

dialog:modal { /* Hypothetical pseudoclass that does not currently exist */
  position: fixed;
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sefeng211 - Thoughts on above? I'd be happy with the above proposal where the applied CSS would be:

dialog:modal {
  position: fixed;
  overflow: auto;
  inset-block-start: 0; inset-block-end: 0;
  /* 6px + 2em = border + padding */
  max-width: calc(100% - 6px - 2em);
  max-height: calc(100% - 6px - 2em);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. Make dialog to be absolute and modal dialog to be fixed looks much safer!

source Outdated
width: fit-content;
height: fit-content;
/* 6px + 2em = border + padding */
max-width: calc(100% - 6px - 2em);
max-height: calc(100% - 6px - 2em);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Today I learned the default border width is 3px; fun!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup! In an ideal world this would have box-sizing: border-box applied, but this would likely change existing users of <dialog> a little too much.

Copy link
Contributor

@emilio emilio Sep 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So:

  • I agree that the fixed-pos thing should only be done for modal dialogs. Actually I take it back, need to think a bit more about this.

  • In Gecko, we're using max-width: 100vw; max-height: 100vh; that seems better than this, as it preserves the right max size when authors change borders / padding, or box-sizing, which I expect to be common

  • Is block-size: fit-content well defined? In Gecko, it just behaves like auto, so an slightly more expressive way to do this would be inline-size: fit-content; block-size: auto; (or omitting block-size altogether). I guess that can be a separate discussion, but I think it is relevant because if it is specified to behave like auto, or it is not well defined on the block axis, then the top: 0; bottom: 0 will stretch the dialog, I think (late, so double-check me here Ian). In Gecko we do top: 50%; transform: translateY(-50%);, which conveniently is how this is done in the wild in all the examples we found, so it doesn't break positioning by sites, see https://bugzilla.mozilla.org/show_bug.cgi?id=1650820.

For reference, our stylesheet is this as of today. Modulo that bug I linked above (which is what caused us to use transform rather than translate, and which is fixed except for a UA-sniffing thing they're doing), we haven't found any other compat issues since we enabled it by default on Nightly months ago.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Gecko, we're using max-width: 100vw; max-height: 100vh; that seems better than this, as it preserves the right max size when authors change borders / padding, or box-sizing, which I expect to be common

The max-height is incorrect on FF today by default however, e.g. the border/padding/scrollbar is clipped when the size is exceeded.

Is block-size: fit-content well defined?

block-size: fit-content - This might be something that is generally underspecified.

This is used to trigger centering based on margins, as you've specified a height. This is generally useful for web-developers maybe we should file a bug on css-sizing / css-position to actually specify that this is supported? (To be clear I'm against us changing behaviour here to un-support this :) )

I'm also opposed to using transform as you've done this would break/prevent any sites using transform to animate a dialog in/out etc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

block-size: fit-content - This might be something that is generally underspecified.

Quickly looking at css-position you could make the argument that Blink's behaviour is expected.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also opposed to using transform as you've done this would break/prevent any sites using transform to animate a dialog in/out etc.

How so? The transform is overriden by the authors. These are not !important styles.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The max-height is incorrect on FF today by default however, e.g. the border/padding/scrollbar is clipped when the size is exceeded.

Ah, that's right... hm, I guess we either need to add box-sizing: border-box, or subtract border/padding. I think doing border-box sizing is cleaner, but if you'd rather leave the calc() that's probably fine too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that's right... hm, I guess we either need to add box-sizing: border-box, or subtract border/padding. I think doing border-box sizing is cleaner, but if you'd rather leave the calc() that's probably fine too.

Right - the change to border-box will likely break too many things.

How so? The transform is overriden by the authors. These are not !important styles.

This will break existing animations, e.g. if I've specified an animation from translate(-1000px) -> translate(0) this will look broken in FF as they don't accumulate.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you want max-width/height: stretch ?

Copy link
Contributor

@sefeng211 sefeng211 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@@ -57253,8 +57251,6 @@ interface <dfn>HTMLDialogElement</dfn> : <span>HTMLElement</span> {

<li><p>Add an <code data-x="attr-dialog-open">open</code> attribute to <var>subject</var>, whose value is the empty string.</p></li>

<li><p>Set the <code>dialog</code> to the <span>centered alignment</span> mode.</p></li>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is a bit surprising to me too. I was under the impression that all discussions that happened around it were targeting centered alignment mode.

source Outdated
inset-inline-start: 0; inset-inline-end: 0;
position: fixed;
overflow: auto;
top: 0; right: 0; bottom: 0; left: 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be written as inset: 0;

source Outdated
width: fit-content;
height: fit-content;
/* 6px + 2em = border + padding */
max-width: calc(100% - 6px - 2em);
max-height: calc(100% - 6px - 2em);
Copy link
Contributor

@emilio emilio Sep 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So:

  • I agree that the fixed-pos thing should only be done for modal dialogs. Actually I take it back, need to think a bit more about this.

  • In Gecko, we're using max-width: 100vw; max-height: 100vh; that seems better than this, as it preserves the right max size when authors change borders / padding, or box-sizing, which I expect to be common

  • Is block-size: fit-content well defined? In Gecko, it just behaves like auto, so an slightly more expressive way to do this would be inline-size: fit-content; block-size: auto; (or omitting block-size altogether). I guess that can be a separate discussion, but I think it is relevant because if it is specified to behave like auto, or it is not well defined on the block axis, then the top: 0; bottom: 0 will stretch the dialog, I think (late, so double-check me here Ian). In Gecko we do top: 50%; transform: translateY(-50%);, which conveniently is how this is done in the wild in all the examples we found, so it doesn't break positioning by sites, see https://bugzilla.mozilla.org/show_bug.cgi?id=1650820.

For reference, our stylesheet is this as of today. Modulo that bug I linked above (which is what caused us to use transform rather than translate, and which is fixed except for a UA-sniffing thing they're doing), we haven't found any other compat issues since we enabled it by default on Nightly months ago.

@emilio
Copy link
Contributor

emilio commented Sep 23, 2020

So regarding changing the styling of non-modal dialogs... I think I don't have a super-strong opinion. I think those right now don't have any specialness (other than the styling defined on the spec), so it may be less risky to just change the modal ones to be fixed.

@bfgeek
Copy link
Member Author

bfgeek commented Sep 23, 2020

So regarding changing the styling of non-modal dialogs... I think I don't have a super-strong opinion. I think those right now don't have any specialness (other than the styling defined on the spec), so it may be less risky to just change the modal ones to be fixed.

We'll need a :modal pseudo class in that case, (unless you are suggesting that we write to the inline-styles or something?)

@emilio
Copy link
Contributor

emilio commented Sep 24, 2020

We'll need a :modal pseudo class in that case, (unless you are suggesting that we write to the inline-styles or something?)

Yeah, that's effectively what we have internally in Gecko. Not sure if such a pseudo-class needs to be exposed to the web though.

@bfgeek
Copy link
Member Author

bfgeek commented Sep 24, 2020

Yeah, that's effectively what we have internally in Gecko. Not sure if such a pseudo-class needs to be exposed to the web though.

I'd slightly prefer to expose this to web-developers as 1) allows greater control, and 2) doesn't seem to be a reason not to?

@bfgeek
Copy link
Member Author

bfgeek commented Oct 1, 2020

@emilio - Are you ok w/ the height: fit-content (and I'll file an issue on the CSSWG spec clarifying our behaviour?) - and OK w/ the additional of a :modal pseudo?

@emilio
Copy link
Contributor

emilio commented Oct 1, 2020

Yes, I'd be ok with those. And per our other discussion it should be fine to make the max/min-height calc(100% - borderpadding) rather than viewport units / box-size.

@bfgeek
Copy link
Member Author

bfgeek commented Oct 2, 2020

@sefeng211 @emilio @domenic - I've added the :modal pseudo-class which relies on a flag within each dialog to conditionally set the position: fixed etc styles, PTAL :) .

domenic
domenic previously approved these changes Oct 2, 2020
Copy link
Member

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, editorially and matches my expectations. I'm happy to merge after @emilio confirms. It seems like @sefeng211 already has chimed in to agree with this version.

Copy link
Contributor

@sefeng211 sefeng211 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Contributor

@emilio emilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks!

@annevk
Copy link
Member

annevk commented Oct 5, 2020

@whatwg/css do new pseudo-classes need to be coordinated with the CSS WG?

(Apologies if I missed something, but I don't see it in https://drafts.csswg.org/selectors/ and it's not discussed in w3c/csswg-drafts#4645 either as far as I can tell.)

@annevk annevk added the do not merge yet Pull request must not be merged per rationale in comment label Oct 5, 2020
@bfgeek
Copy link
Member Author

bfgeek commented Oct 6, 2020

@whatwg/css do new pseudo-classes need to be coordinated with the CSS WG?

Not typically - many examples of pseudo-classes being defined outside of css specifications, e.g.
Many of the pseudo-classes in the html spec, e.g. https://html.spec.whatwg.org/#selector-in-range
https://immersive-web.github.io/dom-overlays/#xr-overlay
etc.

@annevk
Copy link
Member

annevk commented Oct 7, 2020

I'm not familiar with XR, but https://drafts.csswg.org/selectors/#range-pseudos covers the one you mentioned in HTML. And I'm pretty sure the CSS WG wanted to be involved in any additions going forward as HTML minting a couple came as a surprise. (It also seems there needs to be some involvement as there is no registry other than the Selectors document.)

source Outdated
inset-block-start: 0; inset-block-end: 0;
/* 6px + 2em = border + padding */
max-width: calc(100% - 6px - 2em);
max-height: calc(100% - 6px - 2em);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is going to cascade well. If the author changes the border width at all, it'll be wrong, right? You should use the stretch keyword.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine w/ this if @emilio is. Change pre-emptively to 'stretch'.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@domenic not sure if you noticed this but @emilio pointed out to me that currently no browser implements stretch. Firefox might eventually, but if someone were to write a test about the computed value for a dialog element that is modal, they would not see stretch...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Will browsers block implementing dialog until they implement stretch then? Or should we change this to something implementable?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think Firefox would block on stretch.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have stretch but would use -webkit-fill-available which we've been slowly been moving to the defined stretch behaviour. For this particular case it is a drop in replacement. However happy also if we keep as the calc(100% - 6px - 2em).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. So I guess we have two concerns here:

  1. Interop. If Blink uses -webkit-fill-available and Gecko uses calc(), it sounds like there will be interop problems if the author changes the border width. Is this OK?

  2. Compat. If both engines use calc(), then we might be prevented from ever upgrading to stretch since it would impact the layout of <dialog>s whose border width was changed.

These trade off against each other, e.g. by sacrificing interop, we can preserve a bit of flexibility for future changes.

If we prioritize interop, then I'd say the spec (and Blink) should probably use calc(), and in the future, when both engines implement stretch, we could consider upgrading the spec, subject to the usual slow change process for any compat-impacting upgrade of this sort.

If we prioritize compat, then the spec should probably use stretch, since it indicates the desired behavior and roughly matches Blink's -webkit-fill-available IIUC.

(There's a third concern, roughly "conformance", which is that it'd sure be nice if everyone agreed with the spec on things like getComputedStyle(dialog).maxWidth. But that's pretty low priority.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@emilio Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the inline axis we could probably use -moz-available. We don't have anything hooked up for the block axis to do this, I think, but it may not be too hard to either hook that or implement stretch.

Or we can probably just use calc(), honestly I think it's ~fine.

This effectively only changes the total max size of the dialog which is intended to prevent unreachable dialogs. It is mostly a safety mechanism. I don't think we'd have much trouble changing it to stretch in the future (because an overflowing modal dialog is basically always a bug, and stretch will be either equivalent or superior to both solutions).

I think the most concerning case against calc() is full-width dialog in the inline-axis which the author has styled to use less padding/border (or box-sizing: border-box). In that case calc() will incorrectly shrink the dialog too much in the inline axis and it could look a bit ugly (I'm not too concerned for shrinking too much in the block axis I think...).

But generally it seems both Chromium and Gecko have a solution for the inline axis that does the same as stretch, and I don't think using either solution prevents us from moving to stretch in the future.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it likely won't prevent us from moving to stretch in the future, I've changed back to the calc() version.

source Outdated
dialog:modal {
position: fixed;
overflow: auto;
inset-block-start: 0; inset-block-end: 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are already cascading in from the default styles for DIALOG, so they're not necessary.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are necessary as the default styles only include the inline direction variants.

source Outdated
@@ -113100,6 +113068,14 @@ dialog {
background: white;
color: black;
}
dialog:modal {
position: fixed;
overflow: auto;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to incorporate this also into the default styles for DIALOG?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fserb Can you explain why for dialog:modal was added overflow: auto?

That mean if dialog has html dropdowns or html tooltips which shows out of the dialog are broken because dialog shows scrolls by default. Can we eliminate scrolls in dialogs at all by default?

cc @sefeng211 @domenic

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think scroll by default makes sense, otherwise dialogs that are larger than the viewport are completely unreadable. If you're 100% sure that your content won't overflow the viewport you can set overflow: visible.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is rare case when dialog has the same size as viewport, any case the change was break us. And question that Do we have strong reason to have overflow: auto (Ideally - to remove it.).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could happen fairly easily if you have a small viewport and large content in the dialog. Defaulting to not leaving content unreachable makes sense imo.

@bfgeek
Copy link
Member Author

bfgeek commented Oct 28, 2020

@emilio @domenic @annevk I've change the pseudo to :-internal-modal add added prose that should should not be exposed outside the UA stylesheet. We can describe the dialog:-internal-modal rule in prose instead, but if describing these things in prose has taught us anything it'll likely be incorrect :).

@domenic
Copy link
Member

domenic commented Oct 28, 2020

I don't think we should definite an internal pseudo-class for this, if it's not observable by web content. Instead I'd suggest using prose. E.g. like is done in other sentences in the Rendering section like

When an input element's dir attribute is in the auto state and its type attribute is in the Text state, then the user agent is expected to act as if it had a user-agent-level style sheet rule setting the 'unicode-bidi' property to 'plaintext'.

or

When the document's character encoding is ISO-8859-8, the following rules are additionally expected to apply, following those above:

@domenic
Copy link
Member

domenic commented Oct 28, 2020

Oh, comment collision. Yeah, I do prefer prose a good amount, and I think it aligns better with precedent.

@bfgeek
Copy link
Member Author

bfgeek commented Oct 28, 2020

I don't think we should definite an internal pseudo-class for this, if it's not observable by web content. Instead I'd suggest using prose. E.g. like is done in other sentences in the Rendering section like

Even if this is how all the UAs do this?

@domenic
Copy link
Member

domenic commented Oct 28, 2020

Yeah. I think although it is convenient for UAs to mix together internal implementation details with the author-facing pseudo-class concept, it's not a great idea at the spec level, and muddies the meaning of pseudo-classes.

If the CSSWG would like to formally define a notion of internal pseudo-classes, and if we did a wholesale update of all similar cases in HTML (e.g. an :-internal-ISO-8859-8 pseudo-class), then it would be a reasonable route. But until then, I think they should be in prose.

@domenic domenic dismissed their stale review October 28, 2020 17:55

Things are changing

@bfgeek
Copy link
Member Author

bfgeek commented Oct 28, 2020

If the CSSWG would like to formally define a notion of internal pseudo-classes

RESOLVED: Add a hidden pseudo-class for this purpose, in order to solve styling issue while leavine open the possibility of HTML improving its API

?

@bfgeek
Copy link
Member Author

bfgeek commented Oct 28, 2020

(from w3c/csswg-drafts#4645 )

@domenic
Copy link
Member

domenic commented Oct 28, 2020

Oh OK, so you'll also work on defining the internal pseudo-class concept in CSS? It feels like that would involve changes to the parser and cascade specs, right?

Copy link
Member

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with potential nit

source Show resolved Hide resolved
Copy link
Member

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Continues to LGTM. Will give this another day or two in case folks want to review further, but I'm looking forward to merging this.

@annevk
Copy link
Member

annevk commented Oct 29, 2020

#5936 (comment) is probably worth looking into once more before merging.

@domenic domenic removed the do not merge yet Pull request must not be merged per rationale in comment label Nov 3, 2020
@domenic domenic merged commit 979af15 into whatwg:master Nov 3, 2020
@annevk
Copy link
Member

annevk commented Nov 4, 2020

Could someone update OP with the implementation bugs?

@bfgeek
Copy link
Member Author

bfgeek commented Nov 6, 2020

Could someone update OP with the implementation bugs?

Done - @emilio I used mozilla/wg-decisions#412 lmk if you'd like something else.

@bfgeek bfgeek deleted the bfgeek/dialog branch November 6, 2020 19:19
@emilio
Copy link
Contributor

emilio commented Nov 6, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

8 participants