【问题标题】:Styling an input type="file" button样式化输入 type="file" 按钮
【发布时间】:2021-02-23 23:50:32
【问题描述】:

如何设置输入 type="file" 按钮的样式?

<input type="file" />

【问题讨论】:

  • 我将添加自己的答案以按照我的方式进行操作...但这里有一个基于引导程序的示例,可能会有所帮助..geniuscarrier.com/…
  • 这个元素的问题,似乎是它不像其他类似的元素那样采用样式。喜欢input type="submit">。我对两种输入类型应用了相同的样式,这就是我得到的:i.imgur.com/7MI1Poh.jpg
  • 好吧,对我有用的只是在 Input 元素上方放置一个 div 并根据需要设置 div 的样式。然后将 Input opacity 设为 0 并使其与 div 的大小相同。

标签: html css


【解决方案1】:

您不需要 JavaScript!这是一个跨浏览器的解决方案:

See this example! - 适用于 Chrome/FF/IE - (IE10/9/8/7)

最好的方法是将带有for 属性的自定义标签元素附加到隐藏 文件输入元素。 (标签的for 属性必须与文件元素的id 匹配才能正常工作)。

<label for="file-upload" class="custom-file-upload">
    Custom Upload
</label>
<input id="file-upload" type="file"/>

作为替代方案,您也可以直接用标签包装文件输入元素:(example)

<label class="custom-file-upload">
    <input type="file"/>
    Custom Upload
</label>

在样式方面,只需隐藏1使用attribute selector的输入元素。

input[type="file"] {
    display: none;
}

那么您需要做的就是设置自定义label 元素的样式。 (example).

.custom-file-upload {
    border: 1px solid #ccc;
    display: inline-block;
    padding: 6px 12px;
    cursor: pointer;
}

1 - 值得注意的是,如果你使用display: none 隐藏元素,它在IE8 及更低版本中将不起作用。还要注意 jQuery 默认验证 doesn't validate hidden fields 的事实。如果其中任何一个对您来说是个问题,这里有两种不同的方法可以隐藏在这些情况下有效的输入(12)。

【讨论】:

  • 不过,我确实对这个有疑问,选择文件时我们将如何处理然后显示文件名?
  • 如果display: none设置为input[type=file],如何显示所选文件的名称?
  • 很好的解决方案,但您确实需要 javascript。如果要显示文件名,正如其他人一直在问的那样,您需要在标签和隐藏输入之间添加一个跨度:。然后更新更改事件的跨度: $('#file-upload').bind('change', function() { var fileName = ''; fileName = $(this).val(); $('#文件选择').html(fileName); })
  • 出于可访问性原因,您应该使用position: absolute; left: -99999rem 而不是display: none。大多数情况下,如果使用 display: none 方法隐藏元素,屏幕阅读器将不会读取它们。
  • 我很惊讶地发现似乎没有人考虑键盘可访问性。 label 元素不能通过键盘访问,这与 buttons 和 inputs 不同。添加tabindex 不是解决方案,因为当label 获得焦点并且用户按下回车键时,它仍然不会被执行。我通过视觉上隐藏输入解决了这个问题,所以它仍然可以集中,然后在label父级上使用:focus-withinjsbin.com/fokexoc/2/edit?html,css,output
【解决方案2】:

样式文件输入是出了名的困难,因为大多数浏览器不会改变 CSS 或 javascript 的外观。

即使输入的大小也不会响应:

<input type="file" style="width:200px">

相反,您需要使用 size 属性:

<input type="file" size="60" />

对于任何比这更复杂的样式(例如更改浏览按钮的外观),您需要查看在本机文件输入之上覆盖样式按钮和输入框的技巧。 rm 已经在www.quirksmode.org/dom/inputfile.html 提到的文章是我见过的最好的。

更新

虽然很难直接设置&lt;input&gt; 标签的样式,但在&lt;label&gt; 标签的帮助下,这很容易实现。请参阅以下@JoshCrozier 的回答:https://stackoverflow.com/a/25825731/10128619

【讨论】:

  • 刚刚在这里找到了一个基于此脚本的 jquery 解决方案:blog.vworld.at/2008/08/21/…
  • @TLK Ryan 的回答在尝试进行 iframe 上传时在 IE 中不起作用。它给你一个访问被拒绝的错误。对于正常上传,我同意这是最简单的!
  • 解释了一个比 quirksmode 简单得多的解决方案 here。只需将链接放在这里,因为无论如何这个答案基本上都是仅链接的答案。
  • 对于任何对现代方法感兴趣的人,我建议查看this answer。它也不需要像其他一些答案那样的 JavaScript。
  • @JoshCrozier 发布了一个非常好的解决方案。甚至击败假鼠标点击解决方案:)
【解决方案3】:

按照这些步骤,您可以为您的文件上传表单创建自定义样式:

  1. 这是简单的 HTML 表单(请阅读我在下面写的 HTML cmets)

    <form action="#type your action here" method="POST" enctype="multipart/form-data">
      <div id="yourBtn" style="height: 50px; width: 100px;border: 1px dashed #BBB; cursor:pointer;" onclick="getFile()">Click to upload!</div>
      <!-- this is your file input tag, so i hide it!-->
      <div style='height: 0px;width:0px; overflow:hidden;'><input id="upfile" type="file" value="upload"/></div>
      <!-- here you can have file submit button or you can write a simple script to upload the file automatically-->
      <input type="submit" value='submit' >
    </form>
    
  2. 然后使用这个简单的脚本将点击事件传递给文件输入标签。

    function getFile(){
         document.getElementById("upfile").click();
    }
    

    现在您可以使用任何类型的样式,而不必担心如何更改默认样式。

我很清楚这一点,因为我已经尝试更改默认样式一个半月了。相信我,这很难,因为不同的浏览器有不同的上传输入标签。所以使用这个来构建您的自定义文件上传表单。这是完整的自动上传代码。

function getFile() {
  document.getElementById("upfile").click();
}

function sub(obj) {
  var file = obj.value;
  var fileName = file.split("\\");
  document.getElementById("yourBtn").innerHTML = fileName[fileName.length - 1];
  document.myForm.submit();
  event.preventDefault();
}
#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;
}
<form action="#type your action here" method="POST" enctype="multipart/form-data" name="myForm">
  <div id="yourBtn" onclick="getFile()">click to upload a file</div>
  <!-- this is your file input tag, so i hide it!-->
  <!-- i used the onchange event to fire the form submission-->
  <div style='height: 0px;width: 0px; overflow:hidden;'><input id="upfile" type="file" value="upload" onchange="sub(this)" /></div>
  <!-- here you can have file submit button or you can write a simple script to upload the file automatically-->
  <!-- <input type="submit" value='submit' > -->
</form>

【讨论】:

  • @user1053263 -> 感谢您的推荐.. 这里我使用了一个非常简单的 java 脚本,不需要使用 Jquery 或 PrototypeJS 之类的框架。
  • 我在 IE9 中提交表单时遇到问题。我收到“拒绝访问”错误,试图通过 javascript 提交表单。如果我通过 UI 单击提交按钮,它可以工作。有解决办法吗?
  • @kevin -> 请在 document.myForm.submit() 之后尝试 event.preventDefault() ,我对上面的代码进行了更改。
  • 在 Chrome、Firefox、Safari 和 Opera 中运行良好 - 但在 IE9 中无法运行。在 IE9 中,我得到与@Kevin 相同的“访问被拒绝”错误 - 有时只是无声失败,没有错误。
  • 在 IE10(可能还有 IE9 等)中,如果您尝试通过 javascript 单击文件输入按钮后自动提交表单,则会收到“拒绝访问”(或 jQuery 没有响应)。因此,只要用户仍然是提交表单的人,此方法就适用于设置文件输入按钮的样式。我花了一段时间才找到这个,我看到其他人也有同样的问题。有关更多信息,请参阅stackoverflow.com/a/4335390/21579
【解决方案4】:

创建&lt;input type="file"&gt; 时,所有渲染引擎都会自动生成一个按钮。从历史上看,该按钮完全没有样式。但是,Trident 和 WebKit 通过伪元素添加了钩子。

三叉戟

从 IE10 开始,文件输入按钮可以使用 ::-ms-browse 伪元素设置样式。基本上,您应用于常规按钮的任何 CSS 规则都可以应用于伪元素。例如:

::-ms-browse {
  background: black;
  color: red;
  padding: 1em;
}
&lt;input type="file"&gt;

在 Windows 8 的 IE10 中显示如下:

WebKit

WebKit 为其文件输入按钮提供了一个带有::-webkit-file-upload-button 伪元素的钩子。同样,几乎可以应用任何 CSS 规则,因此 Trident 示例也可以在这里使用:

::-webkit-file-upload-button {
  background: black;
  color: red;
  padding: 1em;
}
&lt;input type="file"&gt;

这在 OS X 上的 Chrome 26 中显示如下:

【讨论】:

  • Firefox 等基于 Gecko 的程序没有特殊的样式可能性。
  • 在你的回答中,使用 css,如何在 标签中隐藏“未选择文件”字样。请评论我。
  • 我不知道,对不起
  • 如果有人想玩风格,我在这里添加了一个 jsfidde:jsfiddle.net/peter_drinnan/r0gq6kw2
【解决方案5】:

用 css 隐藏它并使用带有 $(selector).click() 的自定义按钮来激活浏览按钮。然后设置一个时间间隔来检查文件输入类型的值。间隔可以为用户显示值,以便用户可以看到上传的内容。提交表单时间隔将清除[编辑]对不起,我一直很忙是想更新这篇文章,这里是一个例子

<form action="uploadScript.php" method="post" enctype="multipart/form-data">
<div>
    <!-- filename to display to the user -->
    <p id="file-name" class="margin-10 bold-10"></p>

    <!-- Hide this from the users view with css display:none; -->
    <input class="display-none" id="file-type" type="file" size="4" name="file"/>

    <!-- Style this button with type image or css whatever you wish -->
    <input id="browse-click" type="button" class="button" value="Browse for files"/>

    <!-- submit button -->
    <input type="submit" class="button" value="Change"/>
