样式化input type="file"按钮

1072
如何为按钮添加样式?

<input type="file" />


我会添加我的答案,以展示我是如何做到的...但这里有一个基于Bootstrap的例子,可能会有所帮助。http://geniuscarrier.com/how-to-style-a-html-file-upload-button-in-pure-css/ - Vishnu Narang
这个元素的问题似乎是它不像其他类似的元素那样接受样式。比如 input type="submit">。我将相同的样式应用于两种输入类型,这就是我得到的结果:https://i.imgur.com/7MI1Poh.jpg。 - carloswm85
对我来说有效的方法是在输入元素上方放置一个 div 并将 div 样式设置为所需样式。然后将输入元素的不透明度设置为 0 并将其大小设置为与 div 相同。 - Ricardo Figueiredo
48个回答

0

如果有人仍然关心如何在没有JavaScript的情况下完成此操作,请允许我补充Josh的答案:

如何显示文件名的文本:

最简单的方法是将两个元素都设置为position:relative,给标签一个更高的z-index,并给输入文件负边距,直到标签文本位于您想要的位置。不要在输入上使用display:none!

示例

input[type="file"] {
  position:relative;
  z-index:1;
  margin-left:-90px;
}

.custom-file-upload {
  border: 1px solid #ccc;
  display: inline-block;
  padding: 6px 12px;
  cursor: pointer;
  position:relative;
  z-index:2;
  background:white;

}

我真的很想要像这样维护文本,但对我来说这不起作用,FF和Chrome仍然显示标准的灰色按钮在左边(如果没有显示出来,它会看起来相当不错)。IE 11根本不喜欢它。 - dading84
是的,很多人想用纯CSS来实现这个。但它需要在用户代理之间具有鲁棒性,而事实并非如此。 - Hassan Baig

0
我发现这种方法最简单、最轻量级。
以下是工作示例: http://codepen.io/c3zar22/pen/QNoYXN 以下是解释:
  • 这将是标记:

    <label for="attach-project-file">
        <span id="remove-project-file" class="close">x</span>
        <div class="filename" id="attached-project-file">点击选择文件</div>
    </label>
    <input id="attach-project-file" type="file">
    
  • 以这种方式以hacky的方式隐藏输入:

    #attach-project-file {
        width: 0.1px;
        height: 0.1px;
        opacity: 0;
        overflow: hidden;
        position: absolute;
        z-index: -1;
    }
    
  • 样式相应的标签

    [for="attach-project-file"] {
        /* 在此处添加您的样式 */
    }
    
  • 样式“删除文件”按钮

    .close {
        font-size: 16px;
        padding: 10px;
        position: absolute;
        top: 0;
        right: 0;
        cursor: pointer;
        font-style: normal;
    }
    
  • .filename元素将用于显示所选文件

  • 下面是需要注释的JS代码(使用jQuery)才能使其正常工作:

    var $attach = $('#attach-project-file'),
        $remove = $('#remove-project-file'),
        $name = $('#attached-project-file');
    
    // 最初隐藏删除按钮
    $remove.hide();
    
    // 当文件输入已更改时执行此操作
    // 即:已选择文件
    $attach.on('change', function() {
        var val = $(this).val();
        if (val !== '') {
            // 如果值不为空
    
            // 将文件名显示为文本
            // hide/text/fadeIn 在更改文本时创建了一个不错的效果
            $name
                .hide()
                .text(val)
                .fadeIn();
    
            // 显示删除按钮
            $remove.fadeIn();
        } else {
            // 如果值为空,表示文件已被删除
    
            // 显示默认文本
            $name
                .hide()
                .text('点击选择文件')
                .fadeIn();
    
            // 隐藏删除按钮
            $remove.fadeOut();
        }
    });
    
    // 单击删除按钮时删除所选文件
    // 防止单击冒泡到父标签并触发文件选择
    $remove.on('click', function(e) {
        e.preventDefault();
        e.stopPropagation();
    
        $attach
            .val('')
            .change(); // 触发更改事件
    });
    

0

自动检测input[file]并进行样式设置的jquery版本teshguru脚本

<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<style>
#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;
  }
