你如何风格输入类型=“文件”按钮?

<输入类型=“文件” />


当前回答

不要被“伟大的”css解决方案所欺骗,这些解决方案实际上非常特定于浏览器,或者将样式化按钮覆盖在真正的按钮之上,或者强迫您使用<label>而不是<button>,或任何其他类似的hack。JavaScript是必要的,以使其工作为一般用途。如果你不相信我,请学习gmail和DropZone是怎么做的。

只要按你想要的样式设计一个普通的按钮,然后调用一个简单的JS函数来创建并链接一个隐藏的输入元素到你的样式按钮。

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

注意上面的代码是如何在用户每次选择一个文件后重新链接它的。这很重要,因为只有当用户更改文件名时才会调用"onchange"。但您可能希望在用户每次提供该文件时获取该文件。

其他回答

最好的方法是使用伪元素:after或:before作为显化de input的元素。然后按照您的意愿设置该伪元素的样式。我建议你为所有输入文件做一个通用的样式,如下所示:

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

你可以创建一个很棒的(未完成的)文件上传器到<button>元素或任何其他元素:

函数selectFile() { . getelementbyid (fileSelector) .click (); } 输入# fileSelector (type = "文件"){ 显示:没有; } 按钮onclick * =”()”){ 光标:指针; } <input type="file" id="fileSelector"> <按钮onclick = " selectFile ()>选择文件从计算机

不要被“伟大的”css解决方案所欺骗,这些解决方案实际上非常特定于浏览器,或者将样式化按钮覆盖在真正的按钮之上,或者强迫您使用<label>而不是<button>,或任何其他类似的hack。JavaScript是必要的,以使其工作为一般用途。如果你不相信我,请学习gmail和DropZone是怎么做的。

只要按你想要的样式设计一个普通的按钮,然后调用一个简单的JS函数来创建并链接一个隐藏的输入元素到你的样式按钮。

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

注意上面的代码是如何在用户每次选择一个文件后重新链接它的。这很重要,因为只有当用户更改文件名时才会调用"onchange"。但您可能希望在用户每次提供该文件时获取该文件。

当点击有样式的<div>时,只需使用trigger()函数模拟点击<input>。我在<div>中创建了自己的按钮,然后在点击我的<div>时触发了输入上的单击。这允许你创建你想要的按钮,因为它是一个<div>,模拟点击你的文件<input>。然后在<input>上使用display: none。

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

这些答案很好,它们都适用于非常具体的用例。也就是说,他们固执己见。

所以,这里有一个答案,它没有任何假设,但无论你如何修改它都是有效的。你可以用css改变设计,添加javascript,可能会显示一个文件名的变化,等等,它仍然会一直工作。

代码:

这里是核心css

.file-input{
  pointer-events: none;
  position: relative;
  overflow: hidden;
}
.file-input > * {
  pointer-events: none;
}
.file-input > input[type="file"]{
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  opacity: 0;
  pointer-events: all;
  cursor: pointer;
  height: 100%;
  width: 100%;
}

和核心html:

<div class="file-input">
  <input type="file"/>
</div>

如您所见,我们强制将.file-input元素或其任何子元素上发生的任何指针事件(单击)代理到文件输入。这是因为文件输入的位置是绝对的,并且总是占用容器的宽度/高度。因此,您可以根据自己的需要进行定制。样式包装成一个按钮,使用一些js显示文件名选择,等等,没有什么会打破,只要上述核心代码保持不变。

正如你将在演示中看到的,我已经添加了一个带有文本“Select file”的span和一个带有额外样式的类来设置.file-input div的样式。这应该是任何人想要创建自定义文件上传元素的规范起点。

演示:JSFIDDLE