Aplicar estilo a un tipo de entrada = botón "archivo"

735

¿Cómo diseñas un type="file"botón de entrada ?

Shivanand
fuente
Agregaré mi propia respuesta para hacerlo como lo hice ... pero aquí hay un ejemplo basado en bootstrap que podría ayudar ... geniuscarrier.com/…
Vishnu Narang

Respuestas:

235

Las entradas de archivos de estilo son notoriamente difíciles, ya que la mayoría de los navegadores no cambiarán la apariencia de CSS o JavaScript.

Incluso el tamaño de la entrada no responderá a los gustos de:

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

En su lugar, deberá usar el atributo de tamaño:

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

Para cualquier estilo más sofisticado que eso (por ejemplo, cambiar el aspecto del botón de exploración), deberá observar el enfoque engañoso de superponer un botón con estilo y un cuadro de entrada en la parte superior de la entrada del archivo nativo. El artículo ya mencionado por rm en www.quirksmode.org/dom/inputfile.html es el mejor que he visto.

ACTUALIZAR

Aunque es difícil diseñar una <input>etiqueta directamente, esto es posible fácilmente con la ayuda de una <label>etiqueta. Vea la respuesta a continuación de @JoshCrozier: https://stackoverflow.com/a/25825731/10128619

Jonathan Moffatt
fuente
77
Acabo de encontrar una solución jquery basada en este script aquí: blog.vworld.at/2008/08/21/…
mtness
1
La respuesta de @TLK Ryan no funcionará en IE cuando intente realizar cargas de iframe. Le da un error de acceso denegado. Sin embargo, para cargas normales, ¡estoy de acuerdo con que es la más fácil!
frostymarvelous
3
Una solución mucho más simple que es de quirksmode explica aquí . Solo pongo ese enlace aquí, ya que esta respuesta es básicamente una respuesta de solo enlace de todos modos.
Joeytje50
10
Para cualquier persona interesada en un enfoque moderno, sugeriría mirar esta respuesta . Tampoco requiere JavaScript como algunas de las otras respuestas.
Josh Crozier
3
@JoshCrozier publicó una solución increíblemente mucho mejor. Incluso supera las soluciones de clics falsos :)
Lodewijk
1019

¡No necesitas JavaScript para esto! Aquí hay una solución de navegador cruzado:

¡Mira este ejemplo! - Funciona en Chrome / FF / IE - (IE10 / 9/8/7)

El mejor enfoque sería tener un elemento de etiqueta personalizado con un foratributo adjunto a un elemento de entrada de archivo oculto . (El foratributo de la etiqueta debe coincidir con el elemento del archivo idpara que esto funcione).

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

Como alternativa, también podría envolver el elemento de entrada del archivo con una etiqueta directamente: (ejemplo)

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

En términos de estilo, solo oculte 1 el elemento de entrada usando el selector de atributos .

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

Entonces, todo lo que necesita hacer es diseñar el labelelemento personalizado . (ejemplo) .

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

1 - Vale la pena señalar que si ocultas el elemento usando display: none, no funcionará en IE8 y versiones inferiores. También tenga en cuenta el hecho de que jQuery validate no valida los campos ocultos de forma predeterminada. Si alguna de esas cosas es un problema para usted, aquí hay dos métodos diferentes para ocultar la entrada ( 1 , 2 ) que funcionan en estas circunstancias.

