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