Closed grorg closed 3 years ago
The CSS Working Group just discussed dino suggestion on writing modes
.
I was just talking to @heycam about this -- and one question he brought up is whether we should pull in most/all of the non-boolean media queries and allow them to be specified as variables. Do people want to write calc expressions based on things like the width
media query, etc.?
Do people want to write calc expressions based on things like the
width
media query, etc.?
Isn’t this already possible with the vw
and vh
CSS units?
Would constant()
work inside calc()
so we could do things like this?
* {
font-size: calc( (constant(user-font-size) * 0) + 12px);
}
Do people want to write calc expressions based on things like the width media query, etc.?
When you say width
do you mean the same value as window.innerWidth
? I experimented a little big with exposing various values as CSS properties to see what uses I could come up with. Things I experimented with included these global values:
Cursory experimented with exposing:
innerWidth
innerHeight
Scrollery experimented with exposing the following values:
scrollWidth
scrollHeight
scrollTop
scrollLeft
And then the most fun was exposing values related to HTML elements as CSS variables with Varsity like:
offsetWidth
offsetHeight
offsetLeft
offsetTop
value
In my experiments I would use JavaScript to supply, and keep updated, the values for these special CSS variables, and then tried to incorporate these variables in my CSS. Many of these techniques aren't things that these 'User Agent Properties' would enable, but I'm sharing some of these here because what they are, and the way they would be used seems so parallel. Perhaps the CSSplus experiments can validate the usefulness of these 'User Agent Properties' and these 'User Agent Properties' being suggested and add some merit to the idea of exposing more of these values from the browser to CSS using CSS Variables as an interface:
offsetWidth
scrollTop
as a CSS variablescrollHeight
to animate from height: 0;
as a CSS variablechildren.length
as a CSS variableoffsetWidth
as a CSS variableoffsetWidth
as a CSS variableSo hopefully that helps support the idea with some examples of something kind of similar, and gives an idea of what the CSS might look like when integrating these 'global CSS variables' into designs :D
I was just talking to @heycam about this -- and one question he brought up is whether we should pull in most/all of the non-boolean media queries and allow them to be specified as variables. Do people want to write calc expressions based on things like the width media query, etc.?
It's not a bad idea; I'm down for it. It would just mean we'd have to be a little careful about naming conflicts between MQs and other UA-vars, but I don't think that's a huge issue. (Alternately we could namespace, but I don't think that's necessary.)
Also: I really want to hook this functionality for custom JS things; the syntax is already super compatible. Just create a map hanging off of document or CSS or something, require the keys to be --foo
form and the values to be TypedOM instances (so you get grammar-checking at parse-time, as intended), and boom, "global variables" that can be used in all locations in a stylesheet, including in MQ conditions, and which don't have unfortunate performance implications due to inheritance from root.
I had a little brainstorm about exposing JS properties of elements to CSS via CSS variables so authors can make use of a little more situational awareness when writing styles. I've been toying around with this idea for a while, but this thread about User Agent properties gave me the motivation I needed to get it published :D
There are a few fun code examples in the README and on the demo page: https://github.com/tomhodgins/varius#examples
I wonder if a value handoff between JS and CSS like this via an interface of CSS variables could help give CSS more power without needing to extend CSS features 🤔
Now that the iPhone X has been announced, the suggestion to add safe-area-insets is more clear. The idea is that a page needs to know how to avoid the rounded corners and notch at the top or side of the screen (depending on orientation).
The term "safe area" has been around for a fair while in TV, and we think it makes sense here. Since the value can change depending on orientation, it needs to be exposed directly to the style sheet - hence the proposal for CSS constants.
I think we had three major things to decide on:
The name: whether to use constant(name)
, var(name-without-leading-hyphen)
or var(user name)
. I'd prefer constant
because it makes it more clear that there is no way for the developer to set these properties.
A JS hook so that they can be easily queried and raise notifications on change.
A place to define the new properties/values. Maybe these just end up in the respective specifications clearly labelled as read-only.
a page needs to know how to avoid the rounded corners and notch at the top or side of the screen
Why would Apple deem it OK to place this burden on web developers?
@tobireif
Why would Apple deem it OK to place this burden on web developers?
We're not requiring them to do this. By default we'll avoid the notch by insetting everything. However, if the author wants their page to use the full area, they can opt in but then need to avoid the corners.
Why don't you just add a property to body
or html
that tells the browser that it's ok to render stuff that's normally cut off because it's outside the viewport?
render-safe-area: allow;
And then the UA can just fill up the space as needed with stuff that's normally cut off? This way the developer could just place elements outside the normally available viewport, e.g. render a header element that should extend to the edges of the screen with negative margins.
Potentially browsers that support this could add CSS units that are 1/100th's of the safe area (analogous to vw/vh).
This could be useful not only for iPhone X, but also for things like circular watch screens, etc.
Potentially browsers that support this could add CSS units that are 1/100th's of the safe area (analogous to vw/vh).
I think that is the whole point of the proposal for "Use Agent Variables", the value of the variables we are talking about would be exactly similar to variables containing the size of the safe/unsafe area.
I don't want to discourage talking about render-safe-area and other proposals at all, but in a different issue (such that the current issue can stay focused on ironing out the user-agent variables proposal).
I agree with @grorg reasoning about the default behaviour and the new proposed properties, but still, ideally neither the user, nor the developer should need to bother with this.
For colors there are already the so called System Colors, that do work in some browsers and OSes (namely IE and Firefox, never tested in Edge). The Background, Highlight and HighlightText colors also work in Windows Phone's IE and one can do a fully adaptive app theme, that mutates with the currently selected background and highlight in the OS - something not possible in iOS/Android.
If these constants are going to be implemented in all browsers, I'm all for that.
Could this help work around the non-tappable area at the bottom of the viewport in iOS Safari? As a designer of web apps I would love a way around that.
Now that the iPhone X has been announced, the suggestion to add safe-area-insets is more clear. The idea is that a page needs to know how to avoid the rounded corners and notch at the top or side of the screen (depending on orientation).
This has obvious parallels to the Round Display stuff; we should make sure these work in compatible ways. But like @FremyCompany said, this is a different issue and the specifics should be discussed in a different thread.
The name: whether to use constant(name), var(name-without-leading-hyphen) or var(user name). I'd prefer constant because it makes it more clear that there is no way for the developer to set these properties.
I also strongly prefer constant()
. (I discussed in the meeting how this ties into the desire for cheaper "global variables", so authors could use constant(--name)
while UA-defined ones are just constant(name)
)
A JS hook so that they can be easily queried and raise notifications on change.
:+1: This is easy API-wise - just hang a maplike off of CSS
, and make it an event emitter.
A place to define the new properties/values. Maybe these just end up in the respective specifications clearly labelled as read-only.
I'd prefer we make a new spec for this that's intended to be where most of them sit. Like Selectors is for selectors - most of them live there, but a few do live in other specs.
This could be useful not only for iPhone X, but also for things like circular watch screens, etc.
iOS 11 uses viewport-fit
in the viewport meta tag to handle this, which is consistent with the CSS Round Displays working draft.
Why don't you just add a property to body or html that tells the browser that it's ok to render stuff that's normally cut off because it's outside the viewport?
And then the UA can just fill up the space as needed with stuff that's normally cut off? This way the developer could just place elements outside the normally available viewport, e.g. render a header element that should extend to the edges of the screen with negative margins.
We've done that, via a viewport tag. The problem is that we can't just extend objects - because it doesn't always look correct. Also, many objects are snapped to the edges anyway (think of a top or bottom bar), so they need to know how much padding to include in those objects in order to know they are showing content without being clipped.
After a lot of experimentation, we concluded that the best thing to do was to give authors the ability to extend to the full viewport and avoid edges if they want to, but we'd do the right thing otherwise.
Note that this discussion is orthogonal to the constant
proposal. I think there is general support for that without finalizing the safe-area-inset topic.
/me dons fire retardant suit
Note that constant
is partially supported in iOS 11/High Sierra, but we are very open to changing this ASAP to something everyone agrees on. The good news is that the values are always zero on existing hardware (and parsing errors mean they fallback easily on other engines)
This has obvious parallels to the Round Display stuff; we should make sure these work in compatible ways. But like @FremyCompany said, this is a different issue and the specifics should be discussed in a different thread.
Yep, agreed. As mentioned, we use the viewport-fit
meta tag from round displays. One can imagine a display with rounded corners as just a version of a rounded display (or visa versa)… ignoring the notch.
Minor suggestion: const()
might be a nicer name to parallel var()
(since that didn't get named variable()
).
For anyone curious about how this works in practice on the iPhone X (both the viewport-fit
aspects from the CSS Round Displays spec and the proposed constant()
values), I've written a blog post about it with screenshots showing some different cases: https://ayogo.com/blog/ios11-viewport/
I also strongly prefer constant(). (I discussed in the meeting how this ties into the desire for cheaper "global variables", so authors could use constant(--name) while UA-defined ones are just constant(name))
I have got a problem here, and my problem varies ;) More precisely, the values that we are discussing here are not going to be constants. The scrollbar width can be updated on Windows and it is very likely we will end up toggling them off for instance when you detach your keyboard and got to tablet mode.
Similarly, when you enable an high-contrast theme, "constant" colors are going to change.
Even the proposed notch-safe space will depend on the screen orientation, I assume.
All in all, I have not seen any argument to convince me we should invest in adding a new function instead of a namespace for existing value references.
TLDR: "global variables" != "constants"
Hi Dean 😃
We're not requiring them to do this.
You had written "a page needs to know how to avoid the rounded corners and notch" - that sure sounded as if each page is required to know how to avoid the rounded corners and the notch.
By default we'll avoid the notch by insetting everything. However, if the author wants their page to use the full area, they can opt in but then need to avoid the corners.
Thus on/beside each page that doesn't opt in (as the myriads of existing unmaintaned web pages ever created up to now) there will two thick white bars, correct?
https://twitter.com/thomasfuchs/status/907764896829452288
Although the white bars are stylable (albeit in a limited way it seems https://twitter.com/thomasfuchs/status/907770902338785280 ), and although though there might be CSS in the future for intentionally-fuller-area pages for dealing with the notch, ideally web developers wouldn't have to bother with Apple's notch or Apple's white bars - at least in my opinion.
@tobireif, I agree that in addition to giving authors explicit control over how the screen shape is handled, Safari on an iPhone X should by default display pages in a way that takes the notch and rounded corners into account in a reasonable fashion, so that authors are not required to make changes to have their pages properly displayed on the device.
You also seem to be making the argument that's Apple's current answer to this problem (letterboxing the page using the background color, to avoid unexpectedly clipping content in pages not designed to take into account the screen shape) is a completely unfit way to handle the problem. Why do you think that is the case, and what alternative do you suggest?
To me, clipping content by default—to avoid ungainly, unexpected letterboxing—has far more breaking potential, potentially hiding important areas of content or interactive elements. Without allowing any clipping to occur, it's hard not to end up with blank areas around the page; any ideas as to handle these better is appreciated.
Another nice point of the letterboxing-by-default approach is how nicely it folds in with the viewport-fit
working draft, so that authors can work to target non-rectangle displays in general, not just iPhone X-shaped ones.
How should behave this UA Properties/Constants when writing direction is RTL instead of LTR?
safe-area-inset-right
safe-area-inset-left
How should behave this UA Properties/Constants when writing direction is RTL instead of LTR?
Those refer to the left and right of the physical device screen, regardless of writing direction
@Cykelero
You also seem to be making the argument that's Apple's current answer to this problem (letterboxing the page using the background color, to avoid unexpectedly clipping content in pages not designed to take into account the screen shape) is a completely unfit way to handle the problem. Why do you think that is the case, and what alternative do you suggest?
Ideally there wouldn't be a notch. That is my opinion. No notch, no issues 😀
The notch issue is not caused by a force of nature, but it has been added based on a decision by Apple. That is the issue.
Now that they did add the notch, it sure is sensible to limit the default viewport to the safe area (although as default color for the side-bars, black-like-the-notch-etc might be better than glowing bright white), and it also is sensible to also offer an option for using the full area (plus constants for handling the notch etc).
I'm not arguing anything. I'd like to have had a vote (or better a veto 😀 ) regarding whether Apple adds the problematic notch, but alas that decision has been set in stone already.
Now we can only deal with the issues, which I sure will do 😀 I'll probably (normally) stay inside the safe area (the default viewport) but try to style the side-bars/letterboxes in a sensible way.
For the benefit of anyone finding this looking for actionable advice on how to deal with the iPhone X viewport issues, here’s a great write-up on using viewport-fit
: http://stephenradford.me/removing-the-white-bars-in-safari-on-iphone-x/
What @FremyCompany said. @tabatkins had to explain to me that there are two axes of variablilty: changing over tree context and changing over the lifetime of the document. constant()
is about tree context, but “constant” connotes time. global()
would be a better name.
I have got a problem here, and my problem varies ;) More precisely, the values that we are discussing here are not going to be constants.
Yeah, what eeeps said - they're constant over the page, as opposed to refs that can vary from element to element.
All in all, I have not seen any argument to convince me we should invest in adding a new function instead of a namespace for existing value references.
A big difference is that these are usable in places other than properties and animations - you should be able to use these "constants" in MQs and such. (Again, because they're constant across the page, and so don't care about what context they're being used in.) I'm loathe to say "var() is only allowed on elements normally, but you can use it wherever you want if you use this particular type of var name" - much better for everyone if it's a totally distinct name.
From http://stephenradford.me/removing-the-white-bars-in-safari-on-iphone-x/:
I added the following to the main container on the website.
padding: constant(safe-area-inset-right);
Unless I'm mistaken, this will break when the phone is rotated. It also assumes that the right inset will be the largest, and that padding by the largest value on all sides will look fine.
To avoid this kind of error, should we have safe-area-inset
that could be used in shorthand properties like margin, padding, border-width? It would be equivalent of constant(safe-area-inset-top) constant(safe-area-inset-right) constant(safe-area-inset-bottom) constant(safe-area-inset-left)
.
We might also consider ways to get the max/min inset value, via a generic max
and min
function.
It's worth pointing out that these do work in calc()
expressions, so something like padding-top: calc(20px + constant(safe-area-inset-top))
works like a charm
Unless I'm mistaken, this will break when the phone is rotated. It also assumes that the right inset will be the largest, and that padding by the largest value on all sides will look fine.
The inset values adjust when you rotate, so it probably won't break on rotation, but it is indeed wrong.
To avoid this kind of error, should we have safe-area-inset that could be used in shorthand properties like margin, padding, border-width?
If it's possible to have variables/constants produce multiple values, then yes, it would help avoid wrongly over-applying a single edge's value.
We might also consider ways to get the max/min inset value, via a generic max and min function.
CSS calc(), min() and max() are super useful with this, they are already in the CSS Units and Values Level 4 Editor's Draft. https://drafts.csswg.org/css-values/#funcdef-min
Besides the use you describe, it's often useful to padding or margin to the minimum of the inset or a fixed padding for the case where there's no inset.
To me, this could be easily avoidable by having WebKit support a new meta tag that either 'respects full viewport' (so takes the notch into account) or instead on the WebKit/Safari side, just indent the corners to line up the corners and notch so there's no need to inset. Surely that's the most backwards compatible and on-breaking way forward?
This seems very overkill for supporting one platform by implementing more CSS properties that is only useful for iOS Safari (on iPhone X).
Something to the effect of:
<meta name="safe-viewport" content="render-viewport-spacing=full" />
@danieltj27 see the references to viewport-fit in this issue.
I'm really hoping this 'notch' thing is just a very short-lived phase that doesn't last. However, I do expect to see more rounded screens. It could be helpful to have the corner radius values as a relative length unit (like em and rem). Perhaps something like vcr
, 'viewport corner radius' not a 'videocassette recorder' :)
margin-left: 0.5vcr;
But then again, the values for each corner could be different. Also, we should consider that a UI may want to respond differently to non-square corners than to a 'notch' protruding into the viewport.
Also, anyone know how Essential plans to treat the 'notch' in their phone's viewport?
As Dean mentioned, the concept of a "safe area" isn't specific to the iPhone X and also applies to things like TV screens. This issue is specifically about defining a way for user agents to expose those values (and others, such as user requested font size) to web pages.
Discussion around the idea of viewport-fit
, rounded corners, and non-square screens is better targeted towards the CSS Round Devices spec.
Good to know. Safe area for a TV seems quite different than the iPhone X / Essential phone 'notch'.
I've filed a pull request for the constant() and UA properties part of this issue. There will be a separate pull request for the safe-area-insets (when I work out where they should go).
I'll note that the iPhone X notch isn't the only special thing that a user agent might want to tell the author to avoid. It could be an on-screen overlay button or keyboard, or a picture-in-picture video that is being played by another app on the system.
There are many reasons why the User Agent might want to tell the author of the page that content might be occluded and non-interactive in a particular region.
@othermaciej Yeah, custom properties support multiple values. Here's an ugly demo.
OK so I’ve been following this issue for a while and there are some details for which I’d like clarifications if possible. Sorry if some were addressed or implied (and cc-ing @dauwhe and @TzviyaSiegman since that will probably impact the Publishing Working Group and the personalization Task Force at some point).
The first question is quite simple: who will be able to create and set those constants?
For instance, I assume user-font-size
could be set based on the iOS a11y preference or a browser setting, and user-background-color
based on high contrast mode in Windows 10.
But what if you have an intermediary layer managing documents like, say iBooks or Google Play Books? They have sepia and night modes, their own font-size user setting, and a couple of extras options which OSs and browsers might not offer (text-align
, hyphens, line-height
, dyslexia typeface, etc.).
I guess that if the apps are using a web view, they might be able to create and set them. Correct? But what about cloud versions?
Sorry if that is unclear to me, I was kinda super happy when I discovered this proposal as it could help with user settings (both apps and authors) and I guess I need an answer as whether this could fit in there or not. To be fair, this should probably be global variables since they will change at runtime.
On a related note, PDF version 2 is using HTML and CSS to make documents more accessible, so PDF apps might offer such options at some point (and PDF is still a popular format).
Another question: how will this possibly relate to COGA Semantics to Enable Personalization?
People might not like Reading Systems (and I kinda get the reasons why), but if it proved anything, it’s that when user settings have a GUI in the app’s chrome, user will override a lot of authors’ styles (and expect those user settings to be available). On the other hand, authors tend to hate when their entire stylesheet is removed (reader modes, which sometimes fail spectacularly with more than basic documents).
Consequently, I can clearly see how User Agent properties could help, although the burden would be put on authors. Now, this proposal deals with user settings (but this section is not yet developed), so back to the first question.
@grorg IMHO unless Safari supports CSS Level 4 min/max at the same time, it will be tough to accommodate the complex positioning rules we have today.
There are many reasons why the User Agent might want to tell the author of the page that content might be occluded and non-interactive in a particular region.
I hope you mean varying safe-area-inset-* when Safari's bars come and go.
@diligiant
I hope you mean varying safe-area-inset-* when Safari's bars come and go.
Those don't tend to obscure content. They can be scrolled away, unlike the notch. What you're talking about is a better fit for visualViewport
.
@jakearchibald the bottom bar does (try positioning something at 95vh). It disappears when you start to scroll but initially, you have no way to know where the visible content ends.
@diligiant this information is best exposed by visualViewport
.
Here is WebKit's proposal for a new type of property and variable.
User Agent Properties
This specification defines an open-ended set of properties called
User Agent properties
, which, among other things, are used to define the substitution value ofconstant()
functions.Name: (various) Value:
<declaration-value>
Initial: (nothing, see prose) Applies to: all elements Inherited: yes Percentages: n/a Media: all Computed value: specified value with variables substituted (but see prose for "invalid variables") Canonical order: per grammar Animatable: noA User Agent property is not specified in a style sheet. User Agent properties instead define variables, referenced with the
constant()
notation. For example, a page that wants to use the user's requested font sizing, and page background:Unlike other CSS properties, User Agent property names are case-sensitive.
User Agent properties are not reset by the all property. If a style rule attempts to define a value for a User Agent property, it is ignored.
Using Cascading User Agent Variables: the 'constant()' notation
The value of a
User Agent property
can be substituted into the value of another property with theconstant()
function. The syntax ofconstant()
is:The
constant()
function is used in the same manner, and follows the same rules, as thevar()
function.Defined User Agent Variables
user-font-size
: User's requested font sizeuser-background-color
: User's requested background coloruser-foreground-color
: User's requested foreground colorsafe-area-inset-top
: Inset, as a<length>
from the top of the viewport to the title-safe content area.safe-area-inset-right
: Inset, as a<length>
from the right of the viewport to the title-safe content area.safe-area-inset-left
: Inset, as a<length>
from the left of the viewport to the title-safe content area.safe-area-inset-bottom
: Inset, as a<length>
from the bottom of the viewport to the title-safe content area.