Skip to content
📂 Arrastar e largar no botão de carregar: uma funcionalidade oculta do navegador

📂 Arrastar e largar no botão de carregar: uma funcionalidade oculta do navegador

A maioria dos utilizadores não faz ideia: para enviar um ficheiro para um site, não precisa de apontar para o minúsculo botão «Choose File» e navegar pelo gestor de ficheiros. Um único gesto é suficiente: arraste o ficheiro do explorador de ficheiros diretamente para esse botão.

Isto não é um plugin nem o resultado de um script engenhoso. O <input type="file">, um elemento HTML padrão, suporta nativamente arrastar e largar ao nível do navegador. Sem JavaScript, sem bibliotecas, sem zonas de largada. O comportamento está descrito na especificação HTML e funciona pelo menos desde meados da década de 2010.

A equipa do blogue técnico testou este truque numa dúzia de sites. Funciona em todo o lado que utilize um <input type="file"> nativo: enviar plugins para a administração do WordPress, enviar digitalizações para o suporte técnico, anexar currículos em portais de RH. Sem erros, sem danças com o gestor de ficheiros.

💡 Resumo rápido:

  • Arraste um ficheiro do explorador de ficheiros para o botão «Choose File» em qualquer formulário; o navegador insere o ficheiro no input automaticamente.
  • Não é necessário código: o <input type="file"> nativo aceita ficheiros através de arrastar e largar por predefinição.
  • O suporte a múltiplos ficheiros funciona através do atributo multiple: selecione um grupo no explorador de ficheiros, arraste-os e todo o lote é enviado para o servidor numa única operação.
  • Os dispositivos móveis não suportam este truque: as interfaces táteis não implementam o arrastar entre aplicações.

Este pequeno vídeo demonstra como o <input type="file"> funciona e os princípios básicos do envio de ficheiros no navegador. Compreender estes fundamentos ajuda a perceber porque é que arrastar e largar no botão funciona sem código adicional.

Onde isto funciona

A funcionalidade funciona em computadores desktop em todos os navegadores modernos. Testámos no Chrome, Firefox, Safari (macOS), Vivaldi e Edge baseado no Chromium; o ficheiro é aceite corretamente em cada um deles. De acordo com os dados do Can I Use, o suporte cobre mais de 95% dos utilizadores de desktop há vários anos.

Se o campo tiver o atributo multiple, pode arrastar um grupo inteiro de ficheiros de uma só vez. O navegador adiciona-os todos à fila de envio e, após submeter o formulário, o servidor recebe um array de ficheiros da forma padrão. Na prática, isto acelera radicalmente os envios de media no WordPress: selecione uma dúzia de imagens no explorador de ficheiros, arraste-as para o botão «Choose Files» na biblioteca de media e todo o lote segue para o servidor. Sem selecionar uma a uma através de um diálogo.

Os dispositivos móveis não suportam este truque. As interfaces táteis não implementam o arrastar entre aplicações da forma que existe no desktop. Mas para os utilizadores de desktop, cada envio poupa 5 a 10 segundos e elimina a carga cognitiva de navegar por árvores de pastas.

Advertência importante: o truque só funciona com o <input type="file"> nativo. Se um site usar um elemento personalizado, um <div> ou <button> estilizado que abre programaticamente o diálogo de ficheiro, o arrastar não funcionará. Da mesma forma, se o JavaScript do site intercetar os eventos dragover e drop ao nível do documento e chamar e.preventDefault(), o comportamento nativo do navegador é bloqueado.

Porque é que ninguém fala sobre isto

O paradoxo: a funcionalidade está nos navegadores há pelo menos uma década, mas o utilizador comum não sabe dela. Os programadores muitas vezes também não sabem: o hábito de recorrer imediatamente a bibliotecas de arrastar e largar sobrepõe-se à vontade de verificar o comportamento nativo.

Daí as toneladas de tutoriais sobre zonas de largada personalizadas. O mesmo artigo no CSS-Tricks detalha uma implementação em JavaScript com manipuladores de dragover e drop, lendo ficheiros através do FileReader. Entretanto, a capacidade básica do navegador acumula pó nas sombras.

Porque é que os programadores ainda escrevem as suas próprias zonas de largada:

  • Feedback visual. O envio nativo não destaca o botão quando se paira um ficheiro sobre ele, e o utilizador não percebe que o arrastar vai funcionar. Uma zona de largada personalizada fornece um contorno estilizado, mudança de fundo, animação.

  • Pré-visualização e validação. Uma implementação em JavaScript mostra uma miniatura da imagem antes do envio, verifica o tamanho e o tipo de ficheiro no cliente, exibe uma barra de progresso.

  • Múltiplas zonas. Quando uma página tem vários pontos de envio independentes, por exemplo, uma foto de perfil e uma galeria numa conta pessoal, é necessária uma associação clara do ficheiro a um campo específico.

O suporte nativo não elimina estes cenários. Mas em formulários simples, enviar um documento para o suporte técnico, enviar um currículo, instalar um plugin na administração do WordPress, o código personalizado simplesmente não é necessário. O navegador já sabe fazer tudo.

