327

I want to change default text on button that is "Choose File" when we use input="file".

enter image description here

How can I do this? Also as you can see in image button is on left side of text. How can I put it on right side of text?

5

27 Answers 27

305

Use the for attribute of label for input.

<div>
  <label for="files" class="btn">Select Image</label>
  <input id="files" style="display:none;" type="file">
</div>

Below is the code to fetch name of the uploaded file


$("#files").change(function() {
  filename = this.files[0].name;
  console.log(filename);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
    <label for="files" class="btn">Select Image</label>
    <input id="files" style="display:none;" type="file">
</div>

Sign up to request clarification or add additional context in comments.

10 Comments

display:none can be used on INPUT so it won't use not needed space.
Works fine on Mac with Chrome, FF and Safari. If it does it also on IE then this is the best and simplest option to style the file input button. Thanks!
works well, only slight negative is that the user can't see the name of the file that has been selected upon selection.
@Mike Updated the post to fetch filename
We are using this approach, apparently the most widely used in Angular. However it introduces a bug in accessibility, it can not be accessed via tab nor selected a file upon enter.
|
100

I think this is what you want:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>

<body>
  <button style="display:block;width:120px; height:30px;" onclick="document.getElementById('getFile').click()">Your text here</button>
  <input type='file' id="getFile" style="display:none">
</body>

</html>

4 Comments

best solution here so far.
This also handles keyboard navigation. To make it perfect, use tabindex="-1" on the hidden file input to skip it while tabbing.
One thing to note here: If the <button> is inside a <form> , that button will be treated as the "submit" button. This may not be the desired behavior!. To resolve this just add type attribute to the button <button type="button">
<label> tags with correctly set for attribute are clickable by default and activate the related file input and for that reason, I wouldn't recommend using <button> tags where setting onclick is required.
66

Each browser has it's own rendition of the control and as such you can't change either the text or the orientation of the control.

There are some "kind of" hacks you may want to try if you want an / solution rather than a Flash or solution.

http://www.quirksmode.org/dom/inputfile.html

http://www.shauninman.com/archive/2007/09/10/styling_file_inputs_with_css_and_the_dom

Personally, because most users stick to their browser of choice, and therefore are probably used to seeing the control in the default rendition, they'd probably get confused if they saw something different (depending on the types of users you're dealing with).

Comments

38

This might help someone in the future, you can style the label for the input as you like and put anything you want inside it and hide the input with display none.

It works perfectly on cordova with iOS

<link href="https://cdnjs.cloudflare.com/ajax/libs/ratchet/2.0.2/css/ratchet.css" rel="stylesheet"/>
<label for="imageUpload" class="btn btn-primary btn-block btn-outlined">Seleccionar imagenes</label>
<input type="file" id="imageUpload" accept="image/*" style="display: none">

Comments

23

To achieve this, the default input button must be hidden using display:none CSS property and a new button element is added to replace it, so we can customize as we wish.

With Bootstrap

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
 
Optional text here 

<label for="inputField" class="btn btn-info">Try me</label>
<input type="file" id="inputField" style="display:none">

With jQuery

In this case the onclick attribute added to the button element is indicating to JavaScript to click on the hidden default input button whenever the visible button is clicked.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Optional text here 

<button style="cursor:pointer" onclick="$('#inputField').click()">Click me</button>
<input type="file" id="inputField" style="display:none">

Plain JavaScript with event listener

document.getElementById('btn').addEventListener('click', () => { 
  document.getElementById('inputField').click();
})
Optional text here 
<button style="cursor:pointer" id="btn">Click me</button>
<input type="file" id="inputField" style="display:none">

Comments

12

It is not possible. Otherwise you may need to use Silverlight or Flash upload control.

3 Comments

Which is not possible? Changing text or placing button on right or both?
I upvoted this, because I think it's unfair to downvote this answer. It's basically impossible to change the text of the native file input button. The "possible solutions" are all hacks or workarounds.
@PeterLee - Hacks are solutions, some even follows the W3C spec.
9

$(document).ready(function () {
	$('#choose-file').change(function () {
		var i = $(this).prev('label').clone();
		var file = $('#choose-file')[0].files[0].name;
		$(this).prev('label').text(file);
	}); 
 });
.custom-file-upload{
  background: #f7f7f7; 
  padding: 8px;
  border: 1px solid #e3e3e3; 
  border-radius: 5px; 
  border: 1px solid #ccc; 
  display: inline-block;
  padding: 6px 12px;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
can you try this

<label for="choose-file" class="custom-file-upload" id="choose-file-label">
   Upload Document
</label>
<input name="uploadDocument" type="file" id="choose-file" 
   accept=".jpg,.jpeg,.pdf,doc,docx,application/msword,.png" style="display: none;" />

Comments

5

Update 2017:

I have done research on how this could be achieved. And the best explanation/tutorial is here: https://tympanus.net/codrops/2015/09/15/styling-customizing-file-inputs-smart-way/

I'll write summary here just in case it becomes unavailable. So you should have HTML:

<input type="file" name="file" id="file" class="inputfile" />
<label for="file">Choose a file</label>

Then hide the input with CSS:

.inputfile {
  width: 0.1px;
  height: 0.1px;
  opacity: 0;
  overflow: hidden;
  position: absolute;
  z-index: -1;
}

Then style the label:

.inputfile + label {
  font-size: 1.25em;
  font-weight: 700;
  color: white;
  background-color: black;
  display: inline-block;
}

Then optionally you can add JS to display the name of the file:

var inputs = document.querySelectorAll( '.inputfile' );
Array.prototype.forEach.call( inputs, function( input )
{
var label    = input.nextElementSibling,
    labelVal = label.innerHTML;

input.addEventListener( 'change', function( e )
{
    var fileName = '';
    if( this.files && this.files.length > 1 )
        fileName = ( this.getAttribute( 'data-multiple-caption' ) || '' ).replace( '{count}', this.files.length );
    else
        fileName = e.target.value.split( '\\' ).pop();

    if( fileName )
        label.querySelector( 'span' ).innerHTML = fileName;
    else
        label.innerHTML = labelVal;
});
});

But really just read the tutorial and download the demo, it's really good.

Comments

4

I made a script and published it at GitHub: get selectFile.js Easy to use, feel free to clone.


HTML

<input type=file hidden id=choose name=choose>
<input type=button onClick=getFile.simulate() value=getFile>
<label id=selected>Nothing selected</label>


JS

var getFile = new selectFile;
getFile.targets('choose','selected');


DEMO

jsfiddle.net/Thielicious/4oxmsy49/

2 Comments

That's good, but your code doesn't work when we need more than one input
@mehmet The OP did not ask for a solution with multiple file inputs.
4

You can use this approach, it works even if a lot of files inputs.

const fileBlocks = document.querySelectorAll('.file-block')
const buttons = document.querySelectorAll('.btn-select-file')

;[...buttons].forEach(function (btn) {
  btn.onclick = function () {
    btn.parentElement.querySelector('input[type="file"]').click()
  }
})

;[...fileBlocks].forEach(function (block) {
  block.querySelector('input[type="file"]').onchange = function () {
    const filename = this.files[0].name

    block.querySelector('.btn-select-file').textContent = 'File selected: ' + filename
  }
})
.btn-select-file {
  border-radius: 20px;
}

input[type="file"] {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="file-block">
  <button class="btn-select-file">Select Image 1</button>
  <input type="file">
</div>
<br>
<div class="file-block">
  <button class="btn-select-file">Select Image 2</button>
  <input type="file">
</div>

1 Comment

I like this approach, but for me Selected File text not showing up, any idea what is the issue. I am google chrome
4

The trick is to trigger a click event on click of the file input and manage the visibility of the default input file via CSS. Here's how you can do it:

jQuery:

$(function() {
  $("#labelfile").click(function() {
    $("#imageupl").trigger('click');
  });
})

css

.file {
  position: absolute;
  clip: rect(0px, 0px, 0px, 0px);
  display: block;
}

.labelfile {
  color: #333;
  background-color: #fff;
  display: inline-block;
  margin-bottom: 0;
  font-weight: 400;
  text-align: center;
  vertical-align: middle;
  cursor: pointer;
  background-image: none;
  white-space: nowrap;
  padding: 6px 8px;
  font-size: 14px;
  line-height: 1.42857143;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

HTML code:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
  <input name="imageupl" type="file" id="imageupl" class="file" />
  <label class="labelfile" id="labelfile"><i class="icon-download-alt"></i> Browse File</label>
</div>

Comments

3

This should work:

input.*className*::-webkit-file-upload-button {
  *style content..*
}

Comments

3

Here is how its done with bootstrap, only u should put the original input somewhere...idk in head and delete the < br > if you have it, because its only hidden and its taking space anyway :)

 <head> 
 <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
 </head>
 
 <label for="file" button type="file" name="image" class="btn btn-secondary">Secondary</button> </label>
    
 <input type="file" id="file" name="image" value="Prebrskaj" style="visibility:hidden;">
 
 
 <footer>
 
 <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
 
 </footer>

Comments

3

Using Bootstrap you can do this thing like the below code.

<!DOCTYPE html>
<html lang="en">
<head>

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

  </style>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
  <span class="btn btn-file">Upload image from here<input type="file">
</body>
</html>

1 Comment

This code does not print back to the web page what file was chosen.
3

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>

<body>
  <button style="display:block;width:120px; height:30px;" onclick="document.getElementById('getFile').click()">Your text here</button>
  <input type='file' id="getFile" style="display:none">
</body>

</html>

Comments

2

My solution...

HTML :

<input type="file" id="uploadImages" style="display:none;" multiple>

<input type="button" id="callUploadImages" value="Select">
<input type="button" id="uploadImagesInfo" value="0 file(s)." disabled>
<input type="button" id="uploadProductImages" value="Upload">

Jquery:

$('#callUploadImages').click(function(){

    $('#uploadImages').click();
});

$('#uploadImages').change(function(){

    var uploadImages = $(this);
    $('#uploadImagesInfo').val(uploadImages[0].files.length+" file(s).");
});

This is just evil :D

Comments

2

I build a script that can be easier to do that.

For example:

<input data-com="fileBtn" placeholder="Select Image">

basically, my script is very similar to this link

Code

Pure javascript, no dependencies needed

<!-- bootstrap.min.css not necessary -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.0/css/bootstrap.min.css">

<input data-com="fileBtn" placeholder="Select Image"> <!-- com: components -->
<input data-com="fileBtn" placeholder="Select File">
<div class="mt-2">
<input id="build-by-myself" placeholder="Select Video" accept="video/mp4, video/webm">
<div>

<script>
  // 👇 Test
  (()=>{
    window.onload = () =>{
      // FileButton.className ="btn btn-danger"
      FileButton.BuildAll() // auto build all data-com="fileBtn"
      
      // or you can specify the target that you wanted.
      new FileButton(document.getElementById("build-by-myself"), "btn btn-danger")
    }
  })()

  // 👇 script begin
  class FileButton {
    static className = "btn btn-primary"
    static BuildAll() {
      document.querySelectorAll(`input[data-com="fileBtn"]`).forEach(input=>{
        new FileButton(input, FileButton.className)
      })
    }
    /**
     * @param {HTMLInputElement} input
     * @param {string} btnClsName
     * */
    constructor(input, btnClsName) {
      input.style.display = "none" // [display is better than visibility](https://stackoverflow.com/a/48495293/9935654)
      input.type = "file"
      const frag = document.createRange().createContextualFragment(`<button class="${btnClsName}">${input.placeholder}</button>`)
      const button = frag.querySelector(`button`)

      input.parentNode.insertBefore(frag, input)

      button.onclick = ()=>{
        input.click()
      }
      input.addEventListener(`change`, (e)=>{
        // create a textNode to show the file name.
        const file = input.files[0]
        if (file === undefined) {
          return
        }
        const textNode = document.createTextNode(file.name)
        if (button.textNode) { // create a new attribute to record previous data.
          button.textNode.remove()
        }
        button.textNode = textNode
        button.parentNode.insertBefore(textNode, input)
      })
    }
  }
</script>

Reference

1 Comment

Definitely the best solution
1

Ok so very simple pure css way of creating your custom input file.

Use labels, but as you know from previous answers, label doesn't invoke onclick function in firefox, may be a bug but doesn't matter with the following.

<label for="file"  class="custom-file-input"><input type="file"  name="file" class="custom-file-input"></input></label>

What you do is style the label to look how you want it to

    .custom-file-input {
        color: transparent;/* This is to take away the browser text for file uploading*/
        /* Carry on with the style you want */
        background: url(../img/doc-o.png);
        background-size: 100%;
        position: absolute;
        width: 200px;
        height: 200px;
        cursor: pointer;
        top: 10%;
        right: 15%;
    }

now simply hide the actual input button, but you cant set it to to visability: hidden

So make in invisible by setting opacity: 0;

input.custom-file-input {
    opacity: 0;
    position: absolute;/*set position to be exactly over your input*/
    left: 0;
    top: 0;
}

now as you might have noticed i have the same class on my label as i do my input field, that is because i want the to both have the same styling, thus where ever you click on the label, you are actually clicking on the invisible input field.

Comments

1

I'd use a button to trigger the input:

<button onclick="document.getElementById('fileUpload').click()">Open from File...</button>
<input type="file" id="fileUpload" name="files" style="display:none" />

Quick and clean.

1 Comment

duplicate of the answer of Apr 20, 2017
1

Below is an example of a stylized upload button that will read an image, compress it, and download the resulting image. It works by hiding the actual input element, and then through some trickery we make it so that when you click on our fake file uploader it uses the actual input element to pop up the window for choosing a file. By using this method we get 100% control over how the file uploader looks since we are using our own element instead of styling the file upload menu. It also makes it easy to add drag and drop functionality in the future if we ever want to do that.

And then I actually created a series of blog posts about this file upload button.

'use strict'
  
var AMOUNT = 10
var WIDTH = 600
var HEIGHT = 400
var canvas = document.getElementById('canvas')
canvas.width = WIDTH
canvas.height = HEIGHT

//here's how I created the clickable area
//user clicks the clickable area > we send a click event
//to the file opener > the file opener clicks on the open
//file button > the open file dialogue pops up

function clickableAreaListener(e){
  let clickEvent = new CustomEvent("click",{"from":"fileOpenerHandler"});
  document.getElementById("fileOpener").dispatchEvent(clickEvent);
}
function fileOpenerListener(e) {
  document.getElementById("file-btn").click();
  e.preventDefault();
}

function fileSelectedListener(e){
    readFiles(e.target.files);
}

document.getElementById('file-btn').addEventListener('change', fileSelectedListener);
document.getElementById("clickable-area").addEventListener('click', clickableAreaListener);
document.getElementById("fileOpener").addEventListener("click", fileOpenerListener);

function readFiles(files){
  files = [].slice.call(files); //turning files into a normal array

  for (var file of files){
    var reader = new FileReader();

    reader.onload = createOnLoadHandler(file);
    reader.onerror = fileErrorHandler;
    //there are also reader.onloadstart, reader.onprogress, and reader.onloadend handlers

    reader.readAsDataURL(file);
  }
}
  
function fileErrorHandler(e) {
  switch(e.target.error.code) {
    case e.target.error.NOT_FOUND_ERR:
      throw 'Image not found';
      break;
    case e.target.error.NOT_READABLE_ERR:
      throw 'Image is not readable';
      break;
    case e.target.error.ABORT_ERR:
      break;
    default:
      throw 'An error occurred while reading the Image';
  };
}

function createOnLoadHandler(file){
  console.log('reading ' + file.name + ' of type ' + file.type) //file.type will be either image/jpeg or image/png
  
  function onLoad(e){
    var data = e.target.result
    display(data);
    var compressedData = compressCanvas(AMOUNT)
    download(compressedData)
  }
  
  return onLoad
}
  
function display(data){
  
    var img = document.createElement('img');
    img.src = data;
  
    var context = canvas.getContext('2d')
    context.clearRect(0, 0, WIDTH, HEIGHT);
    context.drawImage(img, 0, 0, WIDTH, HEIGHT);
  }

function compressCanvas(){
    return canvas.toDataURL('image/jpeg', AMOUNT / 100);
  }

function download(data) {

    function b64toBlob(b64Data, contentType, sliceSize) {
        contentType = contentType || '';
        sliceSize = sliceSize || 512;

        var byteCharacters = atob(b64Data);
        var byteArrays = [];

        for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
            var slice = byteCharacters.slice(offset, offset + sliceSize);

            var byteNumbers = new Array(slice.length);
            for (var i = 0; i < slice.length; i++) {
                byteNumbers[i] = slice.charCodeAt(i);
            }

            var byteArray = new Uint8Array(byteNumbers);

            byteArrays.push(byteArray);
        }

        var blob = new Blob(byteArrays, {type: contentType});
        return blob;
    }
    
    var chromeApp = Boolean(chrome && chrome.permissions)
    if (chromeApp){
    
      chrome.fileSystem.chooseEntry({type:'openDirectory'}, function(entry) {
        chrome.fileSystem.getWritableEntry(entry, function(entry) {
          entry.getFile('example.jpg', {create:true}, function(entry) {
            entry.createWriter(function(writer){
              writer.write(b64toBlob(data.slice(23), 'image/jpg'))
            })
          })
        })
      })
    
    } else {
      let a = document.createElement("a");
      a.href = data;
      a.download = 'downloadExample.jpg'
      document.body.appendChild(a)
      a.click();
      window.URL.revokeObjectURL(a.href);
      a.remove()
  }
    
}
.fileInput {
  display: none;
  position: absolute;
  top: 0;
  right: 0;
  font-size: 100px;
}
  
#clickable-area{
  background: #ccc;
  width: 500px;
  display: flex;
  margin-bottom: 50px;
}
  
#clickable-area-text{
  margin: auto;
}

