Contenido

Dando estilo a los elementos input type=file

10 Sep

+ 11

Eduo, me avisa del nuevo artículo de Shauninman en el que nos enseña como decorar con CSS y Javascript estos elementos tan descuidados.

<input type=»file» />

Los elementos file, son los más descuidados, en cuanto a diseño, de todos los elementos <input />. Estos elementos nos permite interactuar con el sistema operativo enviando ficheros desde nuestro PC al servidor remoto. Pero el tema del diseño era algo delicado ya que no hay nada estandarizado para todos los navegadores que nos permita darle el toque estético que nos gustaría darle.

Gracias al conjunto de CSS y Javascript, podemos hacer posible esta transformación.

HTML

<label class="cabinet">
    <input type="file" class="file" />
</label>

Primero añadimos las clases necesarias para que se apliquen los estilos.

CSS

.SI-FILES-STYLIZED label.cabinet
{
    width: 79px;
    height: 22px;
    background: url(btn-choose-file.gif) 0 0 no-repeat;

    display: block;
    overflow: hidden;
    cursor: pointer;
}

.SI-FILES-STYLIZED label.cabinet input.file
{
    position: relative;
    height: 100%;
    width: auto;
    opacity: 0;
    -moz-opacity: 0;
    filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);
}

Definimos los estilos teniendo en cuenta las clases insertadas anteriormente y la clase que nuestro script le insertará a nuestro nuevo elemento file modificado. 

Javascript

<script type="text/javascript" src="/path/to/si.files.js"></script>
	SI.Files.stylizeAll();  
//o 
	SI.Files.stylizeById('input-id');

Aplicamos el javascript para hacer que nuestro puntero siempre haga click en nuestro nuevo botón.

La magia

Desde nuestro CSS, le damos al elemento <label /> con class cabinet, la imagen que irá como background-image. Por otro lado hacemos que la opacidad de nuestro <input type="file" /> sea 0, dejándolo invisible para los seres humanos, pero no para el navegador, que permite hacer click sobre él sin ningún tipo de problema.

Finalmente el javascript hará que nuestro puntero accione siempre nuestro elemento file.

Compatibilidad

Con IE5.5+, Firefox 1.5+, Safari 2+

[Demo][Descargar]

  • uh, no me parece TAN buena idea porque una vez que seleccionas el archivo:
    a) no hay forma de saber si el input está vacío o no
    b) no hay forma de saber qué archivo es el que elegimos
    pequeños detalles, pero es accesibilidad. yo preferiría swfupload ( http://swfupload.mammon.se/ )

  • Gran articulo, lo probaré.
    aunque la solucion que yo le daba a este problema era esta

  • Oscar: Esa solucion es similar. Depende del opacity para hacer desaparecer el original y lo reemplaza por el nuevo.

    Fael: swfupload tiene sus propios, y no pocos, problemas de accesibilidad. Esta solución asume que específicamente no te interesa ver el fichero que estas anexando (en la mayoría de los casos tampoco te sirve verlo de cualquier forma).

    Como comentaba ayer con Andrés, todo esto realmente sólo apunta al problema y es que el «input type=file» es uno de los más olvidados y desesperantes elementos. Es el que menos estilo permite, el que más varía de máquina a máquina y el que menos ha evolucionado desde el día que se inventó.

    Justo ayer comentábamos que era increíble que no haya ningún navegador mayoritario que soporte drag & drop sobre él (que debería ser natural por lo menos para Mac).

  • Gracias por la idea, sin duda la probaré a ver que tal me va.

  • @Fael, siempre puedes crear un div, y mediante innerHTML, escribir el «value» del campo file desde el evento «onchange».

    Por ejemplo, este sería el javascript:
    var fileSv = function(file,msg)
    {
    ruta = $(file).value;
    ruta_arr = ruta.split(«\\»);
    archivo = ruta_arr[ruta_arr.length-1];

    $(msg).innerHTML = «» + archivo + «»;
    }
    Esto el html:

    Y para finalizar, las css:
    .file_prev {
    padding-left: 24px;
    color: #0099CC;
    background: url(../images/icon/picture.png) 4px center no-repeat;
    }

  • Bueno, por lo que veo, no puedo escribir html…

Comentar

#

Me reservo el derecho de eliminar y/o modificar los comentarios que contengan lenguaje inapropiado, spam u otras conductas no apropiadas en una comunidad civilizada. Si tu comentario no aparece, puede ser que akismet lo haya capturado, cada día lo reviso y lo coloco en su lugar. Siento las molestias.