Substitua o tipo de entrada = arquivo por uma imagem

96

Como muita gente, gostaria de customizar o feio input type=file, e sei que não pode ser feito sem alguns hacks e / ou javascript. Mas, o que acontece é que, no meu caso, os botões de upload de arquivo são apenas para upload de imagens ( jpeg | jpg | png | gif ), então eu queria saber se poderia usar uma clickableimagem " " que atuaria exatamente como um arquivo de tipo de entrada ( mostra a caixa de diálogo e mesmo $ _FILE na página enviada).
Eu encontrei uma solução alternativa aqui , e esta interessante também (mas não funciona no Chrome = /).

O que vocês fazem quando querem adicionar algum estilo aos botões de arquivo? Se você tem algum ponto de vista sobre isso, basta clicar no botão de resposta;)

Nicolas
fonte
2
Para todos que estão chegando aqui, tympanus.net/codrops/2015/09/15/… também pode valer a pena dar uma olhada. (Não é afiliado a esse site de nenhuma forma, forma ou forma.)
CBroe

Respostas:

276

Isso funciona muito bem para mim:

.image-upload>input {
  display: none;
}
<div class="image-upload">
  <label for="file-input">
    <img src="https://icon-library.net/images/upload-photo-icon/upload-photo-icon-21.jpg"/>
  </label>

  <input id="file-input" type="file" />
</div>

Basicamente, o atributo for do rótulo faz com que clicar no rótulo seja o mesmo que clicar na entrada especificada .

Além disso, a propriedade display definida como none faz com que a entrada do arquivo não seja renderizada de forma alguma, ocultando-a de forma limpa.

Testado no Chrome, mas de acordo com a web deve funcionar em todos os principais navegadores. :)

EDITAR: JSFiddle adicionado aqui: https://jsfiddle.net/c5s42vdz/

difícil
fonte
Não tenho certeza se as pessoas ainda o consideram um 'grande navegador', mas isso não parece funcionar no IE7
Hoppe
@Chet parece estar funcionando nas versões mais recentes do Safari (7 +). Qual versão você está usando?
marcante em
1
@Toto Para mim está funcionando no IE11, adicionei um JSFiddle para que você também possa verificá-lo.
marcante em
@hardsetting Você está certo! Desculpe (talvez eu estivesse em um modo de documento diferente, ie8 ou inferior)
Toto
2
desculpe, mas acho que este código deve ser atualizado com o nome do arquivo ou pelo menos uma mensagem de que o arquivo foi selecionado com sucesso. O usuário não tem entrada visual sobre o que aconteceu depois que ele selecionou o arquivo. Isso poderia ser feito, por favor? Talvez mude para uma imagem diferente, quando um arquivo for escolhido?
JoaMika
66

Na verdade, isso pode ser feito em puro css e é muito fácil ...

Código HTML

<label class="filebutton">
Browse For File!
<span><input type="file" id="myfile" name="myfile"></span>
</label>

Estilos CSS

label.filebutton {
    width:120px;
    height:40px;
    overflow:hidden;
    position:relative;
    background-color:#ccc;
}

label span input {
    z-index: 999;
    line-height: 0;
    font-size: 50px;
    position: absolute;
    top: -2px;
    left: -700px;
    opacity: 0;
    filter: alpha(opacity = 0);
    -ms-filter: "alpha(opacity=0)";
    cursor: pointer;
    _cursor: hand;
    margin: 0;
    padding:0;
}

A ideia é posicionar a entrada absolutamente dentro de sua etiqueta. defina o tamanho da fonte da entrada para algo grande, o que aumentará o tamanho do botão "navegar". Em seguida, é necessária alguma tentativa e erro usando as propriedades esquerda / superior negativa para posicionar o botão de navegação de entrada atrás de sua etiqueta.

Ao posicionar o botão, defina o alfa para 1. Quando terminar, defina-o novamente para 0 (para que você possa ver o que está fazendo!)

