更改<input type="file">的光标类型

96

简单的问题...如何改变文件输入类型的光标类型?

我尝试了以下方法:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <style>
            input[type="file"] {
              cursor: pointer;
            }
        </style>
    </head>
    <body>
        <input type="file">
    </body>
</html>

由于某些原因,它不会运作。


2
这个答案可行:https://dev59.com/QnI_5IYBdhLWcg3wEe1u#8667296 - ErJab
1
这个答案适用于所有主流浏览器,且完美地解决了问题。 - awe
1
这个答案解释了如何对文件输入应用任何类型的自定义样式,而不必使用“hacky”CSS。 - Joeytje50
接受的答案已更改以反映现代技术。 - Tisch
`.file-label{ left:0px; position:relative; cursor: pointer;}` <label class="file-label" ng-if="!$ctrl.multiple" for="file">{{'BUTTON.CHOOSEFILE' | translate}}</label>在Chrome和IE上运行得非常好。 - jsPlayer
如下所述,font-size: 0; 就是我所需的全部。 - pjdavis
14个回答

70

虽然这是一篇旧帖子,但谷歌的搜索结果将其带了上来...我刚刚发现了 Chrome 的部分解决方案(不涉及 Flash、JavaScript、额外的 DOM 操作和 overflow hidden)

  • Firefox 已经修复了这个问题
  • Safari(目前为止是7)和 Chrome 的行为并不完全相同
  • Safari(Mac 上的7)对我来说根本无法使用
  • Chrome(可能还有 Opera,因为它现在是基于 Webkit)可以使用 ::webkit-file-upload-button 伪类

.

input[type=file], /* FF, IE7+, chrome (except button) */
input[type=file]::-webkit-file-upload-button { /* chromes and blink button */
    cursor: pointer; 
}

问题在于通常按钮不会继承光标属性(?),但是其他的input[type=file]字段会。这就是为什么Chrome除了按钮之外都有指针的原因。


59

cursor:pointer 在输入文件上不起作用,仅因默认按钮而已。没有特殊原因。您需要使用此代码移除其外观,注意 font-size:0

input[type='file']{
    opacity: 0;
    cursor: pointer;
    width: 24px;
    height: 24px;
    font-size: 0;
    position: absolute;
}
<input type="file">
<img width="24" height="24" title="" alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAADs0lEQVR42rWVa2iOYRjH9+zd+dw2oWaGwkjzRY5flDC1nBaxsTnVYkaWc8oHoZalETWHsVGkZo0yIyEmGzkWpZhDbBhmxE7v63fp/0j7YGq89e/+XfdzuJ7/dV/3/Tp+//nndHdD2o4RIQHBnilgIPL3+XytjuO0MkZ4O3zllevve3uUYMaulDxeePL0mruNXeaTmJ/IfMlfJZhekBLv+PuNBEPRq8427wN/jxPmeJxM4seoAH0yF+g9WonmVOTfK+o2weTNyZ6w2KC9fNFuQtz7AuF0+DV8Ft4GZ6OvxPXE7xlLGZ8wF4CLK39MMLNwZDoPJPPAHcJwOAiOhp/Ct+Ba3d9J/I3YEjUzTmNuNuwHd8DtcAg8FK4ica2jeuYyFKM4cyB1aGEz0BoUYw6QLWoEakLLUY25UOl+foSubaB8O1wHmWS+R+YadUojbEmi4WjYo4Rv5SCWMdic2LzYEjfBAXAynImDI78nqOXCWcIk2KsHgmB/+ARs6/BE8UDGuYw5KmkbfA5O1QckwfNJUOqWaCnDdVRuL5WsXO1oobrIXpYgJ9W6N9VKgdZRjmreUwqPReYgg7mjroMlZL5K5v2E8XA/2JKshc9okfui78QNxLaYdxgteQkcCVfCW+HX8LiuDqwFr6Ey1B/1Rm/QMJSP8lCkus4cNNheQbt032G5s4+qR8PRIhwccB1kk/kmmSsIB8GdcDVfkEbyU/B45ntZt3Ctg9icfGQ8zdwW+AY8WG36UA7m8XyZm2CxbrqkElmC2/AE+DKcCMeaC/W8nUUtWthVcJ0WtlXNMhmeS4LjXbvoolmF22ErwSh4BTzTuguFaRPadm9iXG0NAFfA1hQvtEaT4CwSHHLXYBHDLWQJ4lXnp2ifuuUYStRC2zPB6LwdYagQzdImeydNtaOFNTjoOsiSTXuot3q9BW6Bc+E62Hb7EOJQ4irGYsY5zO2E4+FmrYE5GA0vsJPWTbBMtbZWG6AyeJXgkxbTDsKXWoPBKp3tn2DY0c5vhp/BY7TIv9p0idrUNlAfnS3uUW6J3uqsaZM8OnPsQAyRfLr3g1rd2rTYdZAjB0WyGadzphHuBQfqhd+I39jX6p5OObCjIspaWQ7NQQ4OitwEm7hQRMYvfv/gx/vM2UIS7HFLtFG7tUUd1C67Udqdn63HVYpoufmuebtuR/kXlS9cu3w7H3zBTWB/laOxlqDNlABbu37VUWw9bn+lIdrBnxljbMPpno/6w7Hj/B383E4GEjzq9k+/p78fan0xNyGwEGgAAAAASUVORK5CYII=" />