Como adicionar feedback visual com um par de linhas

Se precisar de manter o comportamento nativo, mas dar ao utilizador uma dica visual, um mínimo de CSS e JavaScript é suficiente. O código abaixo destaca o botão de seleção de ficheiro ao pairar um ficheiro arrastado, sem tocar no mecanismo de envio em si.

Crie um invólucro à volta do <input type="file"> na marcação:

1<div class="file-upload-wrapper">
2 <input type="file">
3</div>

O script é pendurado no documento inteiro, não num input específico, porque o evento dragover é disparado ao entrar na janela do navegador. Quando o arrastar é detetado, a classe drag-over é adicionada ao invólucro:

1const fileInput = document.querySelector('input[type="file"]');
2const wrapper = fileInput.closest('.file-upload-wrapper');
3
4document.addEventListener('dragover', (e) => {
5 e.preventDefault();
6 wrapper?.classList.add('drag-over');
7});
8
9document.addEventListener('dragleave', (e) => {
10 if (!e.relatedTarget || e.relatedTarget === document.documentElement) {
11 wrapper?.classList.remove('drag-over');
12 }
13});
14
15document.addEventListener('drop', (e) => {
16 e.preventDefault();
17 wrapper?.classList.remove('drag-over');
18});

A classe drag-over é estilizada com uma linha de CSS. Abaixo, um contorno azul tracejado e um preenchimento de fundo claro, a sinalizar «largue aqui»:

1.file-upload-wrapper.drag-over input[type="file"] {
2 outline: 2px dashed #2563eb;
3 background: rgba(37, 99, 235, 0.05);
4}

O ficheiro continua a cair no input de forma nativa. O JavaScript não toca no mecanismo de envio, apenas adiciona feedback visual. Sem FileReader, sem FormData construído manualmente.

Se precisar de mais, validar tipo e tamanho antes da submissão, pré-visualização de imagem, barra de progresso, então faz sentido olhar para uma zona de largada personalizada completa. Felizmente, a MDN e o web.dev documentaram este processo do início ao fim.

⁉️🤔 Perguntas frequentes

Isto funciona no WordPress?

Sim, o carregador padrão do WordPress (plugins, temas, biblioteca de media) é construído sobre o <input type="file"> nativo. O arrastar funciona diretamente na administração sem plugins adicionais. A única nuance: a biblioteca de media no modo de grelha usa uma zona de largada personalizada sobre o campo nativo, pelo que o feedback visual é mais rico, mas o mecanismo básico é o mesmo. Verificado nas versões do WordPress da 5.0 à 6.7.

Que formatos de ficheiro são suportados?

O navegador não impõe restrições de formato ao arrastar: o ficheiro é passado para o input tal como está. Se o campo tiver um atributo accept (por exemplo, accept="image/*,.pdf"), a filtragem será aplicada ao nível do input exatamente como ao escolher através do diálogo de ficheiro. Os ficheiros de tipos não suportados serão ocultados da fila.

Arrastar é seguro?

Absolutamente. Arrastar um ficheiro para o <input type="file"> não dá ao site acesso ao sistema de ficheiros do utilizador. O navegador apenas passa o ficheiro em si (ou um array de ficheiros com multiple), mas não o seu caminho no disco. O modelo de segurança é o mesmo do envio através do diálogo de seleção padrão: o site não sabe de que pasta o ficheiro veio e não pode ler outros ficheiros próximos.

Porque é que o arrastar não funciona em alguns sites?

Duas razões. Primeira: o site não usa um <input type="file"> nativo, mas sim um elemento personalizado, um <div> ou <button> estilizado que abre programaticamente o diálogo de ficheiro. Os eventos nativos de arrastar e largar não estão vinculados a esse elemento. Segunda: o JavaScript do site interceta os eventos dragover e drop ao nível do documento e chama e.preventDefault(), bloqueando o comportamento padrão do navegador. Normalmente, os programadores capturam estes eventos para a sua própria zona de largada e não esperam que isso quebre o envio nativo.

Posso arrastar um ficheiro de um navegador para outro?

Não. O mecanismo só funciona do gestor de ficheiros do sistema operativo para a janela do navegador. Arrastar entre separadores ou de um navegador para outro não é suportado: o modelo de segurança do navegador não permite o acesso ao sistema de ficheiros de outro contexto.

O que usar: zona de largada ou botão nativo

O truque de arrastar para o botão de seleção de ficheiro poupa tempo e reduz a fricção. Não é preciso pegar no rato, apontar ao botão «Browse», navegar pela árvore de pastas. Um gesto, e o ficheiro já está no formulário.

Para cenários simples, enviar documentos, digitalizações, arquivos, instalar plugins no WordPress, o comportamento nativo com um ligeiro melhoramento visual é mais do que suficiente. Antes de carregar kilobytes de JavaScript para uma zona de largada personalizada, verifique: talvez o seu formulário já tenha o suficiente do que o navegador já sabe fazer.

Se administra sites WordPress, na sua próxima atualização experimente arrastar um plugin ou tema diretamente para o botão de envio. Provavelmente ficará surpreendido com o quão mais simples é do que navegar pelo gestor de ficheiros.