Estilo de um tipo de entrada = botão "arquivo"

735

Como você estiliza um type="file"botão de entrada ?

Shivanand
fonte
Vou acrescentar a minha própria resposta para fazê-lo da maneira que eu fiz ... mas aqui está um exemplo baseado em inicialização que podem ajudar .. geniuscarrier.com/...
Vishnu Narang

Respostas:

235

As entradas de arquivo de estilo são notoriamente difíceis, pois a maioria dos navegadores não altera a aparência de CSS ou javascript.

Mesmo o tamanho da entrada não responderá aos gostos de:

<input type="file" style="width:200px">

Em vez disso, você precisará usar o atributo size:

<input type="file" size="60" />

Para qualquer estilo mais sofisticado do que isso (por exemplo, alterando a aparência do botão de navegação), será necessário observar a abordagem complicada de sobrepor um botão estilizado e uma caixa de entrada sobre a entrada do arquivo nativo. O artigo já mencionado por rm em www.quirksmode.org/dom/inputfile.html é o melhor que eu já vi.

ATUALIZAR

Embora seja difícil estilizar uma <input>tag diretamente, isso é facilmente possível com a ajuda de uma <label>tag. Veja a resposta abaixo de @JoshCrozier: https://stackoverflow.com/a/25825731/10128619

Jonathan Moffatt
fonte
7
Acabei de encontrar uma solução jquery baseada neste script aqui: blog.vworld.at/2008/08/21/…
mtness
1
A resposta de @TLK Ryan não funcionará no IE ao tentar fazer uploads de iframe. Isso fornece um erro de acesso negado. Para envios normais, eu concordo que é o mais fácil!
Frostymarvelous
3
Uma solução muito mais simples que a do modo quirks é explicada aqui . Basta colocar esse link aqui, já que essa resposta é basicamente uma resposta apenas de link.
Joeytje50
10
Para qualquer pessoa interessada em uma abordagem moderna, sugiro olhar para esta resposta . Também não requer JavaScript, como algumas das outras respostas.
Josh Crozier
3
A @JoshCrozier postou uma solução incrivelmente melhor. Mesmo bate soluções de mouseclicking falsos :)
Lodewijk
1018

Você não precisa de JavaScript para isso! Aqui está uma solução para vários navegadores:

Veja este exemplo! - Funciona no Chrome / FF / IE - (IE10 / 9/8/7)

A melhor abordagem seria ter um elemento de rótulo personalizado com um foratributo anexado a um elemento de entrada de arquivo oculto . (O foratributo do rótulo deve corresponder ao elemento do arquivo idpara que isso funcione).

<label for="file-upload" class="custom-file-upload">
    Custom Upload
</label>
<input id="file-upload" type="file"/>

Como alternativa, você também pode envolver o elemento de entrada do arquivo diretamente com um rótulo: (exemplo)

<label class="custom-file-upload">
    <input type="file"/>
    Custom Upload
</label>

Em termos de estilo, oculte 1 o elemento de entrada usando o seletor de atributos .

input[type="file"] {
    display: none;
}

Então, tudo que você precisa fazer é estilizar o labelelemento personalizado . (exemplo) .

.custom-file-upload {
    border: 1px solid #ccc;
    display: inline-block;
    padding: 6px 12px;
    cursor: pointer;
}

1 - Vale a pena notar que, se você ocultar o elemento display: none, ele não funcionará no IE8 e abaixo. Também esteja ciente do fato de que o jQuery validate não valida campos ocultos por padrão. Se um desses problemas for um problema para você, aqui estão dois métodos diferentes para ocultar a entrada ( 1 , 2 ) que funciona nessas circunstâncias.

Josh Crozier
fonte
43
Porém, eu tenho uma pergunta com essa, ao selecionar um arquivo, como exibiríamos o nome do arquivo?
precisa saber é o seguinte
17
Como exibir o nome do arquivo selecionado se display: noneestiver definido para input[type=file]?
Sarthak Singhal
38
Ótima solução, mas você realmente precisa de javascript. Se você deseja exibir o nome do arquivo, como outras pessoas perguntam, é necessário adicionar um intervalo entre o rótulo e a entrada oculta: <span id = "file-selected"> </span>. Atualize o período no evento de alteração: $ ('# file-upload'). Bind ('change', function () {var fileName = ''; fileName = $ (this) .val (); $ ('# selecionado-file ') html (fileName);}).
Sam
9
Você deve usar em position: absolute; left: -99999remvez de display: nonepor motivos de acessibilidade. Na maioria das vezes, os leitores de tela não lêem elementos se estiverem ocultos usando o display: nonemétodo
Capsule
10
Estou muito surpreso ao descobrir que ninguém parece ter considerado a acessibilidade do teclado. labelelementos não são acessíveis pelo teclado, ao contrário de buttons e inputs. A adição tabindexnão é uma solução, porque labelainda não será acionada quando tiver o foco e o usuário pressionar enter. I resolvido por esta visualmente escondendo a entrada, para que ainda possa ser centrada, e, em seguida, utilizando :focus-withinno labelpai: jsbin.com/fokexoc/2/edit?html,css,output
Oliver Joseph Ash
195

