Como criar um componente de histórias

Uma visão geral básica sobre como criar uma experiência semelhante aos Stories do Instagram na Web.

Nesta postagem, quero compartilhar ideias sobre como criar um componente Histórias para a Web que é responsiva, oferece suporte à navegação pelo teclado e funciona em navegadores da Web.

Demonstração

Se preferir uma demonstração prática de como criar esse componente de Histórias, confira o codelab sobre o componente Histórias.

Se você preferir o vídeo, aqui está uma versão do YouTube desta postagem:

Visão geral

Dois exemplos famosos de UX de Stories são o Snapchat e o Instagram Stories, sem falar das frotas. Em termos gerais de UX, as Stories geralmente são um padrão de navegação centrado em toques apenas para dispositivos móveis várias assinaturas. Por exemplo, no Instagram, os usuários abrem a história de um amigo e analisar as imagens nele. Eles geralmente fazem isso com muitos amigos em uma tempo de resposta. Ao tocar no lado direito do dispositivo, o usuário vai para a tela do amigo para a próxima matéria. Ao deslizar para a direita, o usuário avança para outro amigo. Um componente de história é bastante semelhante a um carrossel, mas permite navegar por um uma matriz multidimensional, e não unidimensional. É como se tivesse um carrossel dentro cada carrossel. 🤯

Visualização de uma matriz multidimensional usando cartões. Da esquerda para a direita, há uma pilha de cartões com bordas roxas e, dentro de cada um, há várias cartas com bordas ciano. Lista em uma lista.
1o carrossel de amigos
2o "empilhado" carrossel de histórias
👍 Lista em uma lista, também conhecida como: uma matriz multidimensional

Escolher as ferramentas certas para o trabalho

No geral, achei esse componente bem simples de criar, graças a alguns recursos essenciais da plataforma da Web. Vamos explicar cada uma delas.

Grade CSS

Nosso layout não era complicado para o CSS Grid, porque ele é equipado com alguns maneiras poderosas de organizar conteúdo.

Layout de amigos

Nosso wrapper principal do componente .stories é uma visualização de rolagem horizontal que prioriza dispositivos móveis:

.stories {
  inline-size: 100vw;
  block-size: 100vh;

  display: grid;
  grid: 1fr / auto-flow 100%;
  gap: 1ch;

  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior: contain;
  touch-action: pan-x;
}

/* desktop constraint */
@media (hover: hover) and (min-width: 480px) {
  max-inline-size: 480px;
  max-block-size: 848px;
}
Como usar o Chrome DevTools Modo dispositivo para destacar as colunas criadas pela Grade

Vamos detalhar esse layout de grid:

  • Preenchimento explícito da janela de visualização em dispositivos móveis com 100vh e 100vw e restringimos o tamanho em computadores.
  • / separa nossos modelos de linha e coluna
  • auto-flow é traduzido para grid-auto-flow: column
  • O modelo de fluxo automático é 100%, que nesse caso é a largura da janela de rolagem
.

Em um celular, pense nisso como o tamanho da linha sendo a altura da janela de visualização e sendo cada coluna a largura da janela de visualização. Continuando com as Histórias do Snapchat exemplo do Instagram Stories, cada coluna será a história de um amigo. Queremos amigos histórias continuem fora da janela de visualização para que tenhamos algum lugar para rolar. A grade fará quantas colunas forem necessárias para definir o layout do seu HTML para cada amigo história, criando um contêiner de rolagem dinâmico e responsivo para nós. Grade nos permitiu centralizar todo o efeito.

Empilhamento

Precisamos das histórias de cada amigo em um estado pronto para paginação. Para me preparar para a animação e outros desenhos divertidos, escolhi uma pilha. Quando digo pilha, quer dizer que você está olhando para baixo sanduíche, não como se você estivesse olhando de lado.

Com a grade CSS, podemos definir uma grade de célula única (por exemplo, um quadrado), em que as linhas e as colunas compartilham um alias ([story]). Em seguida, cada filho é atribuído a esse espaço de célula única com alias:

