File input (Requires JavaScript)

File inputs are form-controls which can be used to allow users to browse through local files and select one (or more). Halfmoon comes with a custom file input design which works across browsers. The multiple="..." attribute is supported, which can be used to create multi-file inputs.

<!-- File input -->
<div class="custom-file">
  <input type="file" id="file-input-1">
  <label for="file-input-1">Choose a file</label>
</div>

<!-- Multi-file input -->
<div class="custom-file">
  <input type="file" id="multi-file-input-1" multiple="multiple" accept=".jpg,.png,.gif">
  <label for="multi-file-input-1">Choose images</label>
</div>

<!-- Requires halfmoon.js -->
<script src="path/to/halfmoon.js"></script>

The following things should be kept in mind when using custom file inputs in Halfmoon:

  • The <label> element is a requirement, as without it, the custom file input will not be rendered.
  • The <input> element must have the type="file" attribute.
  • The <label> element must come after the <input> element in the container with the .custom-file class.
  • The id="..." attribute of the input and the for="..." attribute of the label should have the same value.
  • The accept="..." attribute can be used to make sure only certain types of files are accepted by the input.
  • The core JavaScript file is required for the file inputs to work properly, mainly to update the file(s) chosen.
  • Containers with the class .custom-file have no margins (margin: 0) by default. The vertically stacked ones on this page are styled to have a margin on the bottom using a utility class. This is not shown in the code for the sake of conciseness. We recommend using a wrapper with the .form-group class inside forms. This will add a margin between the elements. See the example here (opens in new tab).

Setting default values #

By default, the string "No file chosen" is appended to the container with the class .custom-file. However, this can be easily overridden by adding the data-default-value="..." attribute on the file input. The contents of this attribute can also be HTML as string, and Halfmoon will render that underneath the file input button.

<div class="custom-file">
  <input type="file" id="file-input-2" data-default-value="No CV chosen">
  <label for="file-input-2">Choose CV</label>
</div>

<div class="custom-file">
  <input type="file" id="file-input-3" data-default-value="<a href='...' class='hyperlink' target='_blank' rel='noopener'>cute-cat.jpg</a>" accept=".jpg,.png,.gif">
  <label for="file-input-3">Choose picture</label>
</div>

<!-- Requires halfmoon.js -->
<script src="path/to/halfmoon.js"></script>

The last example illustrates how files coming in from storage sites (such as S3, Cloudinary, etc.) can be set as default values on forms for the file inputs.

Disabled file inputs #

File inputs can be disabled by adding the disabled="..." attribute to them.

<!-- Disabled file input -->
<div class="custom-file">
  <input type="file" id="file-input-4" disabled="disabled">
  <label for="file-input-4">Choose a file</label>
</div>

<!-- Requires halfmoon.js -->
<script src="path/to/halfmoon.js"></script>

Invalid file inputs #

Adding the class .is-invalid to a file input provides a visual cue to the users that the chosen file (or the lack of one) is invalid. This can also be achieved by adding the .is-invalid class to a parent container with the .form-group class.

The file is corrupted.
<!-- Invalid file input -->
<div class="custom-file">
  <input type="file" id="file-input-5" class="is-invalid">
  <label for="file-input-5">Choose a file</label>
</div>

<!-- Invalid file input through parent container -->
<div class="form-group is-invalid">
  <div class="invalid-feedback">
    The file is corrupted.
  </div>
  <div class="custom-file">
    <input type="file" id="file-input-6" data-default-value="spreadsheet.xls">
    <label for="file-input-6">Choose a file</label>
  </div>
</div>

<!-- Requires halfmoon.js -->
<script src="path/to/halfmoon.js"></script>

Up next: Input group