siga estas etapas e crie estilos personalizados para o formulário de upload de arquivos:

  1. este é o formulário HTML simples (leia os comentários em HTML que escrevi aqui abaixo)

    <form action="#type your action here" method="POST" enctype="multipart/form-data">
      <div id="yourBtn" style="height: 50px; width: 100px;border: 1px dashed #BBB; cursor:pointer;" onclick="getFile()">Click to upload!</div>
      <!-- this is your file input tag, so i hide it!-->
      <div style='height: 0px;width:0px; overflow:hidden;'><input id="upfile" type="file" value="upload"/></div>
      <!-- here you can have file submit button or you can write a simple script to upload the file automatically-->
      <input type="submit" value='submit' >
    </form>
  2. use esse script simples para passar o evento click para a tag de entrada do arquivo.

    function getFile(){
         document.getElementById("upfile").click();
    }

    Agora você pode usar qualquer tipo de estilo sem se preocupar em alterar os estilos padrão.

Sei muito bem disso, porque tenho tentado alterar os estilos padrão há um mês e meio. acredite, é muito difícil porque navegadores diferentes têm tags de entrada de upload diferentes. Portanto, use este para criar seus formulários de upload de arquivos personalizados. Aqui está o código completo do UPLOAD AUTOMATIZADO.

function getFile() {
  document.getElementById("upfile").click();
}

function sub(obj) {
  var file = obj.value;
  var fileName = file.split("\\");
  document.getElementById("yourBtn").innerHTML = fileName[fileName.length - 1];
  document.myForm.submit();
  event.preventDefault();
}
#yourBtn {
  position: relative;
  top: 150px;
  font-family: calibri;
  width: 150px;
  padding: 10px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border: 1px dashed #BBB;
  text-align: center;
  background-color: #DDD;
  cursor: pointer;
}
<form action="#type your action here" method="POST" enctype="multipart/form-data" name="myForm">
  <div id="yourBtn" onclick="getFile()">click to upload a file</div>
  <!-- this is your file input tag, so i hide it!-->
  <!-- i used the onchange event to fire the form submission-->
  <div style='height: 0px;width: 0px; overflow:hidden;'><input id="upfile" type="file" value="upload" onchange="sub(this)" /></div>
  <!-- here you can have file submit button or you can write a simple script to upload the file automatically-->
  <!-- <input type="submit" value='submit' > -->
</form>

teshguru
fonte
6
@ user1053263 -> Obrigado pela recomendação .. aqui eu usei um script java muito simples, não há necessidade de usar estruturas como Jquery ou PrototypeJS.
teshguru
7
Estou com problemas para enviar o formulário no IE9. Estou recebendo um erro "Acesso negado" que tenta enviar o formulário via javascript. Se eu clicar no botão enviar pela interface do usuário, ele funcionará. Existe uma solução alternativa para isso?
Kevin
1
@kevin -> Por favor, tente event.preventDefault () após document.myForm.submit (), fiz a alteração no código acima.
teshguru
1
Funciona bem no Chrome, Firefox, Safari e Opera - mas não no IE9. No IE9, recebo o mesmo erro 'Acesso negado' que o @ Kevin - e, às vezes, apenas uma falha silenciosa sem erro.
Davidwc
10
No IE10 (e possivelmente no IE9, etc.), você receberá "Acesso negado" (ou nenhuma resposta do jQuery) se tentar enviar automaticamente o formulário após clicar no botão de entrada do arquivo através de javascript. Portanto, esse método funciona para estilizar o botão de entrada do arquivo, desde que o usuário ainda esteja enviando o formulário. Demorei um pouco para descobrir isso e vejo que outros também têm o mesmo problema. Consulte isso para obter mais informações: stackoverflow.com/a/4335390/21579 .
precisa
76

Oculte-o com css e use um botão personalizado com $ (seletor) .click () para ativar o botão de navegação. em seguida, defina um intervalo para verificar o valor do tipo de entrada do arquivo. o intervalo pode exibir o valor para o usuário, para que ele possa ver o que está sendo carregado. o intervalo será limpo quando o formulário for enviado [EDIT] Desculpe, eu tenho estado muito ocupado tentando atualizar esta postagem, aqui está um exemplo