它可以在Chrome、Firefox和IE上完美地运行。


1
这在我的Chrome浏览器版本37.0.2062.94上不起作用。 - dshap
3
这并没有真正解决问题,因为输入按钮仍然位于图像的左上角,光标在悬停时仍会恢复默认状态。您可以通过使用开发工具来取消不透明度样式来确认这一点。 - Emile Bergeron
2
请添加 text-indent: -100px; 以正确隐藏按钮左上角的光标。 - Gimi
你太棒了!!!它像魔法一样运行,谢谢你。特别是字体大小:0像素; - Kamlesh
全能的上帝 @Lewis - Ishan Patel
显示剩余2条评论

40

它在不同的浏览器中的工作方式有所不同。我猜这是因为文件输入类型相当特殊。

你使用哪个浏览器/版本?

我知道IE6不支持在样式中指定类型。

不同浏览器中的工作方式

IE7+

完美地工作。

FireFox

问题已经被修复,现在完美地工作。请参见此问题的错误报告
在3.5版本中根本不起作用。

Chrome和Safari (行为相同)

使用箭头覆盖按钮,但是在其余部分上使用定义的光标。

Opera

完美地工作。


请注意,有几种使用不同技术绕过此问题的解决方法。BjarkeCK的答案是我喜欢的一种优雅的解决方案,并且适用于所有主要浏览器。


1
问题不仅仅来自于[type]的行为。 - enguerran
@enguerran:你说得对。只有IE6存在这个问题。其他浏览器的问题仅与为<input type="file"/>元素设置光标样式有关,无论是在全局样式部分/文件中设置还是直接在HTML标签上设置。 - awe
1
好烦啊,感觉应该有一些高级的 WebKit CSS3 规则来覆盖 Chrome 不支持的功能。如果你第一次使用 CSS 时 IE 做了 Chrome 不支持的事情,那真是太遗憾了。 - Rooster
这个答案不是很正确。请看我下面的回答:https://dev59.com/QnI_5IYBdhLWcg3wEe1u#24488438。 - Lewis
我已经更改了被接受的答案,以更准确地反映当前可用的解决方案。自那时以来,情况已经发生了很大变化。 - Tisch

34
我今天遇到了这个问题,并通过以下方式解决:
/* Chrome/Safari and web-kit-based browsers 
   (if it doesn't work, try maybe also on the parent/wrapper)
*/
::-webkit-file-upload-button {
    cursor:pointer;
}

/* IE11 (if it doesn't work, try maybe also on the parent/wrapper) */
input[type=file] {
    cursor:pointer;
}

看起来它运行正常 :-)


12

如果您想要强制光标变成手形以便将其放在图片上,这是一个

简单的方法,并且它在所有浏览器中都可以工作:

HTML:

<img src="/images/uploadButton.png" id="upfile1" style="cursor:pointer" />
<input type="file" id="file1"  name="file1" style="display:none" />

JQuery:

$("#upfile1").click(function () {
     $("#file1").trigger('click');
});

您可以按任意按钮上传文件,此时您将看到一个指针光标。


在Chrome和Opera中,只有在填充区域上光标才会变成指针,如果使用display:block;,因此对于这些浏览器,您应该进行以下操作:

<input type="file" id="file1"  name="file1" style="display:block; padding:29px 0 0 0;" />

2
不适用于Chrome和Opera:http://jsfiddle.net/LWHbs/1/。出于安全原因,实际上任何浏览器都不应该使用它,但是我们还是这样做了。 - ThatGuy
8
由于这在Chrome和Opera中不起作用,因此您应该从标题文本中删除“适用于所有浏览器”! - awe
2
@awe 这是该主题中最简单的方法,显然比“火狐-根本不起作用”要好。 - ParPar
1
我在Mac上的Chrome浏览器中尝试了这个,它可以工作而不需要填充显示块移动。只需使用jQuery和display:none即可满足Chrome在Mac v22上的要求。如果Windows上的Chrome也可以工作,您应该进行更新。 - Kim Stacks
@ParPar:我刚刚解释了CSS样式在不同浏览器中的实现方式。我并没有说使用变通方法无法提出替代方案。我的回答被高度赞同并被选为采纳的答案,这不是我的错...我点赞了BjarkeCK的答案,它可以在所有浏览器中使用相同的代码来实现。 - awe
显示剩余5条评论

