Use a área da barra de título ao lado dos controles da janela para deixar o PWA mais parecido com um app.
Talvez você se lembre do meu artigo Fazer seu PWA parecer mais um app. como eu mencionei personalizar a barra de título do seu app como estratégia para criar uma experiência mais parecida com a de um app. Aqui está um exemplo de como isso pode ficar mostrando o app macOS Podcasts.
Agora, você pode ficar tentado a objetá-lo, dizendo que Podcasts é um app macOS específico da plataforma que não são executados em um navegador e, portanto, podem fazer o que quiserem sem ter que acessar regras de firewall. Verdadeiro, mas a boa notícia é que o recurso "Sobreposição dos controles da janela", que é o tópico do Neste artigo, em breve você poderá criar interfaces do usuário semelhantes para seu PWA.
Componentes de sobreposição de controles da janela
A sobreposição de controles de janela consiste em quatro sub-recursos:
- O valor
"window-controls-overlay"
para o campo"display_override"
em o manifesto do app da Web. - As variáveis de ambiente CSS
titlebar-area-x
,titlebar-area-y
,titlebar-area-width
etitlebar-area-height
. - A padronização da propriedade CSS anterior
-webkit-app-region
como oapp-region
para definir regiões arrastáveis no conteúdo da Web. - Um mecanismo para consultar e contornar a região de controles da janela usando o
windowControlsOverlay
participante dewindow.navigator
.
O que é a sobreposição de controles da janela
A área da barra de título refere-se ao espaço à esquerda ou à direita dos controles da janela (ou seja, o para minimizar, maximizar, fechar etc.) e muitas vezes contém o título do aplicativo. Janela A sobreposição de controles permite que os Progressive Web Apps (PWAs) ofereçam uma aparência mais semelhante a apps ao trocar barra de título existente de largura total para uma pequena sobreposição contendo os controles da janela. Isso permite desenvolvedores colocarem conteúdo personalizado onde antes era a área da barra de título controlada pelo navegador.
Status atual
Etapa | Status |
---|---|
1. Criar explicação | Concluído |
2. Criar um rascunho inicial da especificação | Concluído |
3. Colete feedback e iterar no design | Em andamento |
4. Teste de origem | Concluído |
5. Lançamento | Concluído (no Chromium 104) |
Como usar a sobreposição de controles da janela
Como adicionar window-controls-overlay
ao manifesto do app da Web
Um App Web Progressivo pode ativar a sobreposição de controles da janela adicionando
"window-controls-overlay"
como o membro "display_override"
principal no manifesto do app da Web:
{
"display_override": ["window-controls-overlay"]
}
A sobreposição de controles da janela só ficará visível quando todas estas condições forem satisfeitas:
- O app não é aberto no navegador, mas em uma janela separada do PWA.
- O manifesto inclui
"display_override": ["window-controls-overlay"]
. (Outros valores são permitido depois disso. - O PWA está sendo executado em um sistema operacional de computador.
- A origem atual corresponde àquela em que o PWA foi instalado.
O resultado disso é uma área vazia da barra de título com os controles de janela normais à esquerda ou o dependendo do sistema operacional.
Mover conteúdo para a barra de título
Agora que há espaço na barra de título, você pode mover algo para lá. Para este artigo, eu criou um PWA de conteúdo em destaque da Wikimedia. Um recurso útil para esse aplicativo pode ser uma pesquisa por palavras em os títulos dos artigos. O HTML do recurso de pesquisa é assim:
<div class="search">
<img src="logo.svg" alt="Wikimedia logo." width="32" height="32" />
<label>
<input type="search" />
Search for words in articles
</label>
</div>
Para mover este div
para a barra de título, é necessário um pouco de CSS:
.search {
/* Make sure the `div` stays there, even when scrolling. */
position: fixed;
/**
* Gradient, because why not. Endless opportunities.
* The gradient ends in `#36c`, which happens to be the app's
* `<meta name="theme-color" content="#36c">`.
*/
background-image: linear-gradient(90deg, #36c, #131313, 33%, #36c);
/* Use the environment variable for the left anchoring with a fallback. */
left: env(titlebar-area-x, 0);
/* Use the environment variable for the top anchoring with a fallback. */
top: env(titlebar-area-y, 0);
/* Use the environment variable for setting the width with a fallback. */
width: env(titlebar-area-width, 100%);
/* Use the environment variable for setting the height with a fallback. */
height: env(titlebar-area-height, 33px);
}
Confira o efeito desse código na captura de tela abaixo. A barra de título é totalmente responsiva. Quando você redimensiona a janela do PWA, a barra de título reage como se fosse composta de conteúdo HTML normal; o que, na verdade, é.
Determinar quais partes da barra de título são arrastáveis
A captura de tela acima sugere que você já terminou, mas o trabalho ainda não terminou. A janela do PWA
não podem mais ser arrastados (exceto por uma área muito pequena), já que os botões de controle da janela não são arrastados
e o restante da barra de título consiste no widget de pesquisa. Corrija isso usando
a propriedade CSS app-region
com um valor de drag
. No caso concreto, é melhor fazer
tudo além do elemento input
arrastável.
/* The entire search `div` is draggable… */
.search {
-webkit-app-region: drag;
app-region: drag;
}
/* …except for the `input`. */
input {
-webkit-app-region: no-drag;
app-region: no-drag;
}
Com esse CSS, o usuário pode arrastar a janela do app como de costume arrastando div
, img
,
ou a label
. Somente o elemento input
é interativo. Portanto, a consulta de pesquisa pode ser inserida.
Detecção de recursos
O suporte à sobreposição dos controles da janela pode ser detectado testando a existência de um
windowControlsOverlay
:
if ('windowControlsOverlay' in navigator) {
// Window Controls Overlay is supported.
}
Consultar a região de controles da janela com windowControlsOverlay
O código até agora tem um problema: em algumas plataformas, os controles da janela ficam à direita, na
outros que estão à esquerda. Para piorar, os "três pontos" O menu do Google Chrome mudará
posição, com base na plataforma. Isso significa que a imagem de plano de fundo em gradiente linear precisa
ser adaptada dinamicamente para execução em #131313
→maroon
ou maroon
→#131313
→maroon
, de forma que
se mistura com a cor de fundo maroon
da barra de título, que é determinada pela
<meta name="theme-color" content="maroon">
Para isso, basta consultar
API getTitlebarAreaRect()
na propriedade navigator.windowControlsOverlay
.
if ('windowControlsOverlay' in navigator) {
const { x } = navigator.windowControlsOverlay.getTitlebarAreaRect();
// Window controls are on the right (like on Windows).
// Chrome menu is left of the window controls.
// [ windowControlsOverlay___________________ […] [_] [■] [X] ]
if (x === 0) {
div.classList.add('search-controls-right');
}
// Window controls are on the left (like on macOS).
// Chrome menu is right of the window controls overlay.
// [ [X] [_] [■] ___________________windowControlsOverlay [⋮] ]
else {
div.classList.add('search-controls-left');
}
} else {
// When running in a non-supporting browser tab.
div.classList.add('search-controls-right');
}
Em vez de colocar a imagem de plano de fundo nas regras CSS da classe .search
diretamente (como antes), a classe
o código modificado agora usa duas classes que o código acima define dinamicamente.
/* For macOS: */
.search-controls-left {
background-image: linear-gradient(90deg, #36c, 45%, #131313, 90%, #36c);
}
/* For Windows: */
.search-controls-right {
background-image: linear-gradient(90deg, #36c, #131313, 33%, #36c);
}
Determinar se a sobreposição de controles da janela está visível
A sobreposição de controles da janela não ficará visível na área da barra de título em todas as circunstâncias. Embora
naturalmente não estará presente em navegadores que não oferecem suporte ao recurso "Sobreposição dos controles da janela",
também não estarão disponíveis quando o PWA em questão for executado em uma guia. Para detectar essa situação, você pode
consulte a propriedade visible
do windowControlsOverlay
:
if (navigator.windowControlsOverlay.visible) {
// The window controls overlay is visible in the title bar area.
}
Como alternativa, também é possível usar a consulta de mídia display-mode
em JavaScript e/ou CSS:
// Create the query list.
const mediaQueryList = window.matchMedia('(display-mode: window-controls-overlay)');
// Define a callback function for the event listener.
function handleDisplayModeChange(mql) {
// React on display mode changes.
}
// Run the display mode change handler once.
handleDisplayChange(mediaQueryList);
// Add the callback function as a listener to the query list.
mediaQueryList.addEventListener('change', handleDisplayModeChange);
@media (display-mode: window-controls-overlay) {
/* React on display mode changes. */
}
Como ser notificado sobre alterações na geometria
Consultar a área de sobreposição de controles da janela com getTitlebarAreaRect()
pode ser suficiente para uma única ocorrência.
como definir a imagem de plano de fundo correta com base em onde estão os controles da janela, mas em
em outros casos, é necessário um controle mais refinado. Por exemplo, um possível caso de uso poderia ser
adaptar a sobreposição de controles da janela com base no espaço disponível e adicionar uma piada diretamente na janela
da sobreposição de controles quando há espaço suficiente.
Para receber notificações sobre alterações na geometria, inscreva-se em
navigator.windowControlsOverlay.ongeometrychange
ou configurando um listener de eventos para o
geometrychange
. Este evento só será disparado quando a sobreposição de controles da janela estiver visível, que
é, quando navigator.windowControlsOverlay.visible
é true
.
const debounce = (func, wait) => {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};
if ('windowControlsOverlay' in navigator) {
navigator.windowControlsOverlay.ongeometrychange = debounce((e) => {
span.hidden = e.titlebarAreaRect.width < 800;
}, 250);
}
Em vez de atribuir uma função a ongeometrychange
, você também pode adicionar um listener de eventos ao
windowControlsOverlay
, conforme mostrado abaixo. Você pode ler sobre a diferença entre os dois
MDN.
navigator.windowControlsOverlay.addEventListener(
'geometrychange',
debounce((e) => {
span.hidden = e.titlebarAreaRect.width < 800;
}, 250),
);
Compatibilidade para execução em uma guia e em navegadores incompatíveis
Há dois casos possíveis a serem considerados:
- O caso em que um app é executado em um navegador compatível com a sobreposição de controles da janela, mas em que o app é usado em uma guia do navegador.
- O caso em que um app é executado em um navegador sem suporte à sobreposição de controles da janela.
Em ambos os casos, por padrão, o HTML criado para os controles de janela
será exibida inline como o conteúdo HTML normal e as variáveis env()
valores substitutos
vai começar para a posição. Em navegadores compatíveis, você também pode optar por não exibir o
O HTML designado para a sobreposição de controles da janela verificando a propriedade visible
da sobreposição e, se
ele reporta false
e, em seguida, oculta esse conteúdo HTML.
Como lembrete, os navegadores não compatíveis não considerarão a
"display_override"
propriedade do manifesto do app da Web ou não reconhece o
"window-controls-overlay"
e, portanto, usa o próximo valor possível de acordo com a cadeia de substituto.
por exemplo, "standalone"
.
Considerações sobre a interface
Embora possa ser tentador, não é recomendável criar um menu suspenso clássico na área "Sobreposição de controles da janela". Isso violaria diretrizes de design no macOS, uma plataforma em que os usuários esperam barras de menu (tanto as do sistema quanto as personalizadas) na parte superior da tela.
Caso seu app ofereça uma experiência em tela cheia, considere se faz sentido
para que a sobreposição de controles da janela faça parte da visualização em tela cheia. Possivelmente,
quiser reorganizar seu layout quando
onfullscreenchange
é acionado.
Demonstração
Criei uma demonstração para você testar diferentes navegadores compatíveis e não compatíveis e nos estados instalado e não instalado. Para para acessar a experiência real da sobreposição de controles da janela, instale o app. Veja abaixo duas capturas de tela do que esperar. A código-fonte do app está disponível no Glitch.
O recurso de pesquisa na sobreposição de controles da janela está totalmente funcional:
Considerações sobre segurança
A equipe do Chromium projetou e implementou a API Window Controls Overlay usando os princípios básicos definido em Como controlar o acesso a recursos avançados da Web Platform, incluindo controle, transparência e ergonomia.
Spoofing
Dar aos sites controle parcial da barra de título permite que os desenvolvedores façam spoofing de conteúdo antes era uma região confiável, controlada pelo navegador. No momento, nos navegadores Chromium, autônomo inclui uma barra de título que, na inicialização inicial, exibe o título da página da Web à esquerda, e a origem da página à direita (seguida pelo botão "configurações e mais" e pela janela . Após alguns segundos, o texto de origem desaparecerá. Se o navegador estiver definido como da direita para a esquerda (RTL), esse layout é invertido para que o texto de origem fique à esquerda. Isso abre Os controles de janela se sobrepõem para falsificar a origem se não houver padding insuficiente entre as origens e a borda direita da sobreposição. Por exemplo, a origem "evil.ltd" poderia ser anexado com uma string site "google.com.br", levando os usuários a acreditar que a fonte é confiável. O plano é manter isso texto de origem para que os usuários saibam qual é a origem do aplicativo e possam garantir que ele corresponda ao as expectativas da equipe. Para navegadores configurados com RTL, deve haver padding suficiente à direita da origem para evitar que um site malicioso anexe a origem não segura a uma origem confiável.
Impressão digital
Ativar a sobreposição de controles da janela e as regiões arrastáveis não se posam
questões de privacidade consideráveis além da detecção de recursos. No entanto, devido aos
tamanhos e posições diferentes dos botões de controle da janela em todos os
sistemas, os
navigator.
retorna um DOMRect
com posição e dimensões que revelam informações sobre o sistema operacional
em que o navegador está sendo executado. Atualmente, os desenvolvedores já podem descobrir o SO
da string do user agent, mas, devido a questões de técnicas de impressão digital,
discussão sobre como congelar a string do UA e unificar as versões do SO. Há um
esforço contínuo dentro da comunidade de navegadores para compreender com que frequência o
o tamanho da janela de controles de sobreposição muda entre as plataformas, já que o tamanho
é que eles são bastante estáveis em todas as versões do SO e, portanto,
útil para observar versões secundárias do sistema operacional. Embora isso seja uma possível
de impressão digital, isso só se aplica a PWAs instalados que usam o
recurso da barra de título e não se aplica ao uso geral do navegador. Além disso, o
A API navigator.
não vai estar disponível para
em iframes incorporados em um PWA.
Navegação
Navegar para uma origem diferente em um PWA faz com que ele retorne ao estado autônomo normal mesmo que atenda aos critérios acima e seja iniciado com a sobreposição de controles da janela. Isso serve para acomodar a barra preta que aparece na navegação para uma origem diferente. Depois voltar à origem original, a sobreposição de controles da janela será usada novamente.
Feedback
A equipe do Chromium quer saber mais sobre suas experiências com a API Window Controls Overlay.
Fale sobre o design da API
Alguma coisa na API não funciona como você esperava? Ou há métodos faltando ou propriedades de que precisa para implementar sua ideia? Tem uma pergunta ou comentário sobre a segurança modelo? Registre um problema de especificação no repositório do GitHub correspondente ou adicione sua opinião a uma problema.
Informar um problema com a implementação
Você encontrou um bug na implementação do Chromium? Ou a implementação é diferente das especificações?
Registre um bug em new.crbug.com. Não deixe de incluir
o máximo de detalhes possível,
instruções simples para reprodução e insira UI>Browser>WebAppInstalls
no bloco Components
caixa O Glitch é ótimo para compartilhar repetições rápidas e fáceis.
Mostrar suporte à API
Você planeja usar a API Window Controls Overlay? Seu apoio público ajuda a equipe do Chromium para priorizar recursos e mostrar a outros fornecedores de navegadores como é essencial oferecer suporte a eles.
Envie um tweet para @ChromiumDev com a
#WindowControlsOverlay
e diga onde e como você a está usando.
Links úteis
- Explicação
- Rascunho de especificações
- Bug do Chromium
- Entrada de status da plataforma Chrome
- Avaliação da TAG
- Documentos relacionados do Microsoft Edge
Agradecimentos
A sobreposição de controles da janela foi implementada e especificada por Amanda Baker, da equipe do Microsoft Edge. Este artigo foi revisado por Joe Medley e Kenneth Rohde Christiansen (link em inglês). Imagem principal de Sigmund no Unsplash.