Josh Crozier
fuente
43
Sin embargo, tengo una pregunta con este, al seleccionar un archivo, ¿cómo haríamos para luego mostrar el nombre del archivo?
Richlewis
17
¿Cómo mostrar el nombre del archivo seleccionado si display: noneestá configurado para input[type=file]?
Sarthak Singhal
38
Gran solución, pero en realidad necesitas JavaScript. Si desea mostrar el nombre del archivo, como han preguntado otras personas, debe agregar un espacio entre la etiqueta y la entrada oculta: <span id = "file-selected"> </span>. Luego actualice el lapso en el evento change: $ ('# file-upload'). Bind ('change', function () {var fileName = ''; fileName = $ (this) .val (); $ ('# file-selected '). html (fileName);})
Sam
99
Debe usar en position: absolute; left: -99999remlugar de display: nonepor razones de accesibilidad. La mayoría de las veces, los lectores de pantalla no leerán elementos si están ocultos usando el display: nonemétodo.
Cápsula
10
Estoy muy sorprendido de encontrar que nadie parece haber considerado la accesibilidad del teclado. labellos elementos no son accesibles por teclado, a diferencia de buttonsy inputs. Agregar tabindexno es una solución porque labelaún no se actuará cuando tenga el foco y el usuario presione Intro. Resolví esto ocultando visualmente la entrada, para que aún pueda enfocarse, y luego usar :focus-withinen el labelpadre: jsbin.com/fokexoc/2/edit?html,css,output
Oliver Joseph Ash
195

siga estos pasos y luego puede crear estilos personalizados para su formulario de carga de archivos:

  1. este es el formulario HTML simple (lea los comentarios HTML que he escrito aquí abajo)

    <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. luego use este script simple para pasar el evento click a la etiqueta de entrada del archivo.

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

    Ahora puede usar cualquier tipo de estilo sin preocuparse por cómo cambiar los estilos predeterminados.

Lo sé muy bien porque he estado tratando de cambiar los estilos predeterminados durante un mes y medio. créeme, es muy difícil porque diferentes navegadores tienen diferentes etiquetas de entrada de carga. Así que use este para construir sus formularios de carga de archivos personalizados. Aquí está el código completo de CARGA AUTOMÁTICA.

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
fuente
66
@ user1053263 -> Gracias por la recomendación ... aquí utilicé un script java muy simple, no es necesario usar frameworks como Jquery o PrototypeJS.
teshguru
77
Tengo problemas para enviar el formulario en IE9. Recibo el error 'Acceso denegado' que intenta enviar el formulario a través de JavaScript. Si hago clic en el botón Enviar a través de la interfaz de usuario, funciona. ¿Hay una solución para esto?
Kevin
1
@kevin -> Intente event.preventDefault () después de document.myForm.submit (), realicé el cambio en el código anterior.
teshguru
1
Funciona bien en Chrome, Firefox, Safari y Opera, pero no en IE9. En IE9 obtengo el mismo error 'Acceso denegado' que @Kevin, y a veces solo un error silencioso sin error.
daveywc
10
En IE10 (y posiblemente IE9, etc.) obtendrá "Acceso denegado" (o ninguna respuesta de jQuery) si intenta enviar el formulario automáticamente después de hacer clic en el botón de entrada de archivo a través de javascript. Por lo tanto, este método funciona para diseñar el botón de entrada de archivo siempre que el usuario siga enviando el formulario. Me tomó un tiempo encontrar esto y veo que otros también tienen el mismo problema. Consulte esto para obtener más información stackoverflow.com/a/4335390/21579 .
Jeff Widmer
76

Escóndelo con css y usa un botón personalizado con $ (selector) .click () para activar el botón de exploración. luego establezca un intervalo para verificar el valor del tipo de entrada del archivo. el intervalo puede mostrar el valor para el usuario para que el usuario pueda ver qué se está cargando. el intervalo se borrará cuando se envíe el formulario [EDITAR] Lo siento, he estado muy ocupado tenía la intención de actualizar esta publicación, aquí hay un ejemplo

