用于文件上传按钮的跨浏览器自定义样式

Joe*_*e50 104 html css file-io cross-browser

我正在尝试根据个人喜好设置文件上传按钮的样式,但如果没有JS,我找不到任何真正可行的方法.我确实找到 关于这个主题的另外两个问题,但那里的答案要么涉及JavaScript,要么建议采用Quirksmode的方法.

这个Quirksmode方法的主要问题是文件按钮仍然具有浏览器定义的尺寸,因此它不会自动调整为用作放置在它下面的按钮的任何东西.我已经制作了一些基于它的代码,但它只占用了文件按钮通常占用的空间,所以它根本不会像我想要的那样填充父div.

HTML:

<div class="myLabel">
    <input type="file"/>
    <span>My Label</span>
</div>
Run Code Online (Sandbox Code Playgroud)

CSS:

.myLabel {
    position: relative;
}
.myLabel input {
    position: absolute;
    z-index: 2;
    opacity: 0;
    width: 100%;
    height: 100%;
}
Run Code Online (Sandbox Code Playgroud)

这个小提示演示了这种方法是如何存在严重缺陷的.在Chrome中,单击!!下面的第二个演示按钮将打开文件对话框,但在所有其他浏览器中,文件按钮不会占用按钮的正确区域.

有没有更坚实的方式来设置文件上传按钮的样式,没有任何JavaScript,并且最好使用尽可能少的"hacky"编码(因为黑客通常带来其他问题,例如小提琴中的那些)?

Joe*_*e50 280

我发布这个是因为(令我惊讶的是)没有其他我能找到的地方推荐这个.

有一种非常简单的方法可以做到这一点,而不会限制您使用浏览器定义的输入维度.只需使用<label>隐藏文件上传按钮周围的标签即可.与通过webkit的内置样式[1]允许的样式相比,这样可以更加自由地进行样式设置.

标签标签的确切目的是将其上的任何点击事件指向子输入[2],因此使用它,您将不再需要任何JavaScript将点击事件指向您的输入按钮.您将使用以下内容:

label.myLabel input[type="file"] {
    position:absolute;
    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;
}
Run Code Online (Sandbox Code Playgroud)
<label class="myLabel">
    <input type="file" required/>
    <span>My Label</span>
</label>
Run Code Online (Sandbox Code Playgroud)

我用一个固定的位置,以隐藏输入,使得即使在古代版本的Internet Explorer它的工作(仿真IE8-拒绝在工作visibility:hiddendisplay:none文件输入).我已经在模拟的IE7及以上版本中进行了测试,并且它运行良好.


  1. 遗憾的是,您不能使用<button>s inside <label>标签,因此您必须自己定义按钮的样式.对我而言,这是这种方法的唯一缺点.
  2. 如果for属性被定义,它的值被用来触发与相同的输入id作为for所述属性<label>.

  • 这太棒了.至于`label`元素内的按钮,它非常好.它们可以包含任何措辞内容(包括"输入"和"按钮"),只要它没有被其他东西标记或是另一个标签.资料来源:https://html.spec.whatwg.org/multipage/forms.html#the-label-element (8认同)
  • 这对我很有用,唯一的问题是在选择文件后,它实际上并不显示已选择文件.有没有办法显示一个文件被选中的指标? (3认同)
  • @regisbsb我刚刚在IE7和8中测试了[这个jsfiddle](http://jsfiddle.net/run4s/1/),确实IE7似乎不起作用了(不再?),但IE8工作得很好.什么是不适合你的代码?PS:在撰写本文时,[只有0.08%的人](http://caniuse.com/usage_table.php)使用IE7,所以我不担心.无论如何,IE8应该仍然可以正常工作,所以你能给我发一个jsfiddle/jsbin/etc的代码链接在IE8中不起作用吗? (2认同)
  • 这就是用CSS中的`:valid`和`:invalid`代码完成的.或者,您可以使用[this](http://jsbin.com/kedajupuwa/1/edit?html,css,output)之类的内容更改文本.但是,这种方式无法显示所选文件的确切内容. (2认同)

reg*_*bsb 10

请在下面找到适用于所有浏览器的方法.基本上我把输入放在图像的顶部.我使用font-size使其变得很大,因此用户总是单击上传按钮.

.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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


小智 9

最好的例子就是这个,没有隐藏,没有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);
}
Run Code Online (Sandbox Code Playgroud)
<input type="file" class="custom-file-input">
Run Code Online (Sandbox Code Playgroud)

  • 此外,它在 Firefox 中根本不起作用。因为 Firefox 基于 Gecko,而不是 webkit。 (6认同)
  • 这会导致IE和Chrome中的行为完全不同.是不是想让它与浏览器无关? (2认同)