10

Is it impossible change choose file text of input file in Bootstrap 5 using CSS like Bootstrap 4?

And how can I add a margin to "No file chosen"?

enter image description here

Gleb Kemarsky
  • 10,160
  • 7
  • 43
  • 68
Morteza Negahi
  • 3,305
  • 8
  • 24
  • 42
  • Same question for [Bootstrap 4](https://stackoverflow.com/q/43250263/) – Gleb Kemarsky Dec 31 '21 at 14:26
  • Have a try on this, some tricks are used but just works fine. [stackoverflow.com/a/73138618/8706905](https://stackoverflow.com/a/73138618/8706905) – SteveHu Aug 09 '22 at 03:30

6 Answers6

18

Bootstrap 5 + some CSS

  1. Compose Bootstrap's custom file input with custom label.
  2. Hide default Choose file button with the ::file-selector-button pseudo-element. There are pseudo-elements ::-webkit-file-upload-button and ::-ms-browse for older versions of Chrome/Opera/Safari and Edge/IE respectively. But bootstrap.css uses ::file-selector-button and ::-webkit-file-upload-button only. So I propose to do the same.
  3. Add some more CSS for the :hover effect and for the thin border between the label and the input field.

Tested in Chrome, Firefox and Edge.

https://codepen.io/glebkema/pen/VwMQWGE

.custom-file-button input[type=file] {
  margin-left: -2px !important;
}

.custom-file-button input[type=file]::-webkit-file-upload-button {
  display: none;
}

.custom-file-button input[type=file]::file-selector-button {
  display: none;
}

.custom-file-button:hover label {
  background-color: #dde0e3;
  cursor: pointer;
}
<div class="container py-3">

  <div class="input-group custom-file-button">
    <label class="input-group-text" for="inputGroupFile">Your Custom Text</label>
    <input type="file" class="form-control" id="inputGroupFile">
  </div>

</div>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css">
Gleb Kemarsky
  • 10,160
  • 7
  • 43
  • 68
3

If the file input is placed inside the label element and then hidden the label itself will act as the file input when it is clicked. Adding the form-control class and the tabindex attribute (which specifies that the element can be focused) to the label will then style it like a generic Bootstrap input.

<div class="input-group">
  <span class="input-group-text">Custom Add-on Text</span>
  <label class="form-control" tabindex="0">Custom Input Text
    <input type="file" class="invisible">
  </label>
</div>

https://codepen.io/yetiface/pen/PoQqrda

This solution has its downsides, for example the label element will not automatically receive bootstrap styles specifically for input[type='file']. However it is such a simple method that I felt it worth posting for those who it can help.

Yeti_Face
  • 76
  • 4
2

I needed to change both texts so this method helped

$('#review-image').change(function(e) {
    let fileName = (e.target.files.length > 0) ? e.target.files[0].name : 'choose_file_not';
    $('#review-image-label').text(fileName);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">


<div class="container mt-3">
  <div class="input-group custom-file-button">
    <label class="input-group-text" for="review-image" role="button">choose_file</label>
    <label for="review-image" class="form-control" id="review-image-label" role="button">choose_file_not</label>
    <input type="file" class="d-none" id="review-image" name="images[]" multiple accept="image/*">
  </div>
</div>
Akbarali
  • 688
  • 7
  • 16
0

Bootstrap 5 beta no longer provides a custom file input like Bootstrap 4 that used pseudo elements to override the browser's file input defaults. Therefore you'd have to use JS or make your own psuedo element to hide the Choose file.. area of the input...

#formFile::before {
  content: "Pick file";
  position: absolute;
  z-index: 2;
  display: block;
  background-color: #eee;
  width: 80px;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

<div class="container min-vh-100 py-2">
  <div class="row">
    <div class="col">
      <div class="mb-3">
        <input class="form-control" type="file" id="formFile">
      </div>
    </div>
  </div>
</div>
isherwood
  • 58,414
  • 16
  • 114
  • 157
Carol Skelly
  • 351,302
  • 90
  • 710
  • 624
0

I created an input group with a label, the input, and then appended another label. This way you can style it however you want and put custom text as the input group text. You then hide the input element (display:none or width:0 or something)

Examples:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

<p>Label before</p>

<div class='input-group'>
  <label class='input-group-prepend'>
    <div class='input-group-text form-control' for='file-input-thing'>Pick File</div>
  </div>
  <input type='file' id='file-input-thing' style='width:0;'>
  <label id='file-input-label' class='form-control' for='file-input-thing'/>
</div>

<p>Label after</p>

<div class='input-group'>
  <label id='file-input-label' class='form-control' for='file-input-thing'/>
  <input type='file' id='file-input-thing' style='width:0;'>
  <div class='input-group-append'>
    <label class='input-group-text form-control' for='file-input-thing'>
  </div>
</div>

You can then assign styling to labels as you see fit. By making both piece labels tied into the input element it allows you to click on either and choose a file. Further you can add an ID to the blank label and update the value to the name of the file.

let inputElement = document.getElementById('file-input-thing');
let inputLabel= document.getElementById('file-input-label');

inputElement.addEventListener('change', function(e) {
  let file = e.target.files[0];
  inputLabel.innerHTML = file.name;
})

I'm new to all this so there's probably a better solution, but this worked for me.

isherwood
  • 58,414
  • 16
  • 114
  • 157
Mark Y
  • 36
  • 3
  • I converted your markup to a snippet. Looks like it needs some polish. There are extra closing div tags, and you wouldn't want two labels for an input. – isherwood Dec 22 '21 at 22:50
0

This is how I have implemented it, just copy-paste it to your code and you'll see the results

<Button onClick={() => document.getElementById('imageFileSelect').click()}>Choose Image</Button>
<input className="form-control d-none"  id='imageFileSelect' type="file" onChange={imageSelected}></input>
Jacob
  • 1
  • 1
  • 1
  • 3
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 29 '21 at 19:06