A UI dos elementos não são tão elementares
A tabela periódica de Dmitri Mendeleev parece simples, mas não parece que os elementos sejam, de facto, significativamente diferentes uns dos outros. Quando você se aprofunda e entende que apenas uma propriedade “aparentemente insignificante” do número de elétrons e prótons faz uma grande diferença na maneira como cada elemento age e reage na proximidade de outros – você tem uma ideia de como uma lista de aparência inofensiva pode esconder toda a complexidade relevante.
Os elementos interativos – os blocos de construção de sites e aplicativos – têm a mesma propriedade ilusória. Se você olhar qualquer um dos sites , repositórios, postagens em mídias sociais e blogs da ‘lista de verificação’, poderá ter a impressão de que tudo não passa de arranjos de frames, ícones e texto. Isso perderia a maior parte da complexidade.
Neste post (parte 1) vou mostrar alguns exemplos da divergência entre como o código e as ferramentas de design visual tratam os elementos e componentes interativos em geral.
Curiosamente, a raiz do problema muitas vezes permanece oculta tanto para os designers quanto para os desenvolvedores e só se torna aparente quando você tenta comparar e comunicar sobre ele. Esta postagem é um exemplo desse esforço.
Simples, mas com peculiaridades
Como exemplo, vejamos três elementos super simples — uma caixa de seleção, um botão de opção e uma chave seletora:
Como a versão web de todos esses elementos foi criada no início da própria web, há mais de 30 anos, havia muitos padrões que foram decididos para uso geral, então até hoje, se você quiser estilizar uma caixa de seleção ou um botão de opção de ponta a ponta de uma forma personalizada que difere muito dos padrões do navegador, você teria que fazer algumas coisas surpreendentes:
- Você teria que usar um contêiner (geralmente um <label> para abrigar tudo o que você deseja ativar)
- Para ocultar a aparência padrão real do [input-type =radio] dos usuários, você pode ser forçado a fazer uma de duas coisas: reduzir a opacidade e o tamanho para 0 quando precisar criar um novo div com conteúdo em vez do real entrada; ou em casos mais simples use ‘appearance: none’ (a propriedade de aparência controla o conjunto de estilo padrão dos navegadores em diferentes sistemas operacionais Chrome/Firefox, macOS/Windows irá afetá-lo) se você precisar apenas remodelar a entrada em si (pode ser suficiente para botões de opção, mas não caixas de seleção).
- Reestilize caso esteja usando ‘appearance:none’ ou recrie o design desejado com um div e um ícone personalizado.
Só então o seu design será da marca, personalizado e persistente em todos os dispositivos, navegadores e sistemas operacionais. Você teria que usar o próprio nó de entrada apenas para sua funcionalidade incorporada que os navegadores reconhecem automaticamente e permitem ao usuário interagir.
É ainda menos trivial usar botões de alternância, já que eles não existem como um elemento web independente. Usando praticamente as mesmas táticas de ocultação – toda vez que você alternava algo online, você pressionava uma [input-type=caixa de seleção] oculta dentro. Sim, todas as opções são, na verdade, caixas de seleção redesenhadas no que diz respeito ao navegador.
Os estados desses elementos básicos são específicos e são incorporados pela funcionalidade da própria web (marcado/desmarcado). Seus nomes são definidos e permanentes e não são variantes da mesma caixa de seleção, como seriam o tamanho e a cor.
Compare isso com a forma como um designer aborda esses 3 elementos em uma ferramenta de design baseada em vetores. O que é uma caixa de seleção visualmente? Uma moldura com um ícone. Os diferentes estados são apenas variantes, indistinguíveis de outras variantes visuais potenciais. Para adicionar rótulos e texto auxiliar, você provavelmente deseja agrupá-los em um quadro, use o layout automático em 2 estágios e pronto.
Um botão de opção é ainda mais fácil — você nem precisa de um ícone vetorial dentro, apenas da borda.
Uma alternância não possui caixa de seleção interna, apenas uma moldura de alternância e um botão. Você pode esquecer estados como foco e desativado, e a maioria dos designers esquece de incluir o estado ‘indeterminado’ ao projetá-los.
Há ainda mais complicações: para o código do produto real, você realmente teria que decidir o que é colocado dentro ou fora do contêiner <label>, pois isso afetará onde o ‘clique’ real afetará o estado da caixa de seleção/ radio/toggle para que o layout em si seja guiado pela funcionalidade, não pelo quão confortável é expressar algo usando o layout automático.
Em nosso exemplo aqui, é mais confortável colocar o rótulo e o texto auxiliar no mesmo quadro, mas em termos de funcionalidade você pode não querer que seu texto auxiliar também acione o estado da caixa de seleção, então você terá que reorganizar o layout para transformar o auxiliar em <label> e, portanto, não afetar a seleção.
Geralmente acontece que um designer estrutura o elemento conforme faz sentido em uma ferramenta de design visual e depois entrega os designs aos desenvolvedores. Os desenvolvedores provavelmente irão olhar para o resultado visual final, inspecionar as medições, baixar ativos relevantes, se necessário, olhar para a estrutura da camada, ver que não é útil para eles, desconsiderar e criar sua própria estrutura correta e tentar o seu melhor para torná-la visualmente idêntico.
Mais complexo – mais problemas!
Para personalizar o estilo de qualquer elemento que seja um pouco mais complexo, como um select, você teria que ocultar muitos mais nós HTML nativos para estilizar o seu próprio em vez deles, e você não pode se safar apenas com CSS, você teria empregar JS para fazê-lo funcionar. Você também precisa tomar cuidado com uma série de decisões de design de interação, como como a caixa de opções será posicionada sobre o próprio select, qual seria a condição quando ele virasse se não pudesse ser aberto para o lado padrão. menu suspenso de seleção múltipla ou única, como é classificado, como é a aparência do preenchimento automático, a caixa se concentra automaticamente em alguma condição, a caixa de opções tem altura máxima ou número de itens, etc.
E isso não sou só eu que estou dizendo; dê uma olhada nesta citação dos documentos da web MDN da Mozilla (que é provavelmente uma das fontes mais abrangentes e confiáveis que documentam tecnologias de plataforma Web e é de código aberto e colaborativo). Na seção ‘ estilo com css ‘ da página selecionada . [Ênfase minha]:
O
<select>
elemento é notoriamente difícil de estilizar de forma produtiva com CSS. Você pode afetar certos aspectos como qualquer elemento – por exemplo, manipular o modelo da caixa , a fonte exibida , etc., e pode usar aappearance
propriedade para remover o sistema padrãoappearance
. No entanto, essas propriedades não produzem um resultado consistente em todos os navegadores e é difícil fazer coisas como alinhar diferentes tipos de elementos de formulário entre si em uma coluna. A estrutura interna<select>
do elemento é complexa e difícil de controlar.
Compare isso com a forma como um designer geralmente trata as caixas de seleção nos sistemas de design das ferramentas de design? Apenas um quadro com um texto em algumas variantes para especificar estados (interativo, aberto, fechado) e variantes visuais (tamanho, estilo, importância talvez). Os designers irão compor a caixa de opções como um quadro simples de outro componente de ‘opção’ com vários estados – e pronto. Tudo bastante ‘o que você vê é o que você obtém’ aqui.
Como definimos um elemento, na verdade?
A taxonomia dos elementos da web não está completamente resolvida. Existem muitos componentes comuns que foram inventados muito depois do início da web, então eles não conseguiram ter um lugar muito bem definido na lista w3c de tags de elementos HTML .
Ao contrário dos elementos do tipo entrada, como entrada de texto, caixa de seleção, etc., pense em coisas mais complicadas, como um seletor de hora, componentes do seletor de data ou até mesmo um assistente ou carrossel. Definitivamente componentes, complexos, mas serão elementos? Se sim – por quê? Se não, com base em que? Quero dizer, é fácil traçar um limite arbitrariamente onde quisermos, mas a questão aqui é que não queremos que esse limite seja arbitrário, tanto quanto possível.
Para tentar traçar uma linha mais precisa nisso – talvez eu precise convocar Brad Frost para nos lembrar do design atômico :
Se os átomos são os blocos de construção básicos da matéria, então os átomos de nossas interfaces servem como os blocos de construção fundamentais que compõem todas as nossas interfaces de usuário . Esses átomos incluem elementos HTML básicos , como rótulos de formulários, entradas, botões e outros que não podem ser decompostos sem deixar de ser funcionais.
Observe a regra – “não pode ser mais subdividido sem deixar de ser funcional ” essa é a regra de Brad para ser suficientemente elementar. A questão que pode ser ilusória aqui é o que constitui uma função aqui?
Se pegarmos um seletor de data – posso facilmente dividi-lo em um monte de botões, um carrossel para alternar entre meses, então isso deveria desqualificá-lo de ser um elemento – mas a função de um seletor de data é registrar uma data, ou um intervalo de datas no sistema , e isso será interrompido se você começar a separar o componente do seletor de data. Então, se permitirmos tratar os elementos não como substantivos, mas como verbos, um elemento se torna – o mínimo necessário para executar aquele verbo, aquela função que o define.
Por esses motivos, um seletor de data é na verdade um elemento, e a compreensão alucinante é que um elemento pode conter outros elementos, se forem mais simples!
Além disso, ao examinar as próprias tags HTML, você verá que sempre foi assim. O que é uma tag <ul>? Lista não ordenada — um elemento. E o que sempre tem dentro dele? <li> — Lista itens. Outros elementos. Então, elementos dentro de elementos, desde o início da própria web.
Como óleo e água?
Todas essas diferenças são apenas um pequeno exemplo que ilustra por que, para começar, era basicamente um jogo fraudulento. Ferramentas de design desenvolvidas para otimizar a expressividade intuitiva , facilidade de manipulação ad-hoc, mesmo às custas do controle, modularidade robusta e regras vinculativas que imitam os padrões da web. HTML, CSS e, posteriormente, React e outras estruturas JS desenvolvidas para obter métodos eficazes – às vezes personalizados e às vezes genéricos – para expressar elementos e manipulá-los conforme necessário . Estas são propriedades completamente diferentes para otimizar, então não é de admirar que esses processos de evolução distintos tenham produzido maneiras muito diferentes de renderizar a estrutura de elementos interativos.
Quanto mais eu mergulho nisso, o simples fato de termos conseguido entregar projetos e construir algo digno com condições iniciais como essas – parece cada vez mais um pequeno milagre para mim!
A ‘dívida Delta’
Neste ponto, você pode pensar consigo mesmo – então qual é o problema – esse não é o trabalho dos desenvolvedores? Bem, é claro que é, mas é exatamente nesse momento que os componentes começam a divergir entre design e desenvolvimento. E isso é um grande problema em massa porque se você tiver mais de 30 componentes elementares e mais de 60 componentes complexos em seu sistema de design, e a maioria deles não estiver realmente sincronizada com o código no nível do que cada camada representa – quando você comece a implementar grandes mudanças, usando tokens e talvez decisões sobre acessibilidade (o que é clicado e aciona a interação, qual área de impacto, o que é focalizável e como etc.) uma dívida desagradável começa a crescer. Eu chamo isso de “dívida Delta”. Você sabe do que estou falando se você é um designer de produto com alguns anos de experiência.
Esse pequeno ‘deixar ir’ quando você faz seu controle de qualidade visual, as versões de teste/produção não mapeiam 1:1 com o design, e quando você pergunta aos desenvolvedores – você obtém um ‘é assim que os navegadores renderizam as coisas, não depende de mim, e fazer um patch personalizado é perigoso e vai prejudicar nossa velocidade, você não queria esse outro recurso?’ ou talvez algo mais intrigante como ‘o que você quer dizer com isso está exatamente de acordo com suas especificações, até o pixel, segui o Figma perfeitamente’.
Então você faz um movimento tático e desiste, prometendo a si mesmo que vai deixar isso passar; provavelmente é apenas você e seu olhar aguçado para detalhes de design que essa coisa está incomodando. Temos coisas mais importantes para fazer agora, e você saberá disso mais tarde, quando houver mais tempo. Infelizmente, nunca haverá mais tempo. Apenas mais componentes mal alinhados.
E assim essa ‘dívida Delta’ só cresce com o tempo, e como a morte por mil cortes – você aumenta seu próprio descontentamento com a aparência e o comportamento do produto real e prefere voltar para seus amados, imaculados e perfeitos arquivos de design, onde seus olhos estão protegidos dessa irritação. Às vezes, a inércia é tão forte que não há nada que se possa dizer que convença as partes interessadas de que esta dívida tem de ser paga. A única coisa que você promete a si mesmo é que, seja na reformulação da marca ou no próximo projeto, você será mais assertivo desde o início para garantir que o design e o produto estejam exatamente alinhados. Apenas para que o mesmo círculo se repita novamente.
Embora frequente, esse problema talvez possa ser evitado. E vejo dois caminhos que podem ajudar a preencher essa lacuna. Um — é fácil de explicar, mas difícil de fazer na prática; o outro — é mais difícil de explicar, mas pode resolver o problema como um subproduto.
Possíveis caminhos para a solução
1º caminho
Melhore a comunicação a um nível em que não haja problemas de silo, o designer e o desenvolvedor passam uma ‘batata quente’ de uma tarefa com muita frequência, até que ambos tenham um modelo mental muito semelhante de como o design deve ser, como se comportar, como deve ser construído. e talvez animar como. Este é provavelmente o conselho mais frequente que você vê as pessoas darem em entrevistas de podcast sobre seu sucesso (é claro), palestras bem-intencionadas e inspiradoras no palco e vários vídeos do Youtube. Infelizmente, o que é fácil de dizer é terrivelmente difícil de fazer . É preciso esforço e atrito para manter uma comunicação coesa, cujos frutos você nem sempre sente tão vividamente, e em um ambiente de trabalho sempre otimizado e medido — é a primeira coisa a sofrer. Especialmente à medida que as startups crescem e se expandem, passando de uma única sala para abranger continentes e fusos horários.
2º caminho
Construa ferramentas e processos para designers e desenvolvedores que tornarão muito mais difícil não estar na mesma página. Suponha que uma ferramenta de design seja feita de elementos reais, com uma estrutura já existente e verificada, apoiada por um código subjacente a tudo. Você vê principalmente construtores de web fazendo isso hoje, como Webflow e Framer. Quando você usa um elemento como uma caixa de seleção nesses aplicativos, é uma caixa de seleção real e funcional. Infelizmente, não há nenhum desenvolvedor para quem entregar tudo, porque os construtores atendem principalmente a equipes onde um designer pode lidar com todo o projeto de ponta a ponta, sem a necessidade de um desenvolvedor no circuito. Agora, imagine algo assim para design geral de produtos, aplicativos da web, aplicativos nativos, etc. produtos massivos que não podem ser resolvidos apenas por um designer talentoso, mas na verdade têm uma tonelada de lógica de negócios, gerenciamento de estado e back-end de dados para lidar. Produtos que exigem muitos desenvolvedores front-end e back-end. A maioria dos produtos para startups de SaaS são assim hoje.
Então, imagine que todas essas equipes usam um processo de design + código e um conjunto de ferramentas que, desde o início, os incentiva a usar elementos pré-existentes e estilizá-los como desejarem, e depois enviam o resultado para desenvolvedores front-end que não precisam. reconstrua tudo do zero, mas prefira conectar tudo com lógica extra não trivial (em seu próprio IDE amado) e usá-lo junto com os engenheiros de back-end.
Quando penso no melhor design de produto, é sempre melhor prevenir um problema do que tentar ajudar a lidar com as consequências do problema. Não seria nenhuma surpresa que eu preferisse o segundo caminho.
Resumo
É um problema difícil de resolver. E se você diminuir o zoom e observar a indústria de ferramentas e métodos de design de produto de cima, verá que, com o passar do tempo, há uma sede cada vez maior por parte dos designers de já preencher essa lacuna. É por isso que você vê uma infinidade de plug-ins para Figma e Sketch que ajudam a ‘traduzir’ (adivinhar) seus designs visualmente otimizados para alguma ou outra forma de código utilizável. É por isso que as ferramentas de design adotam cada vez mais recursos e mecânicas que se assemelham às capacidades do código (como variáveis que podem referenciar outras variáveis, API de componentes através do uso de propriedades e grupos de variantes, layout automático e posicionamento absoluto nele, truncamento em texto, condicional lógica, etc.).
Algumas pessoas acreditam que ainda se trata apenas de habilidades de comunicação, e as ferramentas em si não importam, algumas acreditam que a inteligência artificial incorporada nas ferramentas de design ajudará a espalhar um pouco de pó de fada neste problema e ajudará os designers a atravessar esse abismo, e alguns, como eu mesmo – acredito que é apenas uma questão de construir ferramentas melhores.
Enquanto isso, quanto mais sabemos sobre as diferentes peculiaridades de cada elemento em produtos reais e vivos, mais fácil se torna preencher essa lacuna.
Aqui está uma lista de lugares úteis onde você pode aprender e mergulhar nos detalhes dos diferentes elementos interativos e melhorar sua transferência:
Radix UI é um ótimo repositório de UI sem cabeça para usar e explorar
Claro que a lista mais completa e confiável de todos os elementos HTML, o site MDN
Repositório pequeno, mas útil, de componentes reais — Headless UI
‘Design atômico’ de Brad Frost e blog geral
E este é um artigo inspirador e informativo sobre como estruturar a comunicação tão bem que a transferência se torna quase isenta de riscos (no entanto, boa sorte em realmente implementar isso).