</div>

$(window).load(function () {
    var intervalFunc = function () {
        $('#file-name').html($('#file-type').val());
    };
    $('#browse-click').on('click', function () { // use .live() for older versions of jQuery
        $('#file-type').click();
        setInterval(intervalFunc, 1);
        return false;
    });
});

【讨论】:

  • 请注意,如果您使用这种方式,它将在 Internet Explorer 中中断,因为它是一个安全异常..
  • 感谢提示。当我使用 IE 时,它通常与其他所有内容都有一个单独的布局。讨厌 IE。但我简化了 IE 中的所有内容。
  • 在 FF20 中,$('#file-type').click() 似乎没有弹出“选择文件”对话框——实际上什么也没发生。有什么想法吗?
  • 尝试使用jquery中的触发方式。 .live 在新的 jquery 中也更改为 .on()
  • 一旦你设置了这个间隔,我可以在什么时候清除它?否则它将不断发射
【解决方案6】:

$('.new_Btn').click(function() {
  $('#html_btn').click();
});
.new_Btn {
  // your css propterties
}

#html_btn {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="new_Btn">SelectPicture</div><br>
<input id="html_btn" type='file' " /><br>

您也可以在没有 jQuery 的情况下使用普通的 JavaScript 实现您的目标。

现在 newBtn 与 html_btn 链接,您可以根据需要设置新 btn 的样式:D

【讨论】:

  • 只是好奇,它在Firefox、IE、Opera、Safari、Chrome等新一代浏览器中都可以使用吗?
  • 这对我来说是最简单的解决方案!至少在 IE 9、Chrome 23 和 FF 16 和 jQuery 1.7.2 中,所以更新版本应该可以工作。
  • 如果用户选择了图像,有谁知道如何更改 .new_Btn。现在它只显示同一个类。有人知道如何跟踪吗?谢谢
  • @MehdiKaramosly 它甚至可以在 IE 6 上工作 - 但这是真的
  • @Ando via Javascript/jQuery => 文件输入的值为空或包含本地文件路径 => 使用 onchange 事件并测试 val() :) 见jsfiddle.net/ZrBPF
【解决方案7】:

如果您使用的是 Bootstrap 3,这对我有用:

https://www.abeautifulsite.net/posts/whipping-file-inputs-into-shape-with-bootstrap-3/

.btn-file {
  position: relative;
  overflow: hidden;
}
.btn-file input[type=file] {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 100%;
  min-height: 100%;
  font-size: 100px;
  text-align: right;
  filter: alpha(opacity=0);
  opacity: 0;
  outline: none;
  background: white;
  cursor: inherit;
  display: block;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />

<span class="btn btn-primary btn-file">
    Browse...<input type="file">
</span>

这会产生以下文件输入按钮:

说真的,请查看https://www.abeautifulsite.net/posts/whipping-file-inputs-into-shape-with-bootstrap-3/

【讨论】:

  • 这保留了很棒的拖放功能:),大多数答案不接受丢弃的文件。
  • 那个链接坏了:/
  • 已修复。感谢您的提醒!
【解决方案8】:

本地拖放支持的工作示例:https://jsfiddle.net/j40xvkb3/

在设置文件输入样式时,您不应破坏任何原生交互 输入提供

display: none 方法打破了原生拖放支持。

为了不破坏任何东西,您应该使用opacity: 0 方法作为输入,并在包装​​器中使用相对/绝对模式定位它。

使用这种技术,您可以轻松地为用户设置点击/拖放区域的样式,并在 dragenter 事件中添加自定义类以更新样式并给用户反馈,让他看到他可以拖放文件。

HTML:

<label for="test">
  <div>Click or drop something here</div>
  <input type="file" id="test">
</label>

CSS:

input[type="file"] {
  position: absolute;
  left: 0;
  opacity: 0;
  top: 0;
  bottom: 0;
  width: 100%;
}

div {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #ccc;
  border: 3px dotted #bebebe;
  border-radius: 10px;
}

label {
  display: inline-block;
  position: relative;
  height: 100px;
  width: 400px;
}

这是一个工作示例(带有额外的 JS 来处理 dragover 事件和删除的文件)。

https://jsfiddle.net/j40xvkb3/

希望这有帮助!

【讨论】:

  • 感谢您的帖子,如果添加了 multiple="multiple" 属性,这将如何工作,我拖了 2 张图片但只看到了第 1 张的路径
  • 您在这里错过了代码。小提琴上还有更多。什么图书馆?
  • 只有一些 javascript 在使用 jQuery 来显示已删除的文件。就是这样
  • 在实施了这个解决方案并进一步测试后,它似乎在 Edge 中也不起作用。
  • 啊,好吧,我错过了您的答案中带有相对位置的包装器-我的错。如果输入低于屏幕尺寸,浏览器会尝试滚动到它,并在此过程中将滚动容器向上移动到页面。这是一个演示:stackblitz.com/edit/input-file-overflow?file=style.css(只是没有完全演示绝对位置是如何导致行为的)