Certifique-se de testar em vários navegadores, pois todos eles renderizarão o botão de entrada em um tamanho ligeiramente diferente.

meles
fonte
Obrigado, Toby, por que há 'esquerda: -700px;' ? No firefox, o campo de entrada do arquivo está flutuando no lado esquerdo de uma página ... ele não se fixa na extensão do rótulo ... Se eu remover 'left: -700px;' funciona bem
lisak
+1 Obrigado, @Sloin left: -700px porque ele queria que o botão de navegação ficasse sobre o botão para que o cursor fosse um ponteiro e não o cursor de texto.
Caleb Doucet
14

Ótima solução por @hardsetting, mas fiz algumas melhorias para fazê-lo funcionar com Safari (5.1.7) no Windows

.image-upload > input {
  visibility:hidden;
  width:0;
  height:0
}
<div class="image-upload">
  <label for="file-input">
    <img src="https://placehold.it/100/000000/ffffff?text=UPLOAD" style="pointer-events: none"/>
  </label>

  <input id="file-input" type="file" />
</div>

Eu tenho usado visibility: hidden, width:0em vez de display: nonepara emissão safari e acrescentou pointer-events: noneemimg tag para torná-lo trabalhar se o tipo de arquivo de entrada tag está na tag FORM.

Parece funcionar para mim em todos os principais navegadores.

Espero que ajude alguém.

rishi
fonte
não há necessidade de adicionar style = "pointer-events: none", isso cria o problema para abrir o arquivo de navegação.
SantoshK
5

Eu usaria SWFUpload ou Uploadify . Eles precisam do Flash, mas fazem tudo o que você quiser sem problemas.

Qualquer <input type="file">solução alternativa que tente acionar a caixa de diálogo "abrir arquivo" por meios diferentes de clicar no controle real pode ser removida dos navegadores por motivos de segurança a qualquer momento. (Acho que nas versões atuais do FF e do IE, não é mais possível acionar esse evento programaticamente.)

Pekka
fonte
Obrigado, eu também os vi por aí, mas acho que os dois precisam de um flash player para funcionar, e não quero adicionar outra camada obrigatória para os usuários. Além disso, você tem certeza de que eles enviarão exatamente o mesmo tipo de dados que os do arquivo de entrada? Não quero testar novamente todo o meu PHP feito na página de envio. Felicidades.
Nicolas
@niko não, eles funcionam de maneira diferente, não são elementos de formulário, mas enviam o arquivo para um script de recebimento por conta própria, então você provavelmente terá que alterar o fluxo de trabalho do seu script. Se isso não for uma opção, acho que você não pode fazer melhor do que Shaun Inman fez no post para o qual você tem um link ...
Pekka
Receio então, isso é realmente uma pena. Não há nada sobre isso na implementação futura de CSS? Obrigado pelas respostas de qualquer maneira :)
Nicolas
@niko de nada. Boa pergunta sobre CSS - na verdade não sei, mas HTML 5 pode muito bem trazer coisas novas aqui. Verifique appelsiini.net/2009/10/html5-drag-and-drop-multiple-file-upload por exemplo.
Pekka
Sim, parece promissor mesmo se a demonstração appelsiini.net/demo/html5_upload/demo.html não for exibida com meu FF 3.6.3 enquanto diz que preciso do FF 3.6.x De qualquer forma, para voltar ao meu problema, atualmente HTML / CSS / Javscript (mas sem flash) só me permite fazer o quê? Algumas fontes e personalização de "cores"? Estou certo então? Felicidades.
Nicolas
5

Este é o meu método se entendi

HTML

<label for="FileInput">
    <img src="tools/img/upload2.png" style="cursor:pointer" onmouseover="this.src='tools/img/upload.png'" onmouseout="this.src='tools/img/upload2.png'" alt="Injaz Msila" style="float:right;margin:7px" />
</label>
<form action="upload.php">
    <input type="file" id="FileInput" style="cursor: pointer;  display: none"/>
    <input type="submit" id="Up" style="display: none;" />