<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
fuente
77
Tenga en cuenta que si lo usa de esta manera, se romperá en Internet Explorer porque es una excepción de seguridad ..
Rejinderi
1
Gracias la propina. Cuando uso IE, generalmente tiene un diseño separado de todo lo demás. ODIO IE. pero simplifico todo en IE.
Ryan
1
Con FF20, $ ('# tipo de archivo'). Click () no parece abrir el dial "Elegir archivo"; de hecho, no sucede nada. ¿Algunas ideas?
andig
2
Intente usar el método de activación en jquery. También .live cambió a .on () en el nuevo jquery
Ryan
1
una vez que haya establecido ese intervalo, ¿en qué punto puedo borrarlo? de lo contrario, se disparará constantemente
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

Violín : http://jsfiddle.net/M7BXC/

También puede alcanzar sus objetivos sin jQuery con JavaScript normal.

Ahora newBtn está vinculado con html_btn y puede diseñar su nuevo btn como desee: D

Wykk
fuente
1
Por curiosidad, ¿funciona en todos los navegadores de nueva generación como Firefox, IE, Opera, Safari, Chrome, etc.?
Wh1T3h4Ck5
¡Esta es la solución más simple para mí! Al menos en IE 9, Chrome 23 y FF 16 con jQuery 1.7.2, por lo que con versiones actualizadas debería funcionar.
Dani BISHOP
¿Alguien sabe cómo cambiar .new_Btn en caso de que el usuario haya elegido una imagen? Ahora solo muestra la misma clase. ¿Alguien sabe cómo rastrear eso? Gracias
Ando
2
@MehdiKaramosly funciona incluso en IE 6, pero eso es cierto solo hasta jQuery 1.x , jQuery 2.x + no es compatible con IE antiguos
jave.web
1
@Ando a través de Javascript / jQuery => el valor de la entrada del archivo está vacío o contiene la ruta del archivo local => usa el evento onchange y prueba val () :) ver jsfiddle.net/ZrBPF
jave.web
55

Todos los motores de renderizado generan automáticamente un botón cuando <input type="file">se crea uno. Históricamente, ese botón ha sido completamente sin estilo. Sin embargo, Trident y WebKit han agregado ganchos a través de pseudoelementos.

Tridente

A partir de IE10, el botón de entrada de archivo se puede diseñar utilizando el ::-ms-browsepseudo-elemento. Básicamente, cualquier regla CSS que aplique a un botón normal puede aplicarse al pseudo-elemento. Por ejemplo:

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

Esto se muestra como sigue en IE10 en Windows 8:

Esto se muestra como sigue en IE10 en Windows 8:

WebKit

WebKit proporciona un enlace para su botón de entrada de archivo con el ::-webkit-file-upload-buttonpseudo-elemento. Nuevamente, se puede aplicar casi cualquier regla CSS, por lo tanto, el ejemplo de Trident también funcionará aquí:

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

Esto se muestra de la siguiente manera en Chrome 26 en OS X:

Esto se muestra de la siguiente manera en Chrome 26 en OS X:

Anselmo
fuente
No hay posibilidades de diseño especiales para programas basados ​​en Gecko como Firefox.
Anselmo
2
En su respuesta, usando css, cómo ocultar la palabra "No se ha elegido ningún archivo" en la etiqueta <input type = file>. Por favor, coménteme.
user2086641
No tengo idea, lo siento
Anselm
1
fuente: tjvantoll.com/2013/04/15/…
Anselm
1
En caso de que alguien quiera jugar con estilos, agregué un jsfidde aquí: jsfiddle.net/peter_drinnan/r0gq6kw2
Peter Drinnan
26

Si está utilizando Bootstrap 3, esto funcionó para mí:

Ver 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>

Lo que produce el siguiente botón de entrada de archivo:

Botón de ejemplo

En serio, echa un vistazo a http://www.abeautifulsite.net/whipping-file-inputs-into-shape-with-bootstrap-3/

JDawg
fuente
2
Esto conserva la funcionalidad de arrastrar y soltar que es genial :), la mayoría de las respuestas no aceptan archivos caídos.
A1rPun
25

Ejemplo de trabajo aquí con soporte nativo de arrastrar y soltar: https://jsfiddle.net/j40xvkb3/

