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

Title bar customization: new CSS properties for easier layout #177

Closed
amandabaker opened this issue Jan 27, 2020 · 8 comments
Closed

Title bar customization: new CSS properties for easier layout #177

amandabaker opened this issue Jan 27, 2020 · 8 comments
Assignees

Comments

@amandabaker
Copy link
Member

We've received feedback from multiple people that the JS APIs for laying out the title bar are not ideal.

  1. JS calculations are slower than CSS, so the page will not resize smoothly
  2. It's heavier to use as a dev. There are a lot of calculations involved that vary depending on which side the overlay is on, so it's more prone to bugs

The CSS proposals include:

  • Adding new CSS environment variables, env(). Maybe env(caption-controls-inset-left/right/top/bottom)?
  • Add new units for laying out content within the title bar: th and tw which operate similar to vh and vw, except within the width of the title bar

However, we have also received feedback that it's not worth adding CSS variables/properties/units that need to be standardized and maintained, when they are intended for such a niche use case, so this is something we should take into consideration as well.


Comments from other issues/discussions

From @mgiuca in #165

I don't like the fact that you need to run JS code to update your in-client UI to match the overlay. That is workable, but not ideal, especially since it means that UI isn't being updated by the browser's layout code, but by the much slower JS event loop. That means there's likely to be a user-noticeable lag between resizing the window (or the UA updating the overlay size) and the painting of the in-client UI. Ideally, all the code in your "resizeTitleBar" example could be done in CSS. I just learned (from an internal chat about this) that there's a CSS thing called env() which allows CSS rules to access user-agent-supplied variables. Could we expose the overlay bounds as an env() variable, which would allow the majority of use cases for in-client title bar UI to be sized with CSS rather than JS? Note that this request may conflict with my above request to have multiple overlay rects, since that might make it much harder to expose as a CSS variable. (I don't know much about CSS; I just heard this was a thing, so apologies if this is unworkable for some other reason I haven't foreseen.)

From @aarongustafson

We have units for viewport height & width (vh & vw, respectively). Would it make sense to propose th & tw as well? This would enable designers to avoid having to do calculations in JavaScript all the time and let them use CSS.

Q: Would a hypothetical tw include the reserved area or not?

@domenic
Copy link

domenic commented Jan 28, 2020

I'm a bit curious why the existing CSS env() properties for notches don't work here. Why not just consider the close/maximize/minimize buttons as a notch? That way people can code for both phone PWA notches and desktop PWA windows at the same time.

@amandabaker
Copy link
Member Author

From W3C CSS Environment Variables:

"The safe area insets are four environment variables that define a rectangle by its top, right, bottom, and left insets from the edge of the viewport. For rectangular displays, these must all be zero, but for nonrectangular displays they must form a rectangle, chosen by the user agent, such that all content inside the rectangle is visible, and such that reducing any of the insets would cause some content inside of the rectangle to be invisible due to the nonrectangular nature of the display. This allows authors to limit the layout of essential content to the space inside of the safe area rectangle."

According to that description, combining all the insets together creates a rectangle that the developer can safely draw in, and we can't shrink this rectangle further than necessary.

If we were to return two safe-inset-*s with a non-zero value, then reducing only one of these two insets would not satisfy the requirement above.

We could still set safe-inset-top as a shortcut for the height of the caption controls overlay, but we can't provide both the height and width of the overlay using safe-inset-*s.

@bathos
Copy link

bathos commented Jan 28, 2020

@domenic How do you envision that exactly?

The safe-area-inset-X properties currently seem to describe the largest possible rectangle which can be drawn, unobstructed in the viewport — the “safe” zone for content, with any parts of viewport rect outside the rectangle described by safe-area-inset-X not guaranteed to be visible. If the same vars are used to indicate where overlaid controls are, it seems like the rectangle being described ends up being something pretty different:

 ╭──╮      ╭──╮                
 │┈┈╰──────╯┈┈│ ╌╌┌┈┈┈┈┈┈┈┈┈┈┈┈┐
 │            │   ┆            ┆
 │            │   ┆            ┆
 │            │   ┆            ┆
 │            │   ┆            ┆
 │            │   ┆    SAFE    ┆ 💕
 │            │   ┆            ┆
 │            │   ┆            ┆
 │            │   ┆            ┆
 │            │   ┆            ┆
 ╰────────────╯ ╌╌└┄┄┄┄┄┄┄┄┄┄┄┄┘

 ┌─┬──────────────────────┬────┐
 ├─┘┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈└────┤ ╌╌┌┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┐
 │ ┆                      ┆    │   ┆                      ┆
 │ ┆                      ┆    │   ┆                      ┆
 │ ┆                      ┆    │   ┆                      ┆
 │ ┆                      ┆    │   ┆         SAFE         ┆ 🤔
 │ ┆                      ┆    │   ┆                      ┆
 │ ┆                      ┆    │   ┆                      ┆
 │ ┆                      ┆    │   ┆                      ┆
 └─┴──────────────────────┴────┘ ╌╌└┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┘

I don’t think these are the same concept (we want to draw in the middle top “unsafe” rect in example 2, as well as both allegedly unsafe rects in the second row of example 2), but I’m not sure if I’m missing something...