.yellow-button {
  cursor: pointer;
  color: white;
  background: #f1c40f;
  height: 30px;
  width: 120px;
  padding: 30px;
  font-size: 22px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}
<div id="clickable-area">
  <a id='fileOpener'> </a>
  <input type="file" class="fileInput" id="file-btn" accept="image/*" multiple/>
  <div class="yellow-button"><span>Shrink Image</span>
  </div><p id="clickable-area-text">( you can click anywhere in here ) &nbsp;</p>
</div>
  
<canvas id="canvas"></canvas>

Stack Overflow limitations seem to prevent the code snippet from actually compressing and downloading the file. The exact same code here shows that the full upload/compress/download process does actually work as intended.

Comments

0

With answers from this question, I fixed what many in coments said doesn¨t work for them which is that it's not showing how many files user chose.

<label for="uploadedFiles" class="btn btn-sm btn-outline-primary">Choose files</label>
<input type="file" name="postedFiles" id="uploadedFiles" multiple="multiple" hidden onchange="javascript:updateList()" />
<input class="btn btn-primary mt-2 btn-action" type="submit" value="Send" formmethod="post" formaction="@Url.Action("Create")" /><br />
<span id="selected-count">Selected files: 0</span>
<script>
    updateList = function () {
        var input = document.getElementById('uploadedFiles');//list of files user uploaded
        var output = document.getElementById('selected-count');//element displaying count
        output.innerHTML = 'Selected files: ' + input.files.length;
    }