<form action="uploadScript.php" method="post" enctype="multipart/form-data">
<div>
    <!-- filename to display to the user -->
    <p id="file-name" class="margin-10 bold-10"></p>

    <!-- Hide this from the users view with css display:none; -->
    <input class="display-none" id="file-type" type="file" size="4" name="file"/>

    <!-- Style this button with type image or css whatever you wish -->
    <input id="browse-click" type="button" class="button" value="Browse for files"/>

    <!-- submit button -->
    <input type="submit" class="button" value="Change"/>
</div>

$(window).load(function () {
    var intervalFunc = function () {
        $('#file-name').html($('#file-type').val());
    };
    $('#browse-click').on('click', function () { // use .live() for older versions of jQuery
        $('#file-type').click();
        setInterval(intervalFunc, 1);
        return false;
    });
});
Ryan
fonte
7
Note que se você usar essa maneira ele vai quebrar no Internet Explorer porque sua uma exceção de segurança ..
Rejinderi
1
obrigado a dica. Quando eu uso o IE, geralmente ele tem um layout separado para todo o resto. ODEIO IE. mas eu simplifico tudo no IE.
Ryan
1
Com o FF20, $ ('# tipo de arquivo'). Click () não parece exibir a caixa de diálogo "Escolher arquivo" - na verdade, nada acontece. Alguma ideia?
22713 andig
2
Tente usar o método trigger no jquery. Também mudou .Live para .no () na nova jquery
Ryan
1
Depois de definir esse intervalo, em que ponto posso limpá-lo? então ele irá ser constantemente disparando
Dave Haigh
60

HTML

<div class="new_Btn">SelectPicture</div><br>
<input id="html_btn" type='file'" /><br>

CSS

.new_Btn {
// your css propterties
}

#html_btn {
 display:none;
}

jQuery

$('.new_Btn').bind("click" , function () {
        $('#html_btn').click();
    });
//edit: 6/20/2014: Be sure to use ".on" not ".bind" for newer versions of jQuery

Violino : http://jsfiddle.net/M7BXC/

Você também pode alcançar seus objetivos sem o jQuery com JavaScript normal.

Agora o newBtn está vinculado ao html_btn e você pode estilizar seu novo btn como quiser: D

Wykk
fonte
1
Apenas curioso, ele funciona em todos os navegadores de nova geração, como Firefox, IE, Opera, Safari, Chrome, etc?
Wh1T3h4Ck5 04/10/12
Esta é a solução mais simples para mim! Pelo menos no IE 9, Chrome 23 e FF 16 com jQuery 1.7.2, portanto, com versões atualizadas, ele deve funcionar.
Dani Bishop
Alguém sabe como alterar o .new_Btn, caso o usuário tenha escolhido uma imagem. Agora, apenas mostra a mesma classe. Alguém sabe como rastrear isso? Obrigado
Ando
2
@MehdiKaramosly ele funciona mesmo no IE 6 - mas isso é verdade apenas até jQuery 1.x , jQuery 2.x + não suporta IEs velhos
jave.web
1
@Ando via JavaScript / jQuery => o valor da entrada de arquivo está vazio ou contém locais caminho do arquivo => uso onchange evento e teste para val () :) ver jsfiddle.net/ZrBPF
jave.web
55

Todos os mecanismos de renderização geram automaticamente um botão quando um <input type="file">é criado. Historicamente, esse botão não tem estilo. No entanto, Trident e WebKit adicionaram ganchos através de pseudo-elementos.

Tridente

No IE10, o botão de entrada do arquivo pode ser estilizado usando o ::-ms-browsepseudoelemento. Basicamente, qualquer regra CSS aplicada a um botão regular pode ser aplicada ao pseudoelemento. Por exemplo:

::-ms-browse {
  background: black;
  color: red;
  padding: 1em;
}
<input type="file">

Isso é exibido da seguinte maneira no IE10 no Windows 8:

Isso é exibido da seguinte maneira no IE10 no Windows 8:

WebKit

O WebKit fornece um gancho para o botão de entrada de arquivo com o ::-webkit-file-upload-buttonpseudoelemento. Novamente, praticamente qualquer regra CSS pode ser aplicada; portanto, o exemplo Trident também funcionará aqui:

::-webkit-file-upload-button {
  background: black;
  color: red;
  padding: 1em;
}
<input type="file">

Isso é exibido da seguinte maneira no Chrome 26 no OS X:

Isso é exibido da seguinte maneira no Chrome 26 no OS X:

Anselmo
fonte
Não há possibilidades de estilo especiais para programas baseados no Gecko como o Firefox.
Anselm
2
Na sua resposta, usando css, como ocultar a palavra "Nenhum arquivo escolhido" na tag <input type = file>. Por favor, comente.
user2086641
Eu não tenho idéia, desculpe
Anselm
1
No caso de alguém quer jogar com estilos eu adicionei um jsfidde aqui: jsfiddle.net/peter_drinnan/r0gq6kw2
Peter Drinnan
26

