跨浏览器自定义样式的file uploadbutton

我试图设置一个file uploadbutton到我的个人喜好,但我找不到任何真正坚实的方法来做到这一点,没有JS。 我还发现了 另外 两个关于这个问题的问题,但是那里的答案要么是JavaScript,要么是Quirksmode的方法 。

这个Quirksmode的方法的主要问题是文件button仍然会有浏览器定义的尺寸,所以它不会自动调整为放在它下面的button。 我已经做了一些代码,基于它,但它将占用文件button通常会占用的空间,所以它根本不会像我想要的那样填充父div。

HTML:

<div class="myLabel"> <input type="file"/> <span>My Label</span> </div> 

CSS:

 .myLabel { position: relative; } .myLabel input { position: absolute; z-index: 2; opacity: 0; width: 100%; height: 100%; } 

这个小提琴演示了这种方法是相当有缺陷的。 在Chrome中,点击!! 下面的第二个演示button无论如何都会打开文件对话框,而且在所有其他浏览器中,文件button并不占用button的正确区域。

有没有更强大的方式来设置file uploadbutton的风格,没有任何JavaScript,最好使用尽可能less的'hacky'编码(因为黑客通常会带来其他问题,例如小提琴中的问题)?

我发布这个,因为(令我惊讶)没有其他地方,我可以find推荐这个。

有一个非常简单的方法来做到这一点,而不会限制你浏览器定义的input尺寸。 只需在隐藏file uploadbutton周围使用<label>标签即可。 这允许在样式中比通过webkit的内置样式允许的样式更自由[1]