7

我做了如下操作:

<li>file<input id="file_inp" type="file" /></li>

对于li:

li { /*...*/ position:relative; overflow:hidden; /*...*/ }

对于输入:

input#file_inp { 
    /*...*/ 
    position: absolute; 
    width: 400px; 
    left: -200px; 
    top:0; 
    cursor: pointer; 
    /*...*/ 
}

正如之前所提到的,光标变成了“指针”,可以在整个输入区域内使用,除了按钮以外。在大多数浏览器中,按钮位于左侧或右侧。好的!让我们给输入框设置一个巨大的宽度,然后只显示中间部分...按钮将被隐藏。整个输入框都可以被点击。

这对我来说可以使用。


这几乎是我想到的相同解决方案。不过,我将 width: 100%height: 300%top: -200% 设置了起来。这样无论父级 li 的大小如何,按钮都会在容器上方,并且整个容器仍然被输入元素覆盖。 - Jargs

3
我发现有另一种方法可以制作它。在Opera New,FF,Chrome和Safari中完美运行。不幸的是,在IE中它不能完美地工作(但对我的情况足够好)。
这个想法是将元素包装在固定大小的div中,并隐藏溢出,并设置光标:指针。然后,我们使用左填充将按钮移动到div外部。
<div class="input-file-wrap">
    <input class="file-input" type="file" />
</div>

和示例样式

.input-file-wrap {
    background: red;
    height: 33px;
    width: 240px;
    overflow: hidden;
    position: relative;
    cursor: pointer;
}

.file-input {
    width: 100%;
    height: 100%;
    opacity: 0;
    padding-left: 240px;
    margin-right: -240px;
    cursor: pointer;
}

在这里你可以找到实时例子:http://jsfiddle.net/5c5RH/2/。这个例子与IT技术有关,希望我的翻译能使内容更加通俗易懂,但不会进行解释,html标签将被保留。

2
如果你正在尝试使用Ajax上传器,那么你可以尝试一种适用于兼容浏览器(如FireFox和Chrome)的技术。它们支持在完全不可见的文件输入上触发点击事件。你可以以任何想要的方式隐藏文件输入,除了将其显示属性设置为none。在父表单上设置 { height: 0; overflow: hidden } 将起到作用。我为每个上传者使用单独的表单。
重定向自定义按钮点击事件到隐藏文件输入即可完成操作。
要使用这种技术,必须对Gecko或WebKit引擎执行navigator.userAgent检查。对于其他引擎,您必须使用旧的透明文件输入方法。

1
首先,你的代码在Internet Explorer上可以运行,但在Firefox上却不能。
其次,W3C Css标准不允许对像这样的复杂标签进行样式设置。即使是针对光标属性也是如此。
最后,请参考this page。我没有尝试过他的解决方案,所以请告诉我们它是否有效以及如何操作。

1
你指向的解决方案是一个技巧,可以隐藏文件输入,以便显示自己的外观,但保留文件输入控件提供的鼠标交互内容。这意味着鼠标指针仍然受到文件输入的影响,一点也没有帮助。我还尝试了另一种方式,使用覆盖文件输入的div上的onclick事件。这解决了光标问题,但在FireFox中,fileInput.click()方法不起作用。它实际上在IE中工作,但这对我们没有帮助... - awe
这还是现状吗?我真的无法弄清如何在“input”元素上设置自定义光标 :/ - oldboy
我发现了这个 https://css-tricks.com/snippets/css/custom-file-input-styling-webkitblink/ 和 http://wtfforms.com/ (“时代在变化”)。 - enguerran

1
Chrome也给我带来了这个问题。我尝试设置各种CSS选择器,但似乎没有什么好的解决方法。然而,我通过使用FORM元素找到了一个解决方案。
1. 给你的input[type=file] 元素命名。 2. 命名你的form元素并将input[type=file]放入其中。 3. 制作一个span,并将其放置在表单中输入框下方。这将是您的标签。 4. 使用CSS将输入框的高度设置为0px,将不透明度设置为0,这将使其不可见。 5. 将span定位绝对并向左移动0px。
<style>
    #file {
        height:0px;
        opacity:0;
    }  
    #span {
        left:0px;
        position:absolute;
        cursor: pointer;
    }
</style>

<form name="form">
    <input type="file" id="file" name="file"/>
    <span id="span">My File label!!!!</span>
</form>

<script>
    var span = document.getElementById("span");
    span.onclick = function(event) {
        document.form.file.click(event);
    };
</script>
我在Chrome和FF中测试过了,但没有在ie中测试。希望这能帮到你。 jsfiddle http://jsfiddle.net/aressler38/L5r8L/1/

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