Se você estiver usando o Bootstrap 3, isso funcionou para mim:

Consulte http://www.abeautifulsite.net/whipping-file-inputs-into-shape-with-bootstrap-3/

.btn-file {
  position: relative;
  overflow: hidden;
}
.btn-file input[type=file] {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 100%;
  min-height: 100%;
  font-size: 100px;
  text-align: right;
  filter: alpha(opacity=0);
  opacity: 0;
  outline: none;
  background: white;
  cursor: inherit;
  display: block;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />

<span class="btn btn-primary btn-file">
    Browse...<input type="file">
</span>

Que produz o seguinte botão de entrada de arquivo:

Botão de exemplo

Sério, confira http://www.abeautifulsite.net/whipping-file-inputs-into-shape-with-bootstrap-3/

JDawg
fonte
2
Isso preserva a funcionalidade de arrastar e soltar, o que é ótimo :), a maioria das respostas não aceita arquivos descartados.
A1rPun 22/01
25

Exemplo de trabalho aqui com suporte nativo ao arrastar e soltar: https://jsfiddle.net/j40xvkb3/

Ao estilizar uma entrada de arquivo, você não deve interromper nenhuma interação nativa fornecida pela entrada .

A display: noneabordagem quebra o suporte nativo de arrastar e soltar.

Para não quebrar nada, você deve usar o opacity: 0 abordagem da entrada e posicioná-la usando o padrão relativo / absoluto em um wrapper.

Usando essa técnica, você pode facilmente estilizar uma zona de clique / soltar para o usuário e adicionar classe personalizada em javascript no dragenterevento para atualizar estilos e fornecer um feedback ao usuário para permitir que ele veja que ele pode soltar um arquivo.

HTML:

<label for="test">
  <div>Click or drop something here</div>
  <input type="file" id="test">
</label>

CSS:

input[type="file"] {
  position: absolute;
  left: 0;
  opacity: 0;
  top: 0;
  bottom: 0;
  width: 100%;
}

div {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #ccc;
  border: 3px dotted #bebebe;
  border-radius: 10px;
}

label {
  display: inline-block;
  position: relative;
  height: 100px;
  width: 400px;
}

Aqui está um exemplo prático (com JS adicional para manipular dragoverarquivos de eventos e descartados)

https://jsfiddle.net/j40xvkb3/

Espero que isso tenha ajudado!

kevcha
fonte
obrigado pelo post, como isso funciona se o atributo multiple = "multiple" for adicionado? Eu arrastei duas imagens e vi o caminho apenas para a primeira.
PirateApp
Você perdeu o código aqui. Há mais sobre o violino. Qual biblioteca?
ctrl-alt-delor
Há apenas algum javascript no violino do jQuery para mostrar os arquivos que foram descartados. Isso é tudo
kevcha
Depois de implementar essa solução e testá-la mais, ela não parece funcionar no Edge.
precisa saber é o seguinte
1
Ah, ok, eu perdi o invólucro com a posição relativa em sua resposta - Meu mal. Se a entrada estiver abaixo das dimensões da tela, o navegador tentará rolar até ela e, ao fazer isso, moverá o contêiner de rolagem para cima da página. Aqui está uma demonstração: stackblitz.com/edit/input-file-overflow?file=style.css (apenas não exatamente demonstrando como posição absoluta é a causa do comportamento)
Tom
23

Eu sou capaz de fazê-lo com CSS puro usando o código abaixo. Eu usei bootstrap e fonte-awesome.

<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" />

<label class="btn btn-default btn-sm center-block btn-file">
  <i class="fa fa-upload fa-2x" aria-hidden="true"></i>
  <input type="file" style="display: none;">
</label>

Karthik
fonte
21
 <label>
    <input type="file" />
 </label>

Você pode agrupar seu input type = "file" dentro de um rótulo para a entrada. Estilize o rótulo da maneira que desejar e oculte a entrada com display: none;

JGuo
fonte
Uma alternativa pode ser gist.github.com/barneycarroll/5244258 ou jsfiddle.net/4cwpLvae (funciona no IE11)
surfmuggle
12

Aqui está uma solução que realmente não estiliza o <input type="file" />elemento, mas usa um <input type="file" />elemento em cima de outros elementos (que podem ser estilizados). O <input type="file" />elemento não é realmente visível, portanto, a ilusão geral é de um controle de upload de arquivo com estilo.

Me deparei com esse problema recentemente e, apesar da infinidade de respostas no Stack Overflow, nenhuma parecia realmente se encaixar. No final, acabei personalizando isso para ter uma solução simples e elegante.