.user {
  display: grid;
  grid: [story] 1fr / [story] 1fr;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
.story {
  grid-area: story;
  background-size: cover;
  
}

Isso coloca nosso HTML no controle da ordem de empilhamento e também mantém todos os elementos em fluxo. Observe como não precisamos fazer nada com o posicionamento de absolute ou z-index e não precisávamos corrigir o erro height: 100% ou width: 100%. A grade mãe já definiu o tamanho da janela de visualização de imagens da história, então nenhum desses componentes de história precisavam ser instruídos a preenchê-lo!

Pontos de ajuste de rolagem do CSS

As especificações de pontos de ajuste de rolagem do CSS um clique para fixar os elementos na janela de visualização ao rolar. Antes da existência dessas propriedades CSS, você tinha que usar JavaScript e era... complicado, para dizer o menos. Finalizar compra Conheça os pontos de ajuste de rolagem do CSS por Sarah Drasner para um ótimo detalhamento de como usá-los.

Rolagem horizontal sem e com estilos scroll-snap-points. Sem ela, os usuários podem rolar a tela normalmente. Com ele, o navegador apoia gentilmente cada item.
primária
.stories {
  display: grid;
  grid: 1fr / auto-flow 100%;
  gap: 1ch;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior: contain;
  touch-action: pan-x;
}
Pai com rolagem esticada define o comportamento de ajuste.
criança
.user {
  display: grid;
  grid: [story] 1fr / [story] 1fr;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
As crianças optam por ser um alvo instantâneo.

Escolhi pontos de ajuste de rolagem por alguns motivos:

  • Acessibilidade sem custo financeiro. A especificação dos pontos de ajuste de rolagem indica que pressionar o botão As teclas de seta para a esquerda e seta para a direita se movem pelos pontos de ajuste por padrão.
  • Uma especificação em crescimento. A especificação dos pontos de ajuste de rolagem está recebendo novos recursos e melhorias o tempo todo, o que significa que meu componente Histórias provavelmente só vai melhorar que está por vir.
  • Facilidade de implementação. Os Snap Points de rolagem são praticamente criados para caso de uso de paginação horizontal com foco em toque.
  • Inércia livre no estilo de plataforma. Cada plataforma vai rolar a tela e descansar com o estilo dela, inércia normalizada, que pode ter um estilo incomum de rolagem e de repouso.

Compatibilidade com vários navegadores

Testamos no Opera, Firefox, Safari e Chrome, além de Android e iOS. Aqui está um breve resumo dos recursos da Web onde encontramos diferenças em recursos e suporte.

No entanto, alguns CSS não se aplicam, então algumas plataformas estão perdendo UX e otimizações. Gostei de não precisar gerenciar esses recursos e me senti confiante que, em algum momento, elas cheguem a outros navegadores e plataformas.

scroll-snap-stop

Os carrosséis foram um dos principais casos de uso de UX que incentivaram a criação do Especificação de pontos de ajuste de rolagem do CSS. Ao contrário das Histórias, um carrossel nem sempre precisa parar em cada imagem após a interação do usuário. Pode ser bom ou encorajado rapidamente pelo carrossel. As histórias, por outro lado, são mais bem navegadas uma a uma, e é exatamente isso que o scroll-snap-stop oferece.

.user {
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

No momento em que este artigo foi escrito, o scroll-snap-stop só podia ser usado com apps baseados no Chromium navegadores da Web. Finalizar compra Compatibilidade do navegador para atualizações. Mas não é um obstáculo. Significa apenas que, em navegadores não compatíveis, os usuários podem acidentalmente ignorar um amigo. Portanto, os usuários terão apenas que ter mais cuidado, ou precisamos escrever código JavaScript para garantir que um amigo ignorado não seja marcado como visualizado.

Leia mais na especificação se você estiver interesse.

overscroll-behavior

Você já esteve rolando por um modal quando, de repente, começar a rolar o conteúdo atrás do modal? overscroll-behavior permite que o desenvolvedor prenda essa rolagem e nunca deixe ir embora. É legal para todos os tipos de ocasião. Ele é utilizado pelo componente "Minhas histórias" para evitar que outros gestos de deslizar e de rolagem saiam da componente.

.stories {
  overflow-x: auto;
  overscroll-behavior: contain;
}

Safari e Opera foram os dois navegadores que não funcionaram oferecer suporte a isso, não tem problema. Esses usuários terão uma experiência de rolagem como a de costume. e talvez nunca note essa melhoria. Particularmente, sou um grande fã e gosto incluindo como parte de quase todos os recursos de rolagem que implemento. É um uma adição inofensiva que só pode melhorar a UX.

scrollIntoView({behavior: 'smooth'})

Quando um usuário toca ou clica e chega ao final do conjunto de histórias de um amigo, é hora de passar para o próximo amigo no conjunto de pontos de ajuste de rolagem. Com JavaScript, foi possível fazer referência ao próximo amigo e solicitar que ele fosse rolaram para visualizar. O suporte para os fundamentos disso é ótimo. todos os navegadores rolamos para vê-lo. No entanto, nem todos os navegadores fizeram isso 'smooth'. Isso significa apenas que ela é rolada para visualização em vez de encaixada.

element.scrollIntoView({
  behavior: 'smooth'
})

O Safari foi o único navegador que não oferece suporte ao behavior: 'smooth' aqui. Finalizar compra Compatibilidade do navegador para atualizações.

Na prática

Agora que você sabe como eu fiz isso, como faria?! Vamos diversificar e aprender todas as maneiras de criar na Web. Crie um Glitch, Envie um tweet para sua versão, e eu a adicionarei ao na seção Remixes da comunidade abaixo.

Remixes da comunidade