【解决方案9】:

只有 CSS

使用这个非常simpleEASY

.choose::-webkit-file-upload-button {
  color: white;
  display: inline-block;
  background: #1CB6E0;
  border: none;
  padding: 7px 15px;
  font-weight: 700;
  border-radius: 3px;
  white-space: nowrap;
  cursor: pointer;
  font-size: 10pt;
}
<label>Attach your screenshort</label>
<input type="file" multiple class="choose">

【讨论】:

  • 简单但并非所有地方都支持
  • 这比其他不显示所选文件名称的解决方案要好得多。但是如何更改文本“选择文件”。一个人真的不得不怀疑 HTML/CSS 标准背后的人的能力,谁想出了这些东西?做的太差了。
  • 我只补充一点,firefox 有它自己的类似类 ::file-selector-button
【解决方案10】:
 <label>
    <input type="file" />
 </label>

您可以将输入 type="file" 包装在输入标签内。随意设置标签的样式,并使用 display: none; 隐藏输入;

【讨论】:

【解决方案11】:

我可以用 pure CSS 使用下面的代码来做到这一点。我用过 bootstrap 和 font-awesome。

<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" />

<label class="btn btn-default btn-sm center-block btn-file">
  <i class="fa fa-upload fa-2x" aria-hidden="true"></i>
  <input type="file" style="display: none;">
</label>