Também testei isso no Firefox, IE (11, 10 e 9), Chrome e Opera, iPad e alguns dispositivos Android.

Aqui está o link do JSFiddle -> http://jsfiddle.net/umhva747/

$('input[type=file]').change(function(e) {
    $in = $(this);
    $in.next().html($in.val());
    
});

$('.uploadButton').click(function() {
    var fileName = $("#fileUpload").val();
    if (fileName) {
        alert(fileName + " can be uploaded.");
    }
    else {
        alert("Please select a file to upload");
    }
});
body {
    background-color:Black;
}

div.upload {
    background-color:#fff;
    border: 1px solid #ddd;
    border-radius:5px;
    display:inline-block;
    height: 30px;
    padding:3px 40px 3px 3px;
    position:relative;
    width: auto;
}

div.upload:hover {
    opacity:0.95;
}

div.upload input[type="file"] {
    display: input-block;
    width: 100%;
    height: 30px;
    opacity: 0;
    cursor:pointer;
    position:absolute;
    left:0;
}
.uploadButton {
    background-color: #425F9C;
    border: none;
    border-radius: 3px;
    color: #FFF;
    cursor:pointer;
    display: inline-block;
    height: 30px;
    margin-right:15px;
    width: auto;
    padding:0 20px;
    box-sizing: content-box;
}

.fileName {
    font-family: Arial;
    font-size:14px;
}