标签标签是为了将其上的任何点击事件直接指向子input[2] ,因此使用它,您不再需要任何JavaScript将click事件指向inputbutton。 你会使用像这样的东西:

 label.myLabel input[type="file"] { position: fixed; top: -1000px; } /***** Example custom styling *****/ .myLabel { border: 2px solid #AAA; border-radius: 4px; padding: 2px 5px; margin: 2px; background: #DDD; display: inline-block; } .myLabel:hover { background: #CCC; } .myLabel:active { background: #CCF; } .myLabel :invalid + span { color: #A44; } .myLabel :valid + span { color: #4A4; } 
 <label class="myLabel"> <input type="file" required/> <span>My Label</span> </label> 

请在下面find适用于所有浏览器的方法。 基本上我把input放在图像上面。 我使用字体大小,所以用户总是点击上传button。

 .myFile { position: relative; overflow: hidden; float: left; clear: left; } .myFile input[type="file"] { display: block; position: absolute; top: 0; right: 0; opacity: 0; font-size: 100px; filter: alpha(opacity=0); cursor: pointer; } 
 <label class="myFile"> <img src="http://wscont1.apps.microsoft.com/winstore/1x/c37a9d99-6698-4339-acf3-c01daa75fb65/Icon.13385.png" alt="" /> <input type="file" /> </label> 

最好的例子是这个,没有隐藏,没有jQuery,这是完全纯粹的CSS

http://css-tricks.com/snippets/css/custom-file-input-styling-webkitblink/

 .custom-file-input::-webkit-file-upload-button { visibility: hidden; } .custom-file-input::before { content: 'Select some files'; display: inline-block; background: -webkit-linear-gradient(top, #f9f9f9, #e3e3e3); border: 1px solid #999; border-radius: 3px; padding: 5px 8px; outline: none; white-space: nowrap; -webkit-user-select: none; cursor: pointer; text-shadow: 1px 1px #fff; font-weight: 700; font-size: 10pt; } .custom-file-input:hover::before { border-color: black; } .custom-file-input:active::before { background: -webkit-linear-gradient(top, #e3e3e3, #f9f9f9); } 
 <input type="file" class="custom-file-input"> 

这似乎很好地照顾生意。 一个小提琴在这里:

HTML

 <label for="upload-file">A proper input label</label> <div class="upload-button"> <div class="upload-cover"> Upload text or whatevers </div> <!-- this is later in the source so it'll be "on top" --> <input name="upload-file" type="file" /> </div> <!-- .upload-button --> 

CSS

 /* first things first - get your box-model straight*/ *, *:before, *:after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } label { /* just positioning */ float: left; margin-bottom: .5em; } .upload-button { /* key */ position: relative; overflow: hidden; /* just positioning */ float: left; clear: left; } .upload-cover { /* basically just style this however you want - the overlaying file upload should spread out and fill whatever you turn this into */ background-color: gray; text-align: center; padding: .5em 1em; border-radius: 2em; border: 5px solid rgba(0,0,0,.1); cursor: pointer; } .upload-button input[type="file"] { display: block; position: absolute; top: 0; left: 0; margin-left: -75px; /* gets that button with no-pointer-cursor off to the left and out of the way */ width: 200%; /* over compensates for the above - I would use calc or sass math if not here*/ height: 100%; opacity: .2; /* left this here so you could see. Make it 0 */ cursor: pointer; border: 1px solid red; } .upload-button:hover .upload-cover { background-color: #f06; } 

任何简单的方法来覆盖所有的文件input只是风格你的input[types=button],并把它放在全球把文件input到button:

 $(document).ready(function() { $("input[type=file]").each(function () { var thisInput$ = $(this); var newElement = $("<input type='button' value='Choose File' />"); newElement.click(function() { thisInput$.click(); }); thisInput$.after(newElement); thisInput$.hide(); }); }); 

下面是我从http://cssdeck.com/labs/beautiful-flat-buttons获得的一些示例buttonCSS:;

 input[type=button] { position: relative; vertical-align: top; width: 100%; height: 60px; padding: 0; font-size: 22px; color:white; text-align: center; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); background: #454545; border: 0; border-bottom: 2px solid #2f2e2e; cursor: pointer; -webkit-box-shadow: inset 0 -2px #2f2e2e; box-shadow: inset 0 -2px #2f2e2e; } input[type=button]:active { top: 1px; outline: none; -webkit-box-shadow: none; box-shadow: none; } 

我刚刚遇到了这个问题,并为您正在使用Angular的人写了一个解决scheme。 您可以编写一个由容器,button和input元素组成的自定义指令。 使用CSS,然后将input放置在自定义button上,但不透明度为0.您将容器高度和宽度设置为button的偏移宽度和高度,并将input的高度和宽度设置为容器的100%。

指令

 angular.module('myCoolApp') .directive('fileButton', function () { return { templateUrl: 'components/directives/fileButton/fileButton.html', restrict: 'E', link: function (scope, element, attributes) { var container = angular.element('.file-upload-container'); var button = angular.element('.file-upload-button'); container.css({ position: 'relative', overflow: 'hidden', width: button.offsetWidth, height: button.offsetHeight }) } }; }); 

如果你使用的是玉,那么就是一个玉器模板

 div(class="file-upload-container") button(class="file-upload-button") + input#file-upload(class="file-upload-input", type='file', onchange="doSomethingWhenFileIsSelected()") 

如果您使用的是HTML,则使用相同的模板

 <div class="file-upload-container"> <button class="file-upload-button"></button> <input class="file-upload-input" id="file-upload" type="file" onchange="doSomethingWhenFileIsSelected()" /> </div> 

css

 .file-upload-button { margin-top: 40px; padding: 30px; border: 1px solid black; height: 100px; width: 100px; background: transparent; font-size: 66px; padding-top: 0px; border-radius: 5px; border: 2px solid rgb(255, 228, 0); color: rgb(255, 228, 0); } .file-upload-input { position: absolute; top: 0; left: 0; z-index: 2; width: 100%; height: 100%; opacity: 0; cursor: pointer; } 

如果您正在使用Bootstrap和LESS,也可以轻松地设置标签的样式:

 label { .btn(); .btn-primary(); > input[type="file"] { display: none; } }