</script>

You can easily improve it by showing names of files instead or whatever you wish to do but all I wanted was to inform user that they have already picked files.

Comments

0

You can use a simple button and hide input file

using jquery and bootstrap :

HTML code

<button class="btn btn-white" id="btn-file" type="button"><i class="fa fa-file-pdf"></i> Anexar Documento</button>
<input name="shutdown" id="input-file" type="file" class="form-control hidden" accept="application/pdf, image/png, image/jpeg">

CSS :

.hidden{display:none}

JS :

$("#btn-file").click(function () {
    $("#input-file").trigger('click');
});

$("#input-file").change(function () {
    var file = $(this)[0].files[0].name;
    $("#btn-file").html('<i class="fa fa-file-pdf"></i> ' + file);
});

enter image description here

1 Comment

So besides that the JS is Jquery it's a plain duplicate of the answer of Apr 20, 2017
0

Customize Input Text (without jQuery)

If you want to customize the text of the file selector button, with vanilla JavaScript, here is a snippet:

document.querySelector("#files").onchange = function() {
  const fileName = this.files[0]?.name;
  const label = document.querySelector("label[for=files]");
  label.innerText = fileName ?? "Browse Files";
};
label {
  border: 1px solid #e5e5e5;
  border-radius: 10px;
  padding: 5px 10px;
  font-family: 'Helvetica', sans-serif;
  transition: .5s;
}