.upload + .uploadButton {
    height:38px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form action="" method="post" enctype="multipart/form-data">
    <div class="upload">
        <input type="button" class="uploadButton" value="Browse" />
        <input type="file" name="upload" accept="image/*" id="fileUpload" />
        <span class="fileName">Select file..</span>
    </div>
    <input type="button" class="uploadButton" value="Upload File" />
</form>

Espero que isto ajude!!!

Satwik Nadkarny
fonte
2
Uma solução engenhosamente inteligente para essas nefastas alterações de estilo de upload de arquivos.
Rmcsharry 10/09/16
O melhor de tudo. Perfeito!!
Karra 10/01
11

Isso é simples com o jquery. Para dar um exemplo de código da sugestão de Ryan com uma pequena modificação.

HTML básico:

<div id="image_icon"></div>
<div id="filename"></div>
<input id="the_real_file_input" name="foobar" type="file">

Certifique-se de definir o estilo na entrada quando estiver pronto: opacity: 0 você não pode definir display: noneporque precisa ser clicável. Mas você pode posicioná-lo sob o botão "novo" ou dobrá-lo sob outra coisa com o z-index, se preferir.

Configure algum jquery para clicar na entrada real quando você clicar na imagem.

$('#image_icon').click(function() {
    $('#the_real_file_input').click();
});

Agora seu botão está funcionando. Basta cortar e colar o valor quando alterado.

$('input[type=file]').bind('change', function() {
    var str = "";
    str = $(this).val();
    $("#filename").text(str);
}).change();

Tah dah! Pode ser necessário analisar o val () para algo mais significativo, mas você deve estar pronto.

TLK
fonte
1
isso falhará com o FF11 - motivo: como você não pode influenciar com precisão o tamanho do campo de entrada (apenas usando tamanho html) e o botão (você pode definir a altura usando css), se o seu campo de entrada visível for maior que o FF original nos fornece, você é deixado com uma área muito big blind - ponto de vista do usuário: na maioria dos casos ele vai reclamar que upload não trabalho, quando clicado
Jeffz
2
Boa ideia, mas isso não funcionará no IE. $ ('# the_real_file_input'). click () ativará a caixa de diálogo aberta, mas o arquivo não será selecionado em um formulário e o upload falhará.
Tomas
11

Coloque o botão de upload de arquivo sobre seu botão ou elemento legal e oculte-o.

Muito simples e funcionará em qualquer navegador

<div class="upload-wrap">
    <button type="button" class="nice-button">upload_file</button>
    <input type="file" name="file" class="upload-btn">
</div>

Estilos

.upload-wrap {
    position: relative;
}

.upload-btn {
    position: absolute;
    left: 0;
    opacity: 0;
}
Tigran Babajanyan
fonte
8

VISIBILIDADE: truque oculto

Eu costumo seguir o visibility:hiddentruque

este é o meu botão estilizado

<div id="uploadbutton" class="btn btn-success btn-block">Upload</div>

este é o tipo de entrada = botão de arquivo. Observe a visibility:hiddenregra

<input type="file" id="upload" style="visibility:hidden;">

este é o bit JavaScript para colá-los juntos. Funciona

<script>
 $('#uploadbutton').click(function(){
    $('input[type=file]').click();
 });
 </script>
Gianluca Ghettini
fonte
1
você não pode usar o método click () para disparar um evento para o arquivo do tipo de entrada. a maior parte do navegador não permite por razões de segurança
Mahi
mesmo usando jquery? isso está correto? como você faria isso?
Gianluca Ghettini
style="visibility:hidden"é muito longo, basta usar hidden. Além disso, click()funciona para qualquer navegador e não há nenhuma razão de segurança veryfiable a partir de agora e em qualquer dispositivo é a maneira legal e @Gianluca para uso clássico jQuerytrigger()
Thielicious
1
Esta é precisamente a solução que eu adicionaria a isso! Funciona e você pode exibi-lo exatamente como deseja. Funciona com o Chrome, tentará outros.
markthewizard1234
7

a única maneira de pensar é encontrar o botão com javascript depois que ele é renderizado e atribuir um estilo a ele

você também pode olhar para este artigo

m romano
fonte
CSS puro, sem JavaScript, funciona em todos os navegadores até o ie7 - incrível!
Simon Steinberger
7
<input type="file" name="media" style="display-none" onchange="document.media.submit()">

Eu normalmente usaria javascript simples para personalizar a tag de entrada do arquivo. Um campo de entrada oculto, ao clicar no botão, o javascript chama o campo oculto, solução simples sem qualquer css ou monte de jquery.

<button id="file" onclick="$('#file').click()">Upload File</button>
user2086641
fonte
1
você não pode usar o click()método para disparar evento para o arquivo de tipo de entrada. a maior parte do navegador não permite por motivos de segurança.
Mahi
6

Aqui usamos um período para acionar a entrada do tipo de arquivo e simplesmente personalizamos esse período , para que possamos adicionar qualquer estilo dessa maneira.

Observe que usamos a tag de entrada com a opção visibilidade: oculta e a acionamos no período.

.attachFileSpan{
color:#2b6dad;
cursor:pointer;
}
.attachFileSpan:hover{
text-decoration: underline;
}
<h3> Customized input of type file </h3>
<input id="myInput" type="file" style="visibility:hidden"/>

        <span title="attach file" class="attachFileSpan" onclick="document.getElementById('myInput').click()">
        Attach file
        </span>

Referência

Abdallah Okasha
fonte
5

É uma ótima maneira de fazer isso com o upload de material / arquivo angular. Você pode fazer o mesmo com um botão de inicialização.

Observe que eu usei, em <a>vez <button>disso, permite que os eventos de clique borbulhem.

<label>
    <input type="file" (change)="setFile($event)" style="display:none" />

    <a mat-raised-button color="primary">
      <mat-icon>file_upload</mat-icon>
      Upload Document
    </a>

  </label>
Robert King
fonte
1
Isso funciona muito bem em 2+ angulares. Não sei por que foi votado para baixo. Se você estiver usando angular, esta é a solução mais simples disponível.
precisa saber é o seguinte
4

SOMENTE CSS

Use isso muito simples e fácil

Html:

<label>Attach your screenshort</label>
                <input type="file" multiple class="choose">

Css:

.choose::-webkit-file-upload-button {
    color: white;
    display: inline-block;
    background: #1CB6E0;
    border: none;
    padding: 7px 15px;
    font-weight: 700;
    border-radius: 3px;
    white-space: nowrap;
    cursor: pointer;
    font-size: 10pt;
}
Balvant Ahir
fonte
4

Talvez muitos awnsers. Mas eu gosto disso em CSS puro com botões fa:

.divs {
    position: relative;
    display: inline-block;
    background-color: #fcc;
}

.inputs {
    position:absolute;
    left: 0px;
    height: 100%;
    width: 100%;
    opacity: 0;
    background: #00f;
    z-index:999;
}

.icons {
    position:relative;
}
<div class="divs">
<input type='file' id='image' class="inputs">
<i class="fa fa-image fa-2x icons"></i>
</div>

<div class="divs">
<input type='file' id='book' class="inputs">
<i class="fa fa-book fa-5x icons"></i>
</div>
<br><br><br>
<div class="divs">
<input type='file' id='data' class="inputs">
<i class="fa fa-id-card fa-3x icons"></i>
</div>





<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>

Fiddle: https://jsfiddle.net/zoutepopcorn/v2zkbpay/1/

Johan Hoeksma
fonte
4

Não se deixe enganar por "ótimas" soluções somente CSS que são realmente muito específicas do navegador ou que sobrepõem o botão estilizado na parte superior do botão real ou que o forçam a usar um em <label>vez de um<button> ou qualquer outro tipo de hack . É necessário JavaScript para fazê-lo funcionar para uso geral. Por favor, estude como o Gmail e o DropZone fazem isso, se você não acredita em mim.

Apenas estilize um botão normal como desejar e, em seguida, chame uma função JS simples para criar e vincular um elemento de entrada oculto ao seu botão estilizado.

<!DOCTYPE html>
<meta charset="utf-8">

<style>
    button {
        width            : 160px;
        height           : 30px;
        font-size        : 13px;
        border           : none;
        text-align       : center;
        background-color : #444;
        color            : #6f0;
    }
    button:active {
        background-color : #779;
    }
</style>

<button id="upload">Styled upload button!</button>

<script>

function Upload_On_Click(id, handler) {
    var hidden_input = null;
    document.getElementById(id).onclick = function() {hidden_input.click();}
    function setup_hidden_input() {
        hidden_input && hidden_input.parentNode.removeChild(hidden_input);
        hidden_input = document.createElement("input");
        hidden_input.setAttribute("type", "file");
        hidden_input.style.visibility = "hidden";
        document.querySelector("body").appendChild(hidden_input);
        hidden_input.onchange = function() {
            handler(hidden_input.files[0]);
            setup_hidden_input();
        };
    }
    setup_hidden_input();
}

Upload_On_Click("upload", function(file) {
    console.log("GOT FILE: " + file.name);
});

</script>

Observe como o código acima o vincula novamente após cada vez que o usuário escolhe um arquivo. Isso é importante porque "onchange" é chamado apenas se o usuário alterar o nome do arquivo. Mas você provavelmente deseja obter o arquivo sempre que o usuário o fornecer.

personal_cloud
fonte
1
Para ser exato, a labelabordagem funciona, exceto que não pode mostrar o nome ou o caminho do arquivo selecionado. Então, necessariamente falando, esse é o único problema que um JS precisa resolver.
Hassan Baig
4

Solução de vários arquivos com nome de arquivo convertido

EXEMPLO de inicialização

HTML:

<div>
  <label class="btn btn-primary search-file-btn">
    <input name="file1" type="file" style="display:None;"> <span>Choose file</span>
  </label>
  <span>No file selected</span>
</div>

<div>
  <label class="btn btn-primary search-file-btn">
    <input name="file2" type="file" style="display:None;"> <span>Choose file</span>
  </label>
  <span>No file selected</span>
</div>

1. JS com jQuery:

$().ready(function($){
    $('.search-file-btn').children("input").bind('change', function() {
    var fileName = '';
    fileName = $(this).val().split("\\").slice(-1)[0];
    $(this).parent().next("span").html(fileName);
  })
});

2. JS sem jQuery

Array.prototype.forEach.call(document.getElementsByTagName('input'), function(item) {
  item.addEventListener("change", function() {
    var fileName = '';
    fileName = this.value.split("\\").slice(-1)[0];
    this.parentNode.nextElementSibling.innerHTML = fileName;
  });
});
ChrisRob
fonte
3

Aqui está uma solução que também mostra o nome do arquivo escolhido: http://jsfiddle.net/raft9pg0/1/

HTML:

<label for="file-upload" class="custom-file-upload">Chose file</label>
<input id="file-upload" type="file"/>
File: <span id="file-upload-value">-</span>

JS:

$(function() {
    $("input:file[id=file-upload]").change(function() {
        $("#file-upload-value").html( $(this).val() );
    });
});

CSS:

input[type="file"] {
    display: none;
}

.custom-file-upload {
      background: #ddd;
      border: 1px solid #aaa;
      border-top: 1px solid #ccc;
      border-left: 1px solid #ccc;
      -moz-border-radius: 3px;
      -webkit-border-radius: 3px;
      border-radius: 3px;
      color: #444;
      display: inline-block;
      font-size: 11px;
      font-weight: bold;
      text-decoration: none;
      text-shadow: 0 1px rgba(255, 255, 255, .75);
      cursor: pointer;
      margin-bottom: 20px;
      line-height: normal;
      padding: 8px 10px; }
Caleb
fonte
Como exibir apenas o nome do arquivo, e não o fakepathcaminho?
Hassan Baig
3

Nesta semana, eu também precisei personalizar o botão e exibir o nome do arquivo selecionado ao lado, então, depois de ler algumas das respostas acima (Obrigado, BTW), criei a seguinte implementação:

HTML:

<div class="browse">
<label id="uploadBtn" class="custom-file-upload">Choose file
<input type="file" name="fileInput" id="fileInput" accept=".yaml" ngf-select ngf-change="onFileSelect($files)" />
</label>
<span>{{fileName}}</span>
</div>

CSS

   input[type='file'] {
    color: #a1bbd5;
    display: none;

}

.custom-file-upload {
    border: 1px solid #a1bbd5;
    display: inline-block;
    padding: 2px 8px;
    cursor: pointer;
}

label{
    color: #a1bbd5;
    border-radius: 3px;
}

Javascript (Angular)

app.controller('MainCtrl', function($scope) {

        $scope.fileName = 'No file chosen';

          $scope.onFileSelect = function ($files) {
          $scope.selectedFile = $files;
          $scope.fileName = $files[0].name;
    };
});

Basicamente, estou trabalhando com a lib ng-file-upload, no sentido angular, vinculo o nome do arquivo ao meu $ scope e fornecendo o valor inicial de 'Nenhum arquivo escolhido', também vinculo a função onFileSelect () a meu escopo; assim, quando um arquivo é selecionado, estou obtendo o nome do arquivo usando a API ng-upload e atribuindo-o ao $ scope.filename.

liron_hazan
fonte
3

Simplesmente simule um clique <input>usando a trigger()função ao clicar em um estilo <div>. Criei meu próprio botão a partir de um <div>e, em seguida, iniciei um clique no inputquando clico em meu <div>. Isso permite que você crie seu botão da maneira que desejar, porque é um <div>e simula um clique no seu arquivo <input>. Então use display: noneno seu <input>.

// div styled as my load file button
<div id="simClick">Load from backup</div>

<input type="file" id="readFile" />

// Click function for input
$("#readFile").click(function() {
    readFile();
});

// Simulate click on the input when clicking div
$("#simClick").click(function() {
    $("#readFile").trigger("click");
});
James Marquez
fonte
3

A melhor maneira é usar o pseudo-elemento: after ou: before como um elemento visível na entrada de. Em seguida, estilize esse pseudo elemento como desejar. Eu recomendo que você faça como um estilo geral para todos os arquivos de entrada da seguinte maneira:

input {
  height: 0px;
  outline: none;
}

input[type="file"]:before {
  content: "Browse";
  background: #fff;
  width: 100%;
  height: 35px;
  display: block;
  text-align: left;
  position: relative;
  margin: 0;
  margin: 0 5px;
  left: -6px;
  border: 1px solid #e0e0e0;
  top: -1px;
  line-height: 35px;
  color: #b6b6b6;
  padding-left: 5px;
  display: block;
}
Despertaweb
fonte
3

A melhor maneira que eu encontrei é tendo uma input type: fileconfiguração para display: none. Dê um id. Crie um botão ou qualquer outro elemento que você deseja abrir a entrada do arquivo.

Em seguida, adicione um ouvinte de evento (botão) que, quando clicado, simula um clique na entrada do arquivo original. Como clicar em um botão chamado hello, mas abre uma janela de arquivo.

Código de exemplo

//i am using semantic ui

<button class="ui circular icon button purple send-button" id="send-btn">
      <i class="paper plane icon"></i>
    </button>
  <input type="file" id="file" class="input-file" />

javascript

var attachButton=document.querySelector('.attach-button');
    attachButton.addEventListener('click', e=>{
        $('#file').trigger("click")
    })
Taio
fonte
2

o CSS pode fazer muito aqui ... com um pouco de truque ...

<div id='wrapper'>
  <input type='file' id='browse'>
</div>

#wrapper {
     width: 93px; /*play with this value */
     height: 28px; /*play with this value */
     background: url('browseBtn.png') 0 0 no-repeat;
     border:none;
     overflow:hidden;
}