Al diseñar una entrada de archivo, no debe romper ninguna interacción nativa que proporcione la entrada .

El display: noneenfoque rompe el soporte nativo de arrastrar y soltar.

Para no romper nada, debe usar el opacity: 0enfoque para la entrada y colocarlo usando un patrón relativo / absoluto en un contenedor.

Con esta técnica, puede diseñar fácilmente una zona de clic / soltar para el usuario, y agregar una clase personalizada en JavaScript en dragentercaso de que se actualicen los estilos y brindarle al usuario una retroalimentación para que pueda ver que puede soltar un archivo.

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;
}

Aquí hay un ejemplo de trabajo (con JS adicional para manejar dragovereventos y archivos descartados).

https://jsfiddle.net/j40xvkb3/

Espero que esto haya ayudado!

kevcha
fuente
gracias por la publicación, ¿cómo funciona esto si se agrega el atributo multiple = "multiple"
Arrastré
Te has perdido el código aquí. Hay más en el violín. Que biblioteca
ctrl-alt-delor
Solo hay algunos javascript en el violín con jQuery para mostrar los archivos que se han eliminado. Eso es todo
kevcha
Después de implementar esta solución y probarla más, tampoco parece funcionar en Edge.
ChrisA
1
Ah ok, me perdí el envoltorio con posición relativa en tu respuesta - Lo malo. Si la entrada está por debajo de las dimensiones de la pantalla, el navegador intenta desplazarse hacia ella y, al hacerlo, mueve el contenedor de desplazamiento hacia arriba de la página. Aquí hay una demostración: stackblitz.com/edit/input-file-overflow?file=style.css (simplemente no demuestra exactamente cómo la posición absoluta es la causa del comportamiento)
Tom
23

Puedo hacerlo con CSS puro usando el siguiente código. He usado bootstrap y font-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
fuente
21
 <label>
    <input type="file" />
 </label>

Puede ajustar su tipo de entrada = "archivo" dentro de una etiqueta para la entrada. Diseñe la etiqueta como desee y oculte la entrada con display: none;

JGuo
fuente
Una alternativa podría ser gist.github.com/barneycarroll/5244258 o jsfiddle.net/4cwpLvae (funciona en IE11)
surfmuggle
12

Aquí hay una solución que realmente no da estilo al <input type="file" />elemento, sino que usa un <input type="file" />elemento encima de otros elementos (que se pueden diseñar). El <input type="file" />elemento no es realmente visible, por lo tanto, la ilusión general es un control de carga de archivos con un estilo agradable.

Me encontré con este problema recientemente y, a pesar de la gran cantidad de respuestas en Stack Overflow, ninguna parecía encajar. Al final, terminé personalizando esto para tener una solución simple y elegante.

También he probado esto en Firefox, IE (11, 10 y 9), Chrome y Opera, iPad y algunos dispositivos Android.

Aquí está el enlace 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 esto ayude!!!

Satwik Nadkarny
fuente
2
Una solución ingeniosamente inteligente para estas nefastas travesuras de estilo de carga de archivos.
rmcsharry
El mejor de todos. ¡¡Perfecto!!
Karra
11

Esto es simple con jquery. Para dar un ejemplo de código de la sugerencia de Ryan con una ligera modificación.

HTML básico:

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

Asegúrese de establecer el estilo en la entrada cuando esté listo: opacity: 0 no puede configurarlo display: noneporque debe poder hacer clic en él. Pero puede colocarlo debajo del botón "nuevo" o meterlo debajo de algo más con el índice z si lo prefiere.

Configure algunos jquery para hacer clic en la entrada real cuando haga clic en la imagen.

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

Ahora tu botón está funcionando. Simplemente corte y pegue el valor cuando lo cambie.

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

Tah dah! Es posible que deba analizar el valor val () en algo más significativo, pero debería estar listo.