label:hover {
  background-color: #eee;
}
<div class="input_container">
  <label for="files" class="btn">Browse Files</label>
  <input id="files" style="display:none;" type="file">
</div>

I you wanted to style the file selector button, I have a solution for that: Styling an input type="file" button.

Comments

0

In Javascript you can give the input element a 'title' attribute, for example:

<input type="file" id="upload_photo" title=""onChange={onChangeTextHandle}/>

Comments

0

You can't directly modify it due to browser security restrictions.

But, you can hide one input and create your input with the text you need:

**Please do NOT use display: none. It would not work with it.

<div>
  <label>
        <span>Choose my file</span>
        <input type="file" hidden  />
        <input
          type="text"
          placeholder="Upload your file"
        />
      </label>
</div>
label {
     background-color: #f0f0f0;
    width: 300px;
    border-radius: 5px;
    cursor: pointer;
    padding: 8px 0px 10px 10px;
    background:  #C69F89
 
}
label:hover{
 background: #A6A15E
}

input[type="text"] {
  margin-top: 30px;
  
  padding: 10px 5px;
  border: 1px solid #ccc;
  border-radius: 0px 4px 4px 0px;
  width: 300px;
}

1 Comment

Here is the same example, but with tailwind and React: codesandbox.io/p/live/ffb74e3b-3046-46a3-84f5-1cec55b90004
-1