#browse{
     margin-left:-145px; /*play with this value */
     opacity:0; /* set to .5 or something so you can better position it as an overlay then back to zero again after you're done */
     -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
     filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
}

:: referência :: http://site-o-matic.net/?viewpost=19

-Mosteiro

Mosteiro
fonte
2

Encontrei um método muito fácil de alternar o botão de arquivo para uma imagem. Você apenas rotula uma imagem e a coloca em cima do botão de arquivo.

<html>
<div id="File button">
    <div style="position:absolute;">
        <!--This is your labeled image-->
        <label for="fileButton"><img src="ImageURL"></label>
    </div>
    <div>
        <input type="file" id="fileButton"/>
    </div>
</div>
</html>

Ao clicar na imagem rotulada, você seleciona o botão do arquivo.

D-Inventor
fonte
2

Somente essa abordagem oferece toda a flexibilidade! ES6 / VanillaJS!

html:

<input type="file" style="display:none;"></input>
<button>Upload file</button>

javascript:

document.querySelector('button').addEventListener('click', () => {
  document.querySelector('input[type="file"]').click();
});

Isso oculta o botão do arquivo de entrada, mas, sob o capô, ele clica em outro botão normal, que você pode obviamente usar como qualquer outro botão. Esta é a única solução sem desvantagens além de um nó DOM inútil. Graças a display:none;, o botão de entrada não reserva nenhum espaço visível no DOM.

(Não sei mais a quem dar suporte para isso. Mas recebi essa ideia de algum lugar aqui no Stackoverflow.)

codepleb
fonte