TLK
fuente
1
esto fallará con FF11 - razón: dado que no puede influir con precisión en el tamaño del campo de entrada (solo usando el tamaño html) y el botón (puede establecer la altura usando css), si su campo de entrada visible es más grande de lo que nos proporciona FF original, usted quedan con un área ciega muy grande - punto de vista del usuario: en la mayoría de los casos se quejará de que la carga no funciona, cuando se hace clic
Jeffz
2
Buena idea, pero esto no funcionará en IE. $ ('# # the_real_file_input'). click () activará el diálogo abierto pero el archivo no se seleccionará en un formulario y la carga fallará.
Tomás
11

Coloque el botón de subir archivo sobre su bonito botón o elemento y escóndelo.

Muy simple y funcionará en cualquier 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
fuente
8

VISIBILIDAD: TRUCO oculto

Por lo general voy por el visibility:hiddentruco

este es mi botón de estilo

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

Este es el tipo de entrada = botón de archivo. Tenga en cuenta la visibility:hiddenregla

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

Este es el bit de JavaScript para unirlos. Funciona

<script>
 $('#uploadbutton').click(function(){
    $('input[type=file]').click();
 });
 </script>
Gianluca Ghettini
fuente
1
no puede usar el método click () para activar el evento para el archivo de tipo de entrada. la mayoría del navegador no permite razones de seguridad
Mahi
incluso usando jquery? ¿Es eso correcto? ¿Cómo lo harías en su lugar?
Gianluca Ghettini
style="visibility:hidden"es demasiado largo, simplemente use hidden. Además, click()funciona para cualquier navegador y no hay una razón de seguridad muy confiable a partir de ahora y en cualquier dispositivo es la forma legítima y @Gianluca para el uso clásico de jQuerytrigger()
Thielicious
1
¡Esta es precisamente la solución que iba a agregar a esto! Funciona y puedes mostrarlo exactamente como quieras. Funciona con Chrome, intentará otros.
markthewizard1234
7

la única forma en que puedo pensar es encontrar el botón con javascript después de que se renderice y asignarle un estilo

también puedes mirar este artículo

romano m
fuente
CSS puro, sin JavaScript, funciona en todos los navegadores hasta ie7, ¡increíble!
Simon Steinberger
7
<input type="file" name="media" style="display-none" onchange="document.media.submit()">

Normalmente usaría javascript simple para personalizar la etiqueta de entrada del archivo. Un campo de entrada oculto, al hacer clic en el botón, javascript llama al campo oculto, solución simple sin ningún css o montón de jquery.

<button id="file" onclick="$('#file').click()">Upload File</button>
usuario2086641
fuente
1
no puede usar el click()método para disparar eventos para el archivo de tipo de entrada. La mayor parte del navegador no permite razones de seguridad.
Mahi
6

Aquí usamos un intervalo para activar la entrada del archivo de tipo y simplemente personalizamos ese intervalo , para que podamos agregar cualquier estilo de esta manera.

Tenga en cuenta que usamos la etiqueta de entrada con visibilidad: opción oculta y la activamos en el lapso.

.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>

Referencia

Abdallah Okasha
fuente
5

Esta es una buena manera de hacerlo con la carga de material / archivo angular. Podrías hacer lo mismo con un botón de arranque.

La nota que utilicé en <a>lugar de <button>esto permite que los eventos de clic surjan.

<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
fuente
1
Esto funciona muy bien en angular 2+. No estoy seguro de por qué se ha votado. Si usa angular, esta es la solución más simple disponible.
AndrewWhalan
4

SOLO CSS

Use esto muy simple y 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
fuente
4

Tal vez muchos abridores. Pero me gusta esto en CSS puro con botones 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
fuente
4