</form>

jQuery

<script type="text/javascript">
    $( "#FileInput" ).change(function() {
      $( "#Up" ).click();
    });
</script>
SystemDZ
fonte
3

é muito simples, você pode tentar isso:

$("#image id").click(function(){
    $("#input id").click();
});
Zicsus
fonte
2

Em vez disso, você pode colocar uma imagem e fazer assim:

HTML:

<img src="/images/uploadButton.png" id="upfile1" style="cursor:pointer" />
<input type="file" id="file1"  name="file1" style="display:none" />

JQuery:

$("#upfile1").click(function () {
    $("#file1").trigger('click');
});

CAVEAT : No IE9 e IE10, se você acionar o onclick em uma entrada de arquivo via javascript, o formulário é sinalizado como 'perigoso' e não pode ser enviado com javascript, não há certeza se pode ser enviado tradicionalmente.

ParPar
fonte
2

        form input[type="file"] {
          display: none;
        }
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>

<head>
  <title>Simple File Upload</title>
  <meta name="" content="">
</head>

<body>
  <form action="upload.php" method="post" enctype="multipart/form-data">
    Select image to upload:
    <label for="fileToUpload">
      <img src="http://s3.postimg.org/mjzvuzi5b/uploader_image.png" />
    </label>
    <input type="File" name="fileToUpload" id="fileToUpload">
    <input type="submit" value="Upload Image" name="submit">
  </form>
</body>

</html>

RUN SNIPPET ou apenas copie o código acima e execute. Você vai conseguir o que queria. Muito simples e eficaz sem javascript. Aproveitar!!!

Neocórtex
fonte
Infelizmente, esses métodos não estão funcionando no Safari para mim :(
czLukasss
1

A própria entrada está oculta com a visibilidade CSS: oculta.

Então você pode ter qualquer elemento que desejar - âncora ou imagem .., quando a âncora / imagem for clicada, acione um clique no campo de entrada oculto - a caixa de diálogo para selecionar um arquivo aparecerá.

EDIT: Na verdade funciona no Chrome e Safari, acabei de notar que não é o caso no FF4Beta

Petrunov
fonte
1

Código de Trabalho:

apenas esconda a parte de entrada e faça assim.

<div class="ImageUpload">
   <label for="FileInput">
      <img src="../../img/Upload_Panel.png" style="width: 18px; margin-top: -316px; margin-left: 900px;"/>
   </label>

  <input id="FileInput" type="file" onchange="readURL(this,'Picture')" style="cursor: pointer;  display: none"/>
</div>
user3400389
fonte
1

Tive muitos problemas com entradas ocultas e não visíveis na última década, às vezes as coisas são muito mais simples do que pensamos.

Tive um pequeno desejo com o IE 5,6,7,8 e 9 de não suportar a opacidade e, portanto, a entrada do arquivo cobriria a imagem de upload, entretanto o seguinte código css resolveu o problema.

-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);  

O seguinte recorte foi testado no Chrome, IE 5,6,7,8,9,10, o único problema no IE 5 é que ele não suporta margem automática.

Execute o snippet simplesmente copie e cole o CSS e o HTML modifique o tamanho como desejar.

.file-upload{
	height:100px;
	width:100px;
	margin:40px auto;
	border:1px solid #f0c0d0;
	border-radius:100px;
	overflow:hidden;
	position:relative;
}
.file-upload input{
	position:absolute;
	height:400px;
	width:400px;
	left:-200px;
	top:-200px;
	background:transparent;
	opacity:0;
	-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
	filter: alpha(opacity=0);  
}
.file-upload img{
	height:70px;
	width:70px;
	margin:15px;
}
<div class="file-upload">
<!--place upload image/icon first !-->
<img src="https://i.stack.imgur.com/dy62M.png" />
<!--place input file last !-->
<input type="file" name="somename" />
</div>

codedudey
fonte