</style>
<script type="text/javascript">
$(document).ready(function()
{
    $('input[type=file]').each(function()
    {
        $(this).attr('onchange',"sub(this)");
        $('<div id="yourBtn" onclick="getFile()">click to upload a file</div>').insertBefore(this);
        $(this).wrapAll('<div style="height: 0px;width: 0px; overflow:hidden;"></div>');
    });
});
 function getFile(){
   $('input[type=file]').click();
 }
 function sub(obj){
    var file = obj.value;
    var fileName = file.split("\\");
    document.getElementById("yourBtn").innerHTML = fileName[fileName.length-1];
 }
</script>
</head>
<body>
<?php 
    var_dump($_FILES);
?>
<center>
<form action="" method="post" enctype="multipart/form-data" name="myForm">

<input id="upfile" name="file" type="file" value="upload"/>
<input type="submit" value='submit' >
</form>
</center>
</body>
</html>

0
一个快速而粗糙的方法是将标签设置为按钮,并将位置设置为绝对定位,这样它就会浮动在原始按钮上方,您仍然可以看到文件名。不过,我正在考虑一个移动解决方案。

0
一个非常聪明的解决方案,使用jQuery在所有旧浏览器和新浏览器中都能工作,我在这里找到了链接。 它处理了所有样式和click()问题,使用实际的文件浏览按钮。 我制作了一个纯JavaScript版本:fiddle 这个解决方案非常简单而且巧妙:将文件输入框设置为不可见,并使用一小段代码将其放置在鼠标光标下方。
<div class="inp_field_12" onmousemove="file_ho(event,this,1)"><span>browse</span>
    <input id="file_1" name="file_1" type="file" value="" onchange="file_ch(1)">
</div>
<div id="result_1" class="result"></div>
<script>
    function file_ho(e, o, a) {
        e = window.event || e;
        var x = 0,
        y = 0;
        if (o.offsetParent) {
            do {
            x += o.offsetLeft;
            y += o.offsetTop;
            } while (o = o.offsetParent);
        }
    var x1 = e.clientX || window.event.clientX;
    var y1 = e.clientY || window.event.clientY;
    var le = 100 - (x1 - x);
    var to = 10 - (y1 - y);
    document.getElementById('file_' + a).style.marginRight = le + 'px';
    document.getElementById('file_' + a).style.marginTop = -to + 'px';
    }
</script>
<style>
    .inp_field_12 {
        position:relative;
        overflow:hidden;
        float: left;
        width: 130px;
        height: 30px;
        background: orange;
    }
    .inp_field_12 span {
        position: absolute;
        width: 130px;
        font-family:'Calibri', 'Trebuchet MS', sans-serif;
        font-size:17px;
        line-height:27px;
        text-align:center;
        color:#555;
    }
    .inp_field_12 input[type='file'] {
        cursor:pointer;
        cursor:hand;
        position: absolute;
        top: 0px;
        right: 0px;
        -moz-opacity:0;
        filter:alpha(opacity=0);
        opacity: 0;
        outline: none;
        outline-style:none;
        outline-width:0;
        ie-dummy: expression(this.hideFocus=true);
    }
    .inp_field_12:hover {
        background-position:-140px -35px;
    }
    .inp_field_12:hover span {
        color:#fff;
    }
</style>

0
我找到的插件解决方案太重了,所以我自己制作了一个名为 Drolex FileStyle 的 jQuery 插件。
此插件允许您按照自己的喜好样式化文件输入字段。实际上,您可以将 div 元素样式化为看起来像是超级酷的文件输入,并且实际的文件输入会自动地覆盖在 0% 不透明度上。不需要额外的 HTML。只需在要使用 Drolex FileStyle 的页面中包含 css 和 js 文件即可!编辑 css 文件以满足您的喜好。如果您的页面没有 jQuery 库,请勿忘记添加它。如果客户端未运行 JavaScript,则文件输入将不会被 js 或 css 修改。
已测试在 Chrome 24、Firefox 18 和 Internet Explorer 9 中可用。 预计在这些版本的早期版本和其他浏览器中也可用。
下载: http://web.drolex.net/Drolex-FileStyle.zip