【讨论】:

    【解决方案12】:

    这种方法为您提供了整个灵活性! ES6 / VanillaJS!

    html:

    <input type="file" style="display:none;"></input>
    <button>Upload file</button>
    

    javascript:

    document.querySelector('button').addEventListener('click', () => {
      document.querySelector('input[type="file"]').click();
    });
    

    这隐藏了输入文件按钮,但在引擎盖下从另一个普通按钮单击它,您显然可以像任何其他按钮一样设置样式。除了无用的 DOM 节点之外,这是唯一没有缺点的解决方案。感谢display:none;,输入按钮不会在 DOM 中保留任何可见空间。

    (我不知道该向谁提供支持了。但我是从 Stackoverflow 上的某个地方得到这个想法的。)

    【讨论】:

      【解决方案13】:

      这是一个解决方案,它并没有真正设置&lt;input type="file" /&gt; 元素的样式,而是在其他元素之上使用&lt;input type="file" /&gt; 元素(可以设置样式)。 &lt;input type="file" /&gt; 元素并不真正可见,因此整体错觉是一个样式精美的文件上传控件。

      我最近遇到了这个问题,尽管 Stack Overflow 上有很多答案,但似乎没有一个真正符合要求。最后,我最终定制了这个,以获得一个简单而优雅的解决方案。

      我还在 Firefox、IE(11、10 和 9)、Chrome 和 Opera、iPad 和一些安卓设备上进行了测试。

      这是 JSFiddle 链接 -> http://jsfiddle.net/umhva747/

      $('input[type=file]').change(function(e) {
          $in = $(this);
          $in.next().html($in.val());
          
      });
      
      $('.uploadButton').click(function() {
          var fileName = $("#fileUpload").val();
          if (fileName) {
              alert(fileName + " can be uploaded.");
          }
          else {
              alert("Please select a file to upload");
          }
      });
      body {
          background-color:Black;
      }
      
      div.upload {
          background-color:#fff;
          border: 1px solid #ddd;
          border-radius:5px;
          display:inline-block;
          height: 30px;
          padding:3px 40px 3px 3px;
          position:relative;
          width: auto;
      }
      
      div.upload:hover {
          opacity:0.95;
      }
      
      div.upload input[type="file"] {
          display: input-block;
          width: 100%;
          height: 30px;
          opacity: 0;
          cursor:pointer;
          position:absolute;
          left:0;
      }
      .uploadButton {
          background-color: #425F9C;
          border: none;
          border-radius: 3px;
          color: #FFF;
          cursor:pointer;
          display: inline-block;
          height: 30px;
          margin-right:15px;
          width: auto;
          padding:0 20px;
          box-sizing: content-box;
      }
      
      .fileName {
          font-family: Arial;
          font-size:14px;
      }
      
      .upload + .uploadButton {
          height:38px;
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
      <form action="" method="post" enctype="multipart/form-data">
          <div class="upload">
              <input type="button" class="uploadButton" value="Browse" />
              <input type="file" name="upload" accept="image/*" id="fileUpload" />
              <span class="fileName">Select file..</span>
          </div>
          <input type="button" class="uploadButton" value="Upload File" />
      </form>

      希望对你有帮助!!!

      【讨论】:

      • 巧妙巧妙地解决了这种邪恶的文件上传样式恶作剧。
      【解决方案14】:

      将上传文件按钮放在漂亮的按钮或元素上并将其隐藏。

      非常简单,适用于任何浏览器

      <div class="upload-wrap">
          <button type="button" class="nice-button">upload_file</button>
          <input type="file" name="file" class="upload-btn">
      </div>
      

      样式

      .upload-wrap {
          position: relative;
      }
      
      .upload-btn {
          position: absolute;
          left: 0;
          opacity: 0;
      }
      

      【讨论】:

        【解决方案15】:

        使用 jquery 很简单。给出Ryan的建议稍作修改的代码示例。

        基本的html:

        <div id="image_icon"></div>
        <div id="filename"></div>
        <input id="the_real_file_input" name="foobar" type="file">
        

        准备好后,请务必在输入中设置样式:opacity: 0 你不能设置display: none,因为它需要是可点击的。但是,如果您愿意,可以将其放在“新建”按钮下,或者使用 z-index 将其塞入其他东西下。

        设置一些 jquery 以在单击图像时单击实际输入。

        $('#image_icon').click(function() {
            $('#the_real_file_input').click();
        });
        

        现在您的按钮正在工作。更改时只需剪切并粘贴值即可。

        $('input[type=file]').bind('change', function() {
            var str = "";
            str = $(this).val();
            $("#filename").text(str);
        }).change();
        

        嘀嘀!您可能需要将 val() 解析为更有意义的内容,但您应该已准备就绪。

        【讨论】:

        • 这将在 FF11 中失败 - 原因:因为您无法精确影响输入字段的大小(仅通过使用 html 大小)和按钮(您可以使用 css 设置高度),如果您的可见输入字段更大与原始 FF 提供给我们的相比,您留下了一个非常大的盲区 - 用户观点:在大多数情况下,他会抱怨点击时上传不起作用
        • 好主意,但这不适用于 IE。 $('#the_real_file_input').click() 将触发打开对话框,但文件不会被选择到表单中并且上传会失败。
        【解决方案16】:

        这是一个纯 CSS、无 Javascript、无引导、100% 跨浏览器的解决方案!只需剪切和粘贴一组样式,然后测试您的文件上传控件。

        此解决方案不会像这里的其他帖子那样尝试隐藏然后重新创建原始 HTML 元素。它使用plain CSS 没有任何马戏团技巧或第三方工具来为所有主要浏览器设置原始文件上传表单控件的样式。您甚至不需要更改 HTML 代码!

        这是使用下面的 CSS 在 Firefox、Chrome 和 Edge 中文件上传控件的外观。这是一个非常简单干净的设计。您可以将其更改为您喜欢的任何外观:

        Internet Explorer 为您提供了有限的设计控制,但至少您可以使用 CSS 来操作控制以更改一些内容,包括圆角边框和颜色:

        <style>
        /* Note: This CSS will style all instances of 
           <input type=file /> controls in your website. */
        input[type="file"],
        input[type="file"]:visited,
        input[type="file"]:hover,
        input[type="file"]:focus,
        input[type="file"]:active {
            margin:0;
            padding: 0em 0em;
            padding: 0rem 0rem;
            overflow: hidden; /* long file names overflow so just hide the end */
            background: #ffffff;
            border-radius: .2em;
            border-radius: .2rem;
            outline: none;
            border: 2px solid #bbb;
            cursor: pointer;
            -webkit-appearance: textfield;
            -moz-appearance: textfield;
        }
        
        input[type="file"]:hover {
            background: #f9f9ff; /* I am using a light blue to indicate an interaction */
            border: 2px solid #999;
        }
        
        input[type="file"]:visited,
        input[type="file"]:focus,
        input[type="file"]:active {
            background: #fff; /* Default back to white when focused. */
            border: 2px solid #999;
        }
        
        /* Note: Firefox flags the file name box as a *readonly* input. So that attribute selector was added below. Note: These selectors blow up in IE so have to be separated from the same styles above. */
        input[type="file"]:disabled,
        input[type="file"]:read-only {
            margin: 0;
            padding: 0em 0em;
            padding: 0rem 0rem;
            overflow: hidden; /* long file names overflow so just hide the end */
            background: #ffffff;
            border-radius: .2em;
            border-radius: .2rem;
            outline: none;
            border: 2px solid #bbb;
            cursor: pointer;
            -webkit-appearance: textfield;
            -moz-appearance: textfield;
        }
        
        input[type="file"]:disabled:hover,
        input[type="file"]:read-only:hover {
            background: #f9f9ff; /* I am using a light blue to indicate an interaction */
            border: 2px solid #999;
        }
        
        input[type="file"]:disabled:visited,
        input[type="file"]:disabled:focus,
        input[type="file"]:disabled:active,
        input[type="file"]:read-only:visited,
        input[type="file"]:read-only:focus,
        input[type="file"]:read-only:active {
            background: #fff; /* Default back to white when focused. */
            border: 2px solid #999;
        }
        
        /* IE UPLOAD BUTTON STYLE: This attempts to alter the file upload button style in IE.  Keep in mind IE gives you limited design control but at least you can customize its upload button.*/
        ::-ms-browse { /* IE */
            display: inline-block;
            margin: 0;
            padding: .2em .5em;
            padding: .2rem .5rem;
            text-align: center;
            outline: none;
            border: none;
            background: #fff;
            white-space: nowrap;
            cursor: pointer;
        }
        /* FIREFOX UPLOAD BUTTON STYLE */
        ::file-selector-button {/* firefox */
            display: inline-block;
            margin: 0rem 1rem 0rem 0rem;
            padding: .18em .5em;
            padding: .18rem .5rem;
            -webkit-appearance: button;
            text-align: center;
            border-radius: .1rem 0rem 0rem .1rem;
            outline: none;
            border: none;
            border-right: 2px solid #bbb;
            background: #eee;
            white-space: nowrap;
            cursor: pointer;
        }
        /* CHROME AND EDGE UPLOAD BUTTON STYLE */
        ::-webkit-file-upload-button { /* chrome and edge */
            display: inline-block;
            margin: 0rem 1rem 0rem 0rem;
            padding: .19em .5em;
            padding: .19rem .5rem;
            -webkit-appearance: button;
            text-align: center;
            border-radius: .1rem 0rem 0rem .1rem;
            outline: none;
            border: none;
            border-right: 2px solid #bbb;
            background: #eee;
            white-space: nowrap;
            cursor: pointer;
        }
        </style>
        

        我的解决方案的优点是:

        1. 您坚持使用简单的 CSS 来设置原始 HTML 输入控件的样式
        2. 您可以在文件输入文本框中看到一个或多个文件名
        3. 屏幕阅读器和支持 ARIA 的设备可以与您的文件上传控件正常交互
        4. 您可以在 HTML 元素上设置 tabindex,使其成为 Tab 键顺序的一部分
        5. 因为您使用的是纯 HTML 和 CSS,您的 文件输入按钮在新旧浏览器中都能完美运行
        6. 需要零 JavaScript!
        7. 即使在最古老的浏览器中也能快速运行和加载
        8. 由于您没有使用“display:none”来隐藏控件,因此在任何已知的旧或新浏览器版本中都不会禁止其文件块流数据到达服务器

        您不需要 goofy JavaScript 技巧、Bootstrap 或尝试隐藏/重新创建文件输入控件。这只会破坏在线每个人的可用性。为原始 HTML 控件设置样式意味着您的文件上传控件保证在 25 年的新旧网络浏览器中都能正常工作。

        这就是为什么您不能相信所有这些脚本化的黑客攻击,它们会擦除、重写或破坏 HTML,只是为了尝试重新创造一些视觉体验。这表明您不了解 HTML 是如何使用的,或者为什么它存在 30 年几乎没有变化。您永远不应该尝试重写 HTML 的原生表单控制功能。为什么?在网站中使用自然 HTML 不仅仅是为了一些强制的视觉体验而操纵标记。这些被替换的 HTML 元素中有限的视觉设计的权衡是出于某种原因而设计的。

        我的建议:坚持使用简单的 HTML 和 CSS 解决方案,作为 Web 开发人员,您将遇到零问题。

        【讨论】:

        • 这是真正的交易!非常感谢! (对于其他人:按钮文本不能直接更改或在输入元素上使用 :after 和 :before ,它需要在按钮顶部带有 pointer-events: none; 的单独元素。
        【解决方案17】:

        我能想到的唯一方法是在渲染后使用 javascript 找到按钮并为其分配样式

        你也可以看看this writeup

        【讨论】:

        • 纯 CSS,无 JavaScript,适用于所有浏览器,低至 ie7 - 太棒了!
        【解决方案18】:
        <input type="file" name="media" style="display-none" onchange="document.media.submit()">
        

        我通常会使用简单的javascript来自定义文件输入标签。隐藏输入字段,单击按钮,javascript调用隐藏字段,简单的解决方案没有任何css或一堆jquery。

        <button id="file" onclick="$('#file').click()">Upload File</button>
        

        【讨论】:

        • 您不能使用click() 方法来触发输入类型文件的事件。大多数浏览器出于安全原因不允许。
        【解决方案19】:

        可见性:隐藏的技巧

        我通常选择visibility:hidden 技巧

        这是我的风格按钮

        <div id="uploadbutton" class="btn btn-success btn-block">Upload</div>
        

        这是输入类型=文件按钮。注意visibility:hidden 规则

        <input type="file" id="upload" style="visibility:hidden;">
        

        这是将它们粘合在一起的 JavaScript 位。有效

        <script>
         $('#uploadbutton').click(function(){
            $('input[type=file]').click();
         });
         </script>
        

        【讨论】:

        • 您不能使用 click() 方法来触发输入类型文件的事件。出于安全原因,大多数浏览器都不允许
        • 甚至使用jquery?那是对的吗?你会怎么做呢?
        • style="visibility:hidden" 太长,直接用hidden。此外,click() 确实适用于任何浏览器,目前还没有非常可靠的安全理由,在任何设备上都是合法的方式,@Gianluca 用于经典 jQuery 使用 trigger()
        • 这正是我要添加的解决方案!它工作,你可以准确地显示它你想要的。适用于 Chrome,将尝试其他。
        【解决方案20】:

        转换文件名的多文件解决方案

        引导EXAMPLE

        HTML:

        <div>
          <label class="btn btn-primary search-file-btn">
            <input name="file1" type="file" style="display:None;"> <span>Choose file</span>
          </label>
          <span>No file selected</span>
        </div>
        
        <div>
          <label class="btn btn-primary search-file-btn">
            <input name="file2" type="file" style="display:None;"> <span>Choose file</span>
          </label>
          <span>No file selected</span>
        </div>
        

        1。带有 jQ​​uery 的 JS:

        $().ready(function($){
            $('.search-file-btn').children("input").bind('change', function() {
            var fileName = '';
            fileName = $(this).val().split("\\").slice(-1)[0];
            $(this).parent().next("span").html(fileName);
          })
        });
        

        2。没有 jQuery 的 JS

        Array.prototype.forEach.call(document.getElementsByTagName('input'), function(item) {
          item.addEventListener("change", function() {
            var fileName = '';
            fileName = this.value.split("\\").slice(-1)[0];
            this.parentNode.nextElementSibling.innerHTML = fileName;
          });
        });
        

        【讨论】:

          【解决方案21】:

          这里我们使用 span 来触发类型文件的输入,我们只是自定义了 span,所以我们可以使用这种方式添加任何样式。

          注意,我们使用带有 visibility:hidden 选项的 input 标签并在 span 中触发它。

          .attachFileSpan{
          color:#2b6dad;
          cursor:pointer;
          }
          .attachFileSpan:hover{
          text-decoration: underline;
          }
          <h3> Customized input of type file </h3>
          <input id="myInput" type="file" style="visibility:hidden"/>
          
                  <span title="attach file" class="attachFileSpan" onclick="document.getElementById('myInput').click()">
                  Attach file
                  </span>

          Reference

          【讨论】:

            【解决方案22】:

            这是一个解决方案,它还显示了选择的文件名: http://jsfiddle.net/raft9pg0/1/

            HTML:

            <label for="file-upload" class="custom-file-upload">Chose file</label>
            <input id="file-upload" type="file"/>
            File: <span id="file-upload-value">-</span>
            

            JS:

            $(function() {
                $("input:file[id=file-upload]").change(function() {
                    $("#file-upload-value").html( $(this).val() );
                });
            });
            

            CSS:

            input[type="file"] {
                display: none;
            }
            
            .custom-file-upload {
                  background: #ddd;
                  border: 1px solid #aaa;
                  border-top: 1px solid #ccc;
                  border-left: 1px solid #ccc;
                  -moz-border-radius: 3px;
                  -webkit-border-radius: 3px;
                  border-radius: 3px;
                  color: #444;
                  display: inline-block;
                  font-size: 11px;
                  font-weight: bold;
                  text-decoration: none;
                  text-shadow: 0 1px rgba(255, 255, 255, .75);
                  cursor: pointer;
                  margin-bottom: 20px;
                  line-height: normal;
                  padding: 8px 10px; }
            

            【讨论】:

            • 如何只显示文件名,而不是fakepath路径?
            【解决方案23】:

            这是上传材料/角度文件的好方法。 您可以使用引导按钮执行相同的操作。

            请注意,我使用&lt;a&gt; 而不是&lt;button&gt; 这允许点击事件冒泡。

            <label>
                <input type="file" (change)="setFile($event)" style="display:none" />
            
                <a mat-raised-button color="primary">
                  <mat-icon>file_upload</mat-icon>
                  Upload Document
                </a>
            
              </label>
            

            【讨论】:

            • 这在 Angular 2+ 中效果很好。不知道为什么它被否决。如果您使用 Angular,这是最简单的解决方案。
            【解决方案24】:

            也许有很多遮阳篷。但我喜欢这个带有 fa-buttons 的纯 CSS:

            .divs {
                position: relative;
                display: inline-block;
                background-color: #fcc;
            }
            
            .inputs {
                position:absolute;
                left: 0px;
                height: 100%;
                width: 100%;
                opacity: 0;
                background: #00f;
                z-index:999;
            }
            
            .icons {
                position:relative;
            }
            <div class="divs">
            <input type='file' id='image' class="inputs">
            <i class="fa fa-image fa-2x icons"></i>
            </div>
            
            <div class="divs">
            <input type='file' id='book' class="inputs">
            <i class="fa fa-book fa-5x icons"></i>
            </div>
            <br><br><br>
            <div class="divs">
            <input type='file' id='data' class="inputs">
            <i class="fa fa-id-card fa-3x icons"></i>
            </div>
            
            
            
            
            
            <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>

            小提琴:https://jsfiddle.net/zoutepopcorn/v2zkbpay/1/

            【讨论】:

              【解决方案25】:

              不要被“伟大的”纯 CSS 解决方案所迷惑,这些解决方案实际上非常特定于浏览器,或者将样式按钮覆盖在实际按钮之上,或者迫使您使用 &lt;label&gt; 而不是&lt;button&gt;,或任何其他此类黑客。 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”。但您可能希望每次用户提供文件时都获取该文件。

              【讨论】:

              • 确切地说,label 方法确实有效,只是它不能显示选定的文件名或路径。所以必然地说,这是唯一需要 JS 解决的问题。
              【解决方案26】:

              更新 没关系,这在 IE 或它的新兄弟 FF 中不起作用。按预期适用于所有其他类型的元素,但不适用于文件输入。一个更好的方法是创建一个文件输入和一个链接到它的标签。使文件输入不显示和繁荣,它在IE9+无缝工作。

              警告:下面的都是废话!

              通过使用针对容器定位/调整大小的伪元素,我们可以只使用一个输入文件(不需要额外的标记),并像往常一样设置样式。

              Demo

              <input type="file" class="foo">
              <style>
                  .foo {
                      display: block;
                      position: relative;
                      width: 300px;
                      margin: auto;
                      cursor: pointer;
                      border: 0;
                      height: 60px;
                      border-radius: 5px;
                      outline: 0;
                  }
                  .foo:hover:after {
                      background: #5978f8;
                  }
                  .foo:after {
                      transition: 200ms all ease;
                      border-bottom: 3px solid rgba(0,0,0,.2);
                      background: #3c5ff4;
                      text-shadow: 0 2px 0 rgba(0,0,0,.2);
                      color: #fff;
                      font-size: 20px;
                      text-align: center;
                      position: absolute;
                      top: 0;
                      left: 0;
                      width: 100%;
                      height: 100%;
                      display: block;
                      content: 'Upload Something';
                      line-height: 60px;
                      border-radius: 5px;
                  }
              </style>
              

              尽情享受吧!

              旧更新

              把它变成了一个 Stylus mixin。对于你们中的一个很酷的 SCSS 猫来说应该很容易转换它。

                  file-button(button_width = 150px)
                    display block
                    position relative
                    margin auto
                    cursor pointer
                    border 0
                    height 0
                    width 0
                    outline none
                    &:after
                      position absolute
                      top 0
                      text-align center
                      display block
                      width button_width
                      left -(button_width / 2)
              

              用法:

              <input type="file">
              
              input[type="file"]
                  file-button(200px)
              

              【讨论】:

              • ROTFLMAO@IE的新兄弟FF
              【解决方案27】:

              我找到了一种将文件按钮切换为图片的非常简单的方法。 您只需标记一张图片并将其放在文件按钮的顶部。

              <html>
              <div id="File button">
                  <div style="position:absolute;">
                      <!--This is your labeled image-->
                      <label for="fileButton"><img src="ImageURL"></label>
                  </div>
                  <div>
                      <input type="file" id="fileButton"/>
                  </div>
              </div>
              </html>
              

              点击带标签的图片时,选择文件按钮。

              【讨论】:

                【解决方案28】:

                本周我还需要自定义按钮并将所选文件名显示在旁边,所以在阅读了上面的一些答案(谢谢顺便说一句)后,我想出了以下实现:

                HTML:

                <div class="browse">
                <label id="uploadBtn" class="custom-file-upload">Choose file
                <input type="file" name="fileInput" id="fileInput" accept=".yaml" ngf-select ngf-change="onFileSelect($files)" />
                </label>
                <span>{{fileName}}</span>
                </div>
                

                CSS

                   input[type='file'] {
                    color: #a1bbd5;
                    display: none;
                
                }
                
                .custom-file-upload {
                    border: 1px solid #a1bbd5;
                    display: inline-block;
                    padding: 2px 8px;
                    cursor: pointer;
                }
                
                label{
                    color: #a1bbd5;
                    border-radius: 3px;
                }
                

                Javascript(角度)

                app.controller('MainCtrl', function($scope) {
                
                        $scope.fileName = 'No file chosen';
                
                          $scope.onFileSelect = function ($files) {
                          $scope.selectedFile = $files;
                          $scope.fileName = $files[0].name;
                    };
                });
                

                基本上我正在使用 ng-file-upload lib,Angular-wise 我将文件名绑定到我的 $scope 并赋予它“未选择文件”的初始值,我还绑定了 onFileSelect( ) 函数到我的范围,所以当一个文件被选中时,我使用 ng-upload API 获取文件名并将其分配给 $scope.filename。

                【讨论】:

                  【解决方案29】:

                  在单击样式化的&lt;div&gt; 时使用trigger() 函数简单地模拟对&lt;input&gt; 的单击。我用&lt;div&gt; 创建了自己的按钮,然后在单击&lt;div&gt; 时触发了对input 的单击。这使您可以根据需要创建按钮,因为它是&lt;div&gt; 并模拟单击文件&lt;input&gt;。然后在您的&lt;input&gt; 上使用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");
                  });
                  

                  【讨论】:

                    【解决方案30】:

                    最好的方法是使用伪元素 :after 或 :before 作为在 de 输入之外的元素。然后根据需要设置该伪元素的样式。我建议您将所有输入文件的一般样式如下:

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

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2010-10-09
                      • 2011-09-13
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多