Grow your CSS skills. Land your dream job.

Last updated on:

Custom File Input Styling in WebKit/Blink

<input type="file" class="custom-file-input">
.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);


See the Pen Custom File Inputs in WebKit/Blink by Chris Coyier (@chriscoyier) on CodePen

Fair warning: it doesn't show you the file name selected, but you might be able to tweak it to do that. I find typically these days you're triggering an event after file selection and snagging the data that way anyway.

Reference URL


  1. Harsha
    Permalink to comment#

    On Click of button, there is a extra margin which is in orange color, can you please tell how do I remove that?

  2. Thanks for sharing. There’re a small error on the code:

    .custom-file-inputhover::before {
          border-color: black;

    Must be:

    .custom-file-input:hover::before {
      border-color: black;
  3. Julian
    Permalink to comment#

    There is some extra space around it, which bothers in my case of usage. Is there any way to remove it?
    (Check image)

    • Pawel Sledzikowski
      Permalink to comment#

      I also notices that there is an extra invisible (but clickable) space after the pseudo :before element.

      In fact, that ‘extra’ space is actually the real input file element.

      I solved this issue just by setting visibility: hidden to main input element and
      setting visibility: visible to pseudo before element (together with absolute positioning it).

      In this case there is no longer invisible white space although your pseudo element is actually running out of a main flow which can or cannot be acceptable for you depending on your situation.


    • Jamie Katz

      Thanks Pawel, this worked well. Firefox doesn’t seem to have this issue: you can make the input whatever width you like.

    • Permalink to comment#

      Hey, with Pawel’s fix, I’ve provided event handling.

    • Anant Raj


  4. ricardo
    Permalink to comment#

    It doesn’t work on IE 9 :(

  5. I’m interested to know which browsers this will work in?

    • @henry it should work in Safari and Chrome (as well as any other application that uses their rendering engines). It won’t work in IE since that uses a different rendering engine.

  6. Thanks Chris. Pesky IE always ruins the party! Still a good solution though

  7. Rakesh
    Permalink to comment#

    This “custom file input” is not working in Firefox. Firefox is taking default stylings..

  8. shalini

    Is any way to change the cursor type like (cursor:pointer)?

  9. shalini

    I found the answer.

    .custom-file-input {
    color: transparent; cursor: pointer!important;

    Thank you. It is very easy to use.

  10. yogish d naik

    not working in ie..

  11. Did you make a screenshot of what it’s supposed to look like? On Firefox 30.0 using Ubuntu 14.10, there is just this :

  12. Timothy
    Permalink to comment#

    This is showing an unstyled “Browse” in the Firefox I’m using which is the latest today…

  13. kajal
    Permalink to comment#

    Styling the input type file this way was very easy as only css was used. It solved my query.

  14. Kunal
    Permalink to comment#

    How can we display the name of file and its type we selected … i.e. if i select a image file with name as xyz then it should display as xyz.jpg

  15. José Barros
    Permalink to comment#

    Hi, thank you for the code. I have one problem though. Since my website will be in different languages, i cant use the css content property, because the text will be in different languages. Any alternative? Thank you!

  16. I’ve created something which is a little more helpful for such a case, a jQuery plugin that gives you the ability to stylise everything about your input file, and also controlling it via a few callbacks :). I hope this may help someone.

    Here is the source on github : Simple Input File

  17. Adriana Cajina
    Permalink to comment#

    How can I invert the order of the elements?. I mean How can I set the button to the left and the file path text to the right?

  18. Didik
    Permalink to comment#

    File name is not showed. Can we add an indicator when a file is selected?

  19. Bilal khan
    Permalink to comment#

    This tric is very help full thank you …

  20. SamHeisenberg
    Permalink to comment#

    Kid, input tags can not take pseudo elements like img tag

  21. TonyWilk
    Permalink to comment#

    On browsers this doesn’t work on…. you can overlay the actual button:

    <div style="position:relative; display:inline-block; height:100px;">
            <input style="position:absolute; z-order:1; width:200px; height:50px; 
               type="file" id="fileToRead" onchange="onFileChanged()" >
            <div style="position:absolute; z-order:2; width:200px; height:50px;
                               background:lightgray; pointer-events: none;">
                  Read a file...

    The essentials are:
    1. the input element and the overlay <div> must have position: (for z-order to work)
    2. the overlay must have a higher z-order
    3. the overlay must have pointer-events:none


  22. Permalink to comment#

    Or hide it and use a styled “ as the clicker

  23. Permalink to comment#

    was supposed to say but the back ticks didn’t work

Leave a Comment

Posting Code

  • Use Markdown, and it will escape the code for you, like `<div class="cool">`.
  • Use triple-backticks for blocks of code.
      <h1>multi-line block of code</h1>
      <span>be cool yo.</span>
  • Otherwise, escape your code, like <code>&lt;div class="cool"&gt;</code>. Markdown is just easier though.

Current ye@r *

*May or may not contain any actual "CSS" or "Tricks".