0

这是一个跨浏览器兼容的方法,适用于Chrome、Firefox、Safari和IE。

$(window).on('resize',function() {
 var eqw = $('input[type=text]').width();
 $('textarea').width(eqw - 32);
 $('.fileoutline').width(eqw);
}).trigger('resize');

$('.file+.file').hide();

$(".file").click(function() {
    var input = $(this).next().find('input');
    input.click();
});
$("input[id='file1']").change(function () {
 $('.file+.file').show();
 var filename = $(this).val();
 $('.filename1').html(filename);
 $('.file').find('span').html('CHANGE FILE');
});
$("input[id='file2']").change(function() {
 var filename = $(this).val();
 $('.filename2').html(filename);
 $('.file').find('span').html('CHANGE FILE');
});
 
form { width:55%;margin:0 auto;padding-left:3vw;text-align:left; }
fieldset{border:0;margin:0;padding:0;}
textarea{overflow: auto;height:25vh;resize:none;outline:none;width:93%;background:none;padding:8px 15px;display:block;text-align:left;border:1px solid #000;margin:0;color:#000;font:700 0.85em/2.2 'Futura Book',Arial,sans-serif;}
input:focus{outline:none;}
input[type=text]{font-weight:700;font-size:0.85em;line-height:2.2;background:none;text-align:left;letter-spacing:0.02em;height:33px;display:block;width:100%;border:none;border-bottom:1px solid #000;margin:0 0 28px;color:#000;}
input:focus{outline:0;}
.fileoutline { width:100%;margin:25px auto 0px;left:0;right:0;height:40px;border:1px solid #000;position:relative; }
input[type=file] { -webkit-appearance: none;-moz-appearance:none;appearance: none;opacity:0;position:relative;width:100%;height:35px;font-weight:700;font-size:0.5em;line-height:28px;letter-spacing:0.2em;position: absolute;left: 0;top: 0;height: 100%;z-index:10; }
.file,.filename1,.filename2,#submit { font-size:10px;letter-spacing:0.02em;text-transform:uppercase;color:#ffffff;text-align:center;width:35%;}
.file,.filename1,.filename2 { font-weight:200;line-height:28px;}
.filename1,.filename2 { width:375px;overflow:hidden;top:0;text-align:right;position:absolute;display:block;height:26px;color:#000;}
.file { position:absolute;width:100px;top:6px;left:10px;background:#000;border-radius:14px; }
::-webkit-file-upload-button,::-ms-browse { width: 100%;height:25px;opacity: 0;-webkit-appearance: none;appearance: none; }
#submit{border:none;height:32px;background: #000;box-shadow:0 0 0 0.5px #fff,0 0 0 5px #000;margin:35px 0;float:right;display:block;}
<form action="" method="post" enctype="multipart/form-data">
    <input type="text" name="email" id="email" placeholder="Email address" />
    <input type="text"  type="text" name="name" id="title" placeholder="Name" />
    <textarea rows="7" cols="40" name="description" id="description" placeholder="Description"></textarea>
    <div class="fileoutline"><div class="file"><span>CHOOSE FILE</span><input type="file" name="file[]" id="file1"><div class="filename1">NO CHOSEN FILE</div></div></div>
    <div class="fileoutline"><div class="file"><span>CHOOSE FILE</span><input type="file" name="file[]" id="file2"><div class="filename2">NO CHOSEN FILE</div></div></div>
    <input type="submit" name="submit" value="Submit" id="submit">
</form>


0

最近的建议是同时使用[type="file"][type="file"]::file-selector-button,这是很好的提示,但解决方案针对的是站点中的每个文件输入,而不仅仅是手头的元素。

要隐藏所选文本(这就是我要找的),唯一需要调整的属性是输入框和按钮的宽度(它们应该匹配)。

要仅针对一部分文件输入进行定位,请在<input>元素上设置自定义类(例如class="custom-fileinput"),然后在选择器构造中使用此类。

对于我的需求,为了隐藏所选文件文本,我最终使用了以下CSS:

.custom-fileinput, .custom-fileinput::file-selector-button {
    width: 12em;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接