Edit: seems I was writing at the same time as @amandabaker, who addressed the same thing, so this is a bit redundant now that I see that response too.

@domenic
Copy link

domenic commented Jan 28, 2020

I don’t think these are the same concept (we want to draw in the middle top “unsafe” rect in example 2, as well as both allegedly unsafe rects in the second row of example 2), but I’m not sure if I’m missing something...

I see your point, and the diagram is very helpful. However this feels like a failure of the CSS safe-inset spec to me... or at least an opportunity for extending it, instead of having two specs side by side.

In particular, what is really different here?

  • There are two notches instead of one
  • The notches are in the corners instead of in the middle

It's surprising that would need a whole new model.

More concretely, referring to your diagram, I'd argue that the top area (between the two notches) should be counted as "unsafe" similar to the iOS "ears". It's where you draw extra information that might jut up against OS/hardware constraints. The side areas being counted as "unsafe", though, is a bit wierd, and perhaps an area to explore tweaking the spec regarding...

I'll note that I might be totally wrong, and perhaps the two differences I list are enough to need a whole new model. But I think it's worth exploring, and perhaps getting the CSS WG's opinion.

@bathos
Copy link

bathos commented Jan 29, 2020

I imagine you’re right that a unified API is (or at least would have been...?) possible.

The ‘largest real rectangle’ concept has been useful, but it’s pretty tailored to needs related to a specific generation of devices. One currently expects the unsafe zone to be small and effectively decorative (e.g. allowing a header’s background image to extend into that area while ensuring the header’s text doesn’t). But the largest-rectangle model for “safe area” wouldn’t be very helpful at all for handling layout within, say, a circular display ... not that I know of any, but I think that extreme example aligns with your sense that the current safe-inset model may be underbaked. For both notches and titlebar components you can say the data we want to act on is “the effective viewport shape, which might not really be the viewport rect.” I have no idea what an API for that would look like though — it doesn’t seem like css env vars could readily express that if it can be some rando polygon / path.

That said, I still tend to think “shape of display” and “positions and dimensions of titlebar chrome” are pretty different. In the latter case, it’s significant that the titlebar area is a titlebar — it’s not just “available space,” it’s space where, if available, one likely wants to render titlebar stuff. So I’m not certain how one would write CSS that works correctly for both titlebar layout and non-rectangular display bleed if the vars were conflated — we need at least some signal that it’s space which exists for that purpose. Plus conflation seems to include an assumption that there’d never be titlebar components within a non-rectangular display, which seems iffy.

@mhartington
Copy link

mhartington commented Feb 21, 2020

Hello 👋 . I was asked to chime in here since I have experience with safe-insets while adding them to Ionic.

After reading over things, I think the safe-area insets take a care of a lot this. For example, given some markup:

<header-cmp>
  <title-cmp>My App</title-cmp>
</header-cmp>

<content-cmp></content-cmp>

We'd want "My App" to be below the safe-area, but still allow the header (and potential background color) to take up the full space

 ╭──╮      ╭──╮
 │  ╰──────╯  │
 │My App      │
 │┈┈┈┈┈┈┈┈┈┈┈┈│
 │            │
 │            │
 │            │
 │            │
 │            │
 │            │
 │            │
 │            │
 ╰────────────╯

In ionic, we do this by applying padding to the title component and letting the header get cut off by the notch.

If the device is rotated and the notch is on the start/end side this can still be handle by safe-insets as just adjust automatically.

So far, the safe inset variables work well for us at Ionic, so I'm not sure there is any benefit of adding additional variables that could handle the same thing.

As far as the new units, this can be very useful if there's enough by in from other vendors as well. If not new units, maybe env variables?

header-cpm {
  /* This could be 44px on iOS, 56px on chrome/edge on android, etc etc */
  height: env(system-header-height);
}

Though this doesn't account for headers that could have mult-line sections.

Just some comments from a random dev 🙂

@amandabaker
Copy link
Member Author

@mhartington In your screenshot, are the time and status icons are provided by the OS and you're just placing the background color behind those icons?

If they are drawn by the OS, then that's not quite analogous to the problem that we're trying to solve: placing web content next to a resizable "notch" that is anchored in the top left or right corner. However, it could signal that it's not worth trying to sell this as a "notch" problem, and that maybe we should just propose unique CSS env()'s for this scenario: e.g. env(title-bar-start/end) used in conjunction with env(safe-area-inset-top) to layout the custom title bar area.

If you can control their placement, how do you ensure that they don't flow behind the notch?

amandabaker added a commit that referenced this issue Mar 3, 2020
…le bar (#212)

Update explainer to use and explain new CSS environment variables: `unsafe-area-top-inset-left/right`. 

CSS working group proposal: 
- [[css-env] Add environment variable for left/right bounds of notch](w3c/csswg-drafts#4721)

Related issues: 
- #177 Title bar customization: new CSS properties for easier layout
- #203 [Title Bar Customization] Consider using css env variables for `controlsOverlay` bounding rect
@amandabaker
Copy link
Member Author

Added CSS environment variables in #212

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

No branches or pull requests

5 participants