Pure CSS solution:

.inputfile {
  /* visibility: hidden etc. wont work */
  width: 0.1px;
  height: 0.1px;
  opacity: 0;
  overflow: hidden;
  position: absolute;
  z-index: -1;
}
.inputfile:focus + label {
  /* keyboard navigation */
  outline: 1px dotted #000;
  outline: -webkit-focus-ring-color auto 5px;
}
.inputfile + label * {
  pointer-events: none;
}
<input type="file" name="file" id="file" class="inputfile" />
<label for="file">Choose a file (Click me)</label>

source: http://tympanus.net/codrops

(You could also just style the button with ::file-selector-button, but that doesn't allow you to change its text.)

Comments

-1

Here is a solution that also shows the selected files in the same way as the unmodified one but can have the text and style of the button be set. It also does not need any external libraries/modules, it is 100% customizable, it even displays the full list of selected files in the title property, just like the actual file input type:

<script>
  window.onload = ()=>{
    sourceElement.addEventListener("change", async(e) => {
      if(sourceElement.files.length==0){
        afterChooseFileButtonB.innerText="No file chosen"
        sourceElementLabel.title="No file chosen"
      }else{
        afterChooseFileButtonB.innerText=sourceElement.files[0].name
        sourceElementLabel.title=inputElement.files[0].name
      }
    })
    inputElement.addEventListener("change", () => {
      if(inputElement.files.length==0){
        afterChooseFileButtonA.innerText="No file chosen, please choose one or more files"
        inputElementLabel.title="No file chosen, one or more files are required"
      }else if(inputElement.files.length!=1){
        afterChooseFileButtonA.innerText=inputElement.files.length+" files"
        inputElementLabel.title=Object.values(inputElement.files).map(file=>file.name).join("\n")
      }else{
        afterChooseFileButtonA.innerText=inputElement.files[0].name
        inputElementLabel.title=inputElement.files[0].name
      }
    })
  }
</script>
<label for="inputElement" style="font-family: monospace;" form="mainform" id="inputElementLabel" title="No file chosen, one or more files are required">Target Files: 
  <button style="font-family: monospace; background-color: #87ceeb;" onclick="inputElement.click()">
    <u>Please</u> <b>Choose</b> <span style="color: red;">Target</span> <em>Files</em>
  </button>
  <span id="afterChooseFileButtonA">No file chosen, please choose one or more files</span>
</label>
<input type="file" id="inputElement" multiple="" name="inputElement" style="font-family: monospace; display: none;" form="mainform">
<br>
<label for="sourceElement" style="font-family: monospace;" form="mainform" id="sourceElementLabel" title="No file chosen">Source File: 
  <button style="font-family: monospace; background-color: #87ceeb;" onclick="sourceElement.click()">
    Choose The Source File
  </button>
  <span id="afterChooseFileButtonB">No file chosen</span>
</label>
<input type="file" id="sourceElement" name="sourceElement" style="font-family: monospace; display: none;" form="mainform">

Here is another variation with regularly styled buttons:

<script>
  window.onload = ()=>{
    sourceElement.addEventListener("change", async(e) => {
      if(sourceElement.files.length==0){
        afterChooseFileButtonB.innerText="No file chosen"
        sourceElementLabel.title="No file chosen"
      }else{
        afterChooseFileButtonB.innerText=sourceElement.files[0].name
        sourceElementLabel.title=inputElement.files[0].name
      }
    })
    inputElement.addEventListener("change", () => {
      if(inputElement.files.length==0){
        afterChooseFileButtonA.innerText="No file chosen, please choose one or more files"
        inputElementLabel.title="No file chosen, one or more files are required"
      }else if(inputElement.files.length!=1){
        afterChooseFileButtonA.innerText=inputElement.files.length+" files"
        inputElementLabel.title=Object.values(inputElement.files).map(file=>file.name).join("\n")
      }else{
        afterChooseFileButtonA.innerText=inputElement.files[0].name
        inputElementLabel.title=inputElement.files[0].name
      }
    })
  }
 </script>
<label for="inputElement" style="font-family: monospace;" form="mainform" id="inputElementLabel" title="No file chosen, one or more files are required">Target Files: 
  <button style="font-family: monospace;" onclick="inputElement.click()">
    <u>Please</u> <b>Choose</b> <span style="color: red;">Target</span> <em>Files</em>
  </button>
  <span id="afterChooseFileButtonA">No file chosen, please choose one or more files</span>
</label>
<input type="file" id="inputElement" multiple="" name="inputElement" style="font-family: monospace; display: none;" form="mainform">
<br>
<label for="sourceElement" style="font-family: monospace;" form="mainform" id="sourceElementLabel" title="No file chosen">Source File: 
  <button style="font-family: monospace;" onclick="sourceElement.click()">
    Choose The Source File
  </button>
  <span id="afterChooseFileButtonB">No file chosen</span>
</label>
<input type="file" id="sourceElement" name="sourceElement" style="font-family: monospace; display: none;" form="mainform">

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.