Si estás leyendo esto es porque estás intentando dar estilo a tu flamante formulario, al borde de la desesperación, con la hoja de estilos css abierta e inspeccionando el botón de subir archivos de contact form 7. Respira hondo y hazte una tila que aquí te vamos a dar la solución. ?
Pasamos de darle estilo al input type=”file”
Este botón va a tener un estilo distinto en función del navegador que estemos utilizando; va a pasar olímpicamente de tu hoja de estilo y va a incorporar la suya como una buena armadura, con yelmo y todo.
El caso es que no se puede cambiar el estilo del input type=”file”. Por lo que la solución es ocultarlo para hacer que sea un label el que haga las veces de input. Esto es posible gracias a la funcionalidad de este input. Si fuera una caja de texto el label lo único que haría sería activarla para escribir dentro; sin embargo, en los input type=”file” estas etiquetas provocan la misma funcionalidad. Cosa que aprovecharemos a nuestro favor.
Por tanto, pasamos a mil por hora del input y vamos a ocultarlo a machete:
input[type=”file”]#nuestroinput { width: 0.1px; height: 0.1px; opacity: 0; overflow: hidden; position: absolute; z-index: -1; }
Y a partir de aquí, procedemos a darle estilo a nuestro label, por ejemplo:
label[for=" nuestroinput"] { font-size: 14px; font-weight: 600; color: #fff; background-color: #106BA0; display: inline-block; transition: all .5s; cursor: pointer; padding: 15px 40px !important; text-transform: uppercase; width: fit-content; text-align: center; }
Problemas de usabilidad
Con esto tendríamos resuelta la papeleta del input feo, pero surge un problema que tiene que ver con la usabilidad. Normalmente, cuando subimos un archivo, nos aparece el nombre del archivo (como en la imagen de abajo).
Al perder el input de vista, sólo contamos con el nombre del label para ofrecer información de algún tipo al usuario. Por ello, os sugerimos utilizar un pequeño codiguito que insertaremos antes del cierre de la etiqueta body.
<script type="application/javascript"> jQuery('input[type=file]').change(function(){ var filename = jQuery(this).val().split('\\').pop(); var idname = jQuery(this).attr('id'); console.log(jQuery(this)); console.log(filename); console.log(idname); jQuery('span.'+idname).next().find('span').html(filename); }); </script>
Para que este código funcione tendremos que envolver el input[type=”file”] con una etiqueta span, que va a tener una clase CSS con el mismo nombre que la id del input[type=”file”] y, por tanto, que el for del label, cuyo texto también tendrá que estar envuelto con un span.
Extra tip para Contact Form 7
Si estas trabajando en WordPress y en concreto con el plugin Contact Form 7, verás que este maravilloso plugin de WordPress trabaja con shortcodes por tanto no puedes modificar el HTML de manera directa. Sin embargo si inspeccionas el elemento input con el inspector de tu navegador, verás que Contact Form 7 envuelve automáticamente los input con etiquetas span con clases CSS propias, las cuales no podemos modificar, esto a priori puede ser una faena, pero lo vamos a jugar a nuestro favor. Lo que haremos es utilizar el nombre de esta clase CSS para el id del input[type=”file”] y para el for del label “molador”.
Buenas, tendras el codigo fuente de este ejemplo, es que no me cambia el nombre del laber por el nombre del archivo, no se si son por los span, gracias
Hola Joel, gracias por tu comentario, te dejo aquí una captura de pantalla con la estructura necesaria del código html, espero que te sirva!
Hola.
En primer lugar gracias por el aporte.
Tuve algunos problemas sobre wordpress, ya que no se porque me daba problemas la función split para separar la ruta, y quedarme solo con el nombre del archivo. Al final opte por buscar directamente el nombre en el objeto que surge del “change”.
Mi código es:
jQuery(‘input[type=file]’).change(function(e){
var filename = e.currentTarget.files[0].name
….
Con esto consegui no tener que trabajar con la ruta, y conseguir directament el nombre.
Un saludo
Buenas Santiago, muchísimas gracias por tu añadido!
Hola muy buena la idea. Yo hacia algo similar ocultando el elemento y creando uno nuevo. Este elemento nuevo lo asociaba al input utilizando un trigger con javascript. pero le problemaque tengo es que pierdo la funcionalidad de arrastrar una imagen sobre el input. pense que esto de usar el label me permitiria conservar la ventaja de arrastrar pero no fue asi. Sabes como podria hacer para mantener esa funcionalidad? Muchas gracias por todo!
Buenas Iñaki, gracias por tu comentario. Al ser tan sencillo, este truco sólo funciona haciendo click en el label, no con un drap and drop como nos comentas. Necesitaríamos estudiarlo un poco más en profundidad para resolver tu problema, sin embargo, te dejo una entrada que explica bastante bien cómo hacer lo que nos planteas:
https://css-tricks.com/drag-and-drop-file-uploading/
Un saludo!
Hola, que tal, tengo un prblema y es que creo dinamicamente con una fucnion jquery otro campo tipo file con el mismo nombre e id igual al primero, entonces solo se agrega y cambio el label al primero pero no a los que creo de manera dinamica, no les puedo cambiar el id a los otros. Como hago en ese caso ?
Hola Keisel, gracias por tu comentario.
Ahora mismo no sabría dar solución a la duda que nos planteas. Siempre que haya dos IDs iguales en la misma página el label activará el primero de ellos. Imagino que habrá que buscar otro método de selección, tendríamos que estudiarlo en profundidad.
Siento no poder darte solución :(
Hola me regalarias la imagen del boton la que tiene la flecha arriba y el css para colocarla ahi y que se vea bonita porfas
Hola David, puedes descargar una imagen similar desde esta página https://www.iconfinder.com/. Para insertarla vía css te recomiendo que uses el pseudo-elemento :before, en este caso sería el siguiente código:
label[for=”nuestroinput”]:before {
content: url(icono.png);
margin-right: 12px;
}
Muy buen tutorial!
Muchas gracias por tu comentario Juan!
como hago para quitar el texto que aparece al lado del input type=”file” “ningún archivo seleccionado”
Hola Edwin, gracias por tu comentario.
Como indicamos en el post, no hay forma de modificar el input type=”file” a través de css. Por eso lo ocultamos y en su lugar añadimos un label. Siento no poder ofrecerte la solución que buscas.
Un saludo
Se puede también, agregar un selector al span.
Seleccionar archivo
y en la función jQuery llamarlo directamente.
$(“#psTexto”).html(‘ ‘ + filename);
*span id=”psTexto”*
*i class=”fas fa-star”* */i*
Seleccionar archivo
*/span*
Cambiar * por
Gracias por el aporte LM, un saludo
Gracias Gonzalo!! Me ha ayudado mucho. He tardado un rato en darme cuenta de que eras mi compañero y estaba leyendo en nuestra web. Cosas de la concentración. Que maravilla, jajaja.
Hahaha Hola Alejandro, lo primero gracias por tu comentario. Me alegra haberte sido de ayuda, cualquier duda que que te surja, estamos cerca.
Un saludo.
gracias amigo me ayudo mucho
Gracias por tu comentario, un saludo.
Gracias!
Gracias a ti por tu comentario Inti. Saludos.
Eres una rata muerta de hambre, porque si vas a explicar algo, explicalo bien y comparte el codigo. Dios, que asco de pagina, suicidate ya basura asquerosa.
Hola Rafa, lo primero gracias por tu feedback, siento mucho que el post no haya sido de tu agrado. Los códigos los verás más arriba.
Sobre lo demás, comentarte que las palabras “explícalo”, “código”, “página” y “suicídate” llevan tilde.
Un cordial saludo.
Hola Gonzalo, muchas gracias por el post, me ha servido de mucho! :) Lo único que no soy capaz de cambiar el nombre una vez que se ha adjuntado el archivo y salga el nombre del mismo. Además que lo tengo como un +, para añadir y no quedaría bien meter de repente el texto del nombre del archivo subido. ¿Es posible que al adjuntar el archivo, aparezca un mensaje debajo en plan “Archivo adjuntado”? Ya que no consigo que me funcione el script :S
Estoy usando Contact Form7 en WordPress.
Muchas gracias! :)
Muchas Gracias Me sirvip Mucho
Si me funciono bastante bien ¡Muchas gracias! Lo hice en un WordPress con Contact Form 7. También lo ejecute en CodePen y sin problemas por si alguien quiere revisarlo.
En CF7 lo monté así:
[file curriculum id:upload-file filetypes:pdf|doc|docx limit:3mb]Cargar C.V.
Igual por si alguien lo necesita, le puede añadir los span y las clases de forma directa.
Creo que no cargó todo el código del CF7, pero lo añadí como comentario en el Codepen
hola, como podría hacer para colocar otro texto diferente al “seleccionar archivo” en el input type=”file” por ejemplo que diga “subir foto” en vez de “seleccionar archivo”?
qué asco de página, no puedo ni moverme en ella
Hola Gonzalo, muchas gracias por la pista que me diste de ocultar el input tipo file.
Estuve haciendo pruebas y descubrí que con solo agregar el atributo de oculto desde el html es más que suficiente y no hace falta agregar el estilo css para ocultar el input
Buscar
Excelente, me ayudó bastante en mi proyecto
Maravilla!