No se deje engañar por las "excelentes" soluciones solo para CSS que en realidad son muy específicas del navegador, o que superponen el botón con estilo en la parte superior del botón real, o que lo obligan a usar un en <label>lugar de un <button>, o cualquier otro truco . JavaScript ES necesario para que funcione para uso general. Estudie cómo lo hacen gmail y DropZone si no me cree.

Simplemente diseñe un botón normal como desee, luego llame a una función JS simple para crear y vincular un elemento de entrada oculto a su botón con estilo.

<!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 cómo el código anterior lo vuelve a vincular cada vez que el usuario elige un archivo. Esto es importante porque "onchange" solo se llama si el usuario cambia el nombre del archivo. Pero probablemente desee obtener el archivo cada vez que el usuario lo proporcione.

nube_personal
fuente
1
Para ser exactos, el labelenfoque funciona, excepto que no puede mostrar el nombre o la ruta del archivo seleccionado. Hablando necesariamente, ese es el único problema que uno necesita que JS resuelva.
Hassan Baig
4

Solución de archivos múltiples con nombre de archivo convertido

Bootstrap EJEMPLO

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 con 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 sin 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
fuente
3

Aquí hay una solución, que también muestra el nombre del archivo elegido: 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
fuente
¿Cómo mostrar únicamente el nombre del archivo y no la fakepathruta?
Hassan Baig
3

Esta semana también necesitaba personalizar el botón y mostrar el nombre del archivo seleccionado a un lado, así que después de leer algunas de las respuestas anteriores (Gracias, por cierto), se me ocurrió la siguiente implementación:

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;
    };
});

Básicamente estoy trabajando con ng-file-upload lib, Angular-sabio estoy vinculando el nombre de archivo a mi $ scope y dándole el valor inicial de 'No se ha elegido ningún archivo', también estoy vinculando la función onFileSelect () a mi alcance, así que cuando se selecciona un archivo, obtengo el nombre de archivo usando ng-upload API y lo asigno al $ scope.filename.

liron_hazan
fuente
3

Simplemente simule un clic en el <input>mediante la trigger()función al hacer clic en un estilo <div>. Creé mi propio botón a partir de a <div>y luego activé un clic en inputal hacer clic en mi <div>. Esto le permite crear su botón como quiera porque es un <div>y simula un clic en su archivo <input>. Luego úsalo display: noneen tu <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
fuente
3

La mejor manera es usar el pseudo elemento: after o: before como elemento que sobrepasa la entrada de entrada. Luego, diseñe ese pseudo elemento como desee. Le recomiendo que haga como un estilo general para todos los archivos de entrada de la siguiente manera:

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
fuente
3

La mejor manera que he encontrado es tener un input type: fileajuste en display: none. Dale un id. Cree un botón o cualquier otro elemento que desee abrir la entrada del archivo.

Luego agregue un detector de eventos en él (botón) que cuando se hace clic simula un clic en la entrada del archivo original. Como hacer clic en un botón llamado hola pero abre una ventana de archivo.

Código de ejemplo

//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
fuente
2

css puede hacer mucho aquí ... con un pequeño truco ...

<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);
}

:: referencia :: http://site-o-matic.net/?viewpost=19

-abadía

Abadía
fuente
2

He encontrado un método muy fácil para cambiar el botón de archivo a una imagen. Simplemente etiquete una imagen y colóquela encima del botón de archivo.

<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>

Al hacer clic en la imagen etiquetada, selecciona el botón de archivo.

D-Inventor
fuente
2

¡Solo este enfoque le brinda toda la flexibilidad! 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();
});

Esto oculta el botón del archivo de entrada, pero debajo del capó lo hace clic desde otro botón normal, que obviamente puede diseñar como cualquier otro botón. Esta es la única solución sin inconvenientes, aparte de un nodo DOM inútil. Gracias a display:none;, el botón de entrada no reserva ningún espacio visible en el DOM.

(Ya no sé a quién dar accesorios para esto. Pero tuve esa idea de algún lugar aquí en Stackoverflow).

codepleb
fuente