<input type="file"> #
::: section-content
<input>
elements with type="file"
let the user choose
one or more files from their device storage. Once chosen, the files can
be uploaded to a server using
form
submission, or
manipulated using JavaScript code and
the File
API.
:::
Try it #
::: section-content ::: iframe ::: {.output-header .border-rounded-top}
HTML Demo: <input type="file"> #
Reset :::
::: {#warning-no-script .warning-container} ::: warning The interactive example cannot be shown because JavaScript is disabled. ::: :::
::: {#warning-mathml-not-supported .warning-container .hidden} ::: warning The interactive example cannot be shown because MathML is not supported by your browser. ::: :::
::: {#editor-container .editor-container .tabbed-shorter .hidden .border-rounded-bottom editor-type=“tabbed”} ::: {#tab-container .section .tabs} ::: {#tablist .tab-list role=“tablist”} HTML
CSS
JavaScript :::
::: {#html-panel .section .hidden tabindex=“0” role=“tabpanel” aria-labelledby=“html” aria-hidden=“true”} ::: {#html-editor}
<input type="file" id="avatar" name="avatar" accept="image/png, image/jpeg" />
::: :::
::: {#css-panel .section .hidden tabindex=“0” role=“tabpanel” aria-labelledby=“css” aria-hidden=“true”} ::: {#css-editor} label { display: block; font: 1rem ‘Fira Sans’, sans-serif; }
input,
label {
margin: 0.4rem 0;
}
::: :::
::: {#js-panel .section .hidden tabindex=“0” role=“tabpanel” aria-labelledby=“js” aria-hidden=“true”} ::: {#js-editor} ::: ::: :::
::: {#output .output-container}
Output #
::: :::
::: {.section .console-container .hidden aria-hidden=“true”}
Console Output #
![] clear console
::: {#console .console} ::: :::
::: {#html-output .output .editor-tabbed} %html-content% ::: ::: :::
Value #
::: section-content
A file input's
value
attribute contains a string
that represents the path to the selected file(s). If no file is selected
yet, the value is an empty string (""
). When the user selected
multiple files, the value
represents the first file in the list of
files they selected. The other files can be identified using the
input's HTMLInputElement.files
property.
::: {#sect1 .notecard .note}
Note: The value is
always the file's name prefixed with
C:\fakepath\
{target="_blank"},
which isn't the real path of the file. This is to prevent malicious
software from guessing the user's file structure.
:::
:::
Additional attributes #
::: section-content
In addition to the common attributes shared by all
<input>
elements, inputs of type file
also support the following attributes.
:::
accept #
::: section-content
The
accept
attribute value is a string that
defines the file types the file input should accept. This string is a
comma-separated list of unique file type
specifiers. Because a given file type
may be identified in more than one manner, it's useful to provide a
thorough set of type specifiers when you need files of a given format.
For instance, there are a number of ways Microsoft Word files can be
identified, so a site that accepts Word files might use an <input>
like this:
::: code-example [html]{.language-name}
<input
type="file"
id="docpicker"
accept=".doc,.docx,.xml,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
::: :::
capture #
::: section-content
The
capture
attribute value is a string
that specifies which camera to use for capture of image or video data,
if the
accept
attribute indicates that the
input should be of one of those types. A value of user
indicates that
the user-facing camera and/or microphone should be used. A value of
environment
specifies that the outward-facing camera and/or microphone
should be used. If this attribute is missing, the
user
agent is
free to decide on its own what to do. If the requested facing mode
isn't available, the user agent may fall back to its preferred default
mode.
::: {#sect2 .notecard .note}
Note: capture
was previously a Boolean attribute which, if
present, requested that the device's media capture device(s) such as
camera or microphone be used instead of requesting a file input.
:::
:::
multiple #
::: section-content
When the
multiple
Boolean attribute is
specified, the file input allows the user to select more than one file.
:::
Non-standard attributes #
::: section-content In addition to the attributes listed above, the following non-standard attributes are available on some browsers. You should try to avoid using them when possible, since doing so will limit the ability of your code to function in browsers that don't implement them. :::
webkitdirectory
#
::: section-content
The Boolean webkitdirectory
attribute, if present, indicates that only
directories should be available to be selected by the user in the file
picker interface. See
HTMLInputElement.webkitdirectory
for additional details and examples.
Though originally implemented only for WebKit-based browsers,
webkitdirectory
is also usable in Microsoft Edge as well as Firefox 50
and later. However, even though it has relatively broad support, it is
still not standard and should not be used unless you have no
alternative.
:::
Unique file type specifiers #
::: section-content
A unique file type specifier is a string that describes a type of
file that may be selected by the user in an
<input>
element of type file
. Each unique file type specifier may take one of
the following forms:
- A valid case-insensitive filename extension, starting with a period
(".") character. For example:
.jpg
,.pdf
, or.doc
. - A valid MIME type string, with no extensions.
- The string
audio/*
meaning "any audio file". - The string
video/*
meaning "any video file". - The string
image/*
meaning "any image file".
The accept
attribute takes a string containing one or more of these
unique file type specifiers as its value, separated by commas. For
example, a file picker that needs content that can be presented as an
image, including both standard image formats and PDF files, might look
like this:
::: code-example [html]{.language-name}
<input type="file" accept="image/*,.pdf" />
::: :::
Using file inputs #
A basic example #
::: section-content ::: code-example [html]{.language-name}
<form method="post" enctype="multipart/form-data">
<label for="file">Choose file to upload</label>
<input type="file" id="file" name="file" multiple />
<button>Submit</button>
</form>
:::
This produces the following output:
::: {#sect3 .code-example} ::: iframe ::: :::
::: {#sect4 .notecard .note} Note: You can find this example on GitHub too — see the source code{target="_blank"}, and also see it running live{target="_blank"}. :::
Regardless of the user's device or operating system, the file input provides a button that opens up a file picker dialog that allows the user to choose a file.
Including the
multiple
attribute, as shown above,
specifies that multiple files can be chosen at once. The user can choose
multiple files from the file picker in any way that their chosen
platform allows (e.g. by holding down [Shift]{.kbd} or [Control]{.kbd}
and then clicking). If you only want the user to choose a single file
per <input>
, omit the multiple
attribute.
:::
Getting information on selected files #
::: section-content
The selected files' are returned by the element's
HTMLInputElement.files
property, which is a
FileList
object containing a list of
File
objects.
The FileList
behaves like an array, so you can check its length
property to get the number of selected files.
Each File
object contains the following information:
name
The file's name.
lastModified
A number specifying the date and time at which the file was last modified, in milliseconds since the UNIX epoch (January 1, 1970 at midnight).
lastModifiedDate
[Deprecated]{.visually-hidden}A
Date
object representing the date and time at which the file was last modified. This is deprecated and should not be used. UselastModified
instead.size
The size of the file in bytes.
type
The file's MIME type.
webkitRelativePath
[Non-standard]{.visually-hidden}A string specifying the file's path relative to the base directory selected in a directory picker (that is, a
file
picker in which thewebkitdirectory
attribute is set). This is non-standard and should be used with caution.
::: {#sect5 .notecard .note}
Note: You can set as well as get the value of
HTMLInputElement.files
in all modern browsers; this was most recently
added to Firefox, in version 57 (see
Firefox bug
1384030{target="_blank"}).
:::
:::
Limiting accepted file types #
::: section-content Often you won't want the user to be able to pick any arbitrary type of file; instead, you often want them to select files of a specific type or types. For example, if your file input lets users upload a profile picture, you probably want them to select web-compatible image formats, such as JPEG or PNG.
Acceptable file types can be specified with the
accept
attribute, which takes a comma-separated list of allowed file extensions
or MIME types. Some examples:
accept="image/png"
oraccept=".png"
— Accepts PNG files.accept="image/png, image/jpeg"
oraccept=".png, .jpg, .jpeg"
— Accept PNG or JPEG files.accept="image/*"
— Accept any file with animage/*
MIME type. (Many mobile devices also let the user take a picture with the camera when this is used.)accept=".doc,.docx,.xml,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document"
— accept anything that smells like an MS Word document.
Let's look at a more complete example:
::: code-example [html]{.language-name}
<form method="post" enctype="multipart/form-data">
<label for="profile_pic">Choose file to upload</label>
<input
type="file"
id="profile_pic"
name="profile_pic"
accept=".jpg, .jpeg, .png" />
<button>Submit</button>
</form>
:::
This produces a similar-looking output to the previous example:
::: {#sect6 .code-example} ::: iframe ::: :::
::: {#sect7 .notecard .note} Note: You can find this example on GitHub too — see the source code{target="_blank"}, and also see it running live{target="_blank"}. :::
It may look similar, but if you try selecting a file with this input,
you'll see that the file picker only lets you select the file types
specified in the accept
value (the exact interface differs across
browsers and operating systems).
The accept
attribute doesn't validate the types of the selected
files; it provides hints for browsers to guide users towards selecting
the correct file types. It is still possible (in most cases) for users
to toggle an option in the file chooser that makes it possible to
override this and select any file they wish, and then choose incorrect
file types.
Because of this, you should make sure that the accept
attribute is
backed up by appropriate server-side validation.
:::
Notes #
::: section-content
You cannot set the value of a file picker from a script — doing something like the following has no effect:
::: code-example [js]{.language-name}
const input = document.querySelector("input[type=file]"); input.value = "foo";
:::
When a file is chosen using an
<input type="file">
, the real path to the source file is not shown in the input'svalue
attribute for obvious security reasons. Instead, the filename is shown, withC:\fakepath\
prepended to it. There are some historical reasons for this quirk, but it is supported across all modern browsers, and in fact is defined in the spec{target="_blank"}. :::
Examples #
::: section-content
In this example, we'll present a slightly more advanced file chooser
that takes advantage of the file information available in the
HTMLInputElement.files
property, as well as showing off a few clever
tricks.
::: {#sect8 .notecard .note} Note: You can see the complete source code for this example on GitHub — file-example.html{target="_blank"} ( see it live also{target="_blank"}). We won't explain the CSS; the JavaScript is the main focus. :::
First of all, let's look at the HTML:
::: code-example [html]{.language-name}
<form method="post" enctype="multipart/form-data">
<label for="image_uploads">Choose images to upload (PNG, JPG)</label>
<input
type="file"
id="image_uploads"
name="image_uploads"
accept=".jpg, .jpeg, .png"
multiple />
<div class="preview">
<p>No files currently selected for upload</p>
<button>Submit</button>
</form>
:::
This is similar to what we've seen before — nothing special to comment on.
Next, let's walk through the JavaScript.
In the first lines of script, we get references to the form input
itself, and the
`` element with the class of .preview
.
Next, we hide the
<input>
element — we do this because
file inputs tend to be ugly, difficult to style, and inconsistent in
their design across browsers. You can activate the input
element by
clicking its
<label>
, so it is better to visually hide the
input
and style the label like a button, so the user will know to
interact with it if they want to upload files.
::: code-example [js]{.language-name}
const input = document.querySelector("input");
const preview = document.querySelector(".preview");
input.style.opacity = 0;
:::
::: {#sect9 .notecard .note}
Note:
opacity
is
used to hide the file input instead of
visibility: hidden
or
display: none
,
because assistive technology interprets the latter two styles to mean
the file input isn't interactive.
:::
Next, we add an
event
listener
to the input to listen for changes to its selected value (in this case,
when files are selected). The event listener invokes our custom
updateImageDisplay()
function.
::: code-example [js]{.language-name}
input.addEventListener("change", updateImageDisplay);
:::
Whenever the updateImageDisplay()
function is invoked, we:
- Use a
while
loop to empty the previous contents of the preview ``. - Grab the
FileList
object that contains the information on all the selected files, and store it in a variable calledcurFiles
. - Check to see if no files were selected, by checking if
curFiles.length
is equal to 0. If so, print a message into the preview `` stating that no files have been selected. - If files have been selected, we loop through each one, printing information about it into the preview ``. Things to note here:
- We use the custom
validFileType()
function to check whether the file is of the correct type (e.g. the image types specified in theaccept
attribute). - If it is, we:
- Print out its name and file size into a list item inside the
previous `` (obtained from
file.name
andfile.size
). The customreturnFileSize()
function returns a nicely-formatted version of the size in bytes/KB/MB (by default the browser reports the size in absolute bytes). - Generate a thumbnail preview of the image by calling
URL.createObjectURL(file)
. Then, insert the image into the list item too by creating a new<img>
and setting itssrc
to the thumbnail.
- Print out its name and file size into a list item inside the
previous `` (obtained from
- If the file type is invalid, we display a message inside a list item telling the user that they need to select a different file type.
::: code-example [js]{.language-name}
function updateImageDisplay() {
while (preview.firstChild) {
preview.removeChild(preview.firstChild);
}
const curFiles = input.files;
if (curFiles.length === 0) {
const para = document.createElement("p");
para.textContent = "No files currently selected for upload";
preview.appendChild(para);
} else {
const list = document.createElement("ol");
preview.appendChild(list);
for (const file of curFiles) {
const listItem = document.createElement("li");
const para = document.createElement("p");
if (validFileType(file)) {
para.textContent = `File name ${file.name}, file size ${returnFileSize(
file.size,
)}.`;
const image = document.createElement("img");
image.src = URL.createObjectURL(file);
listItem.appendChild(image);
listItem.appendChild(para);
} else {
para.textContent = `File name ${file.name}: Not a valid file type. Update your selection.`;
listItem.appendChild(para);
}
list.appendChild(listItem);
}
}
}
:::
The custom validFileType()
function takes a
File
object
as a parameter, then uses
Array.prototype.includes()
to check if any value in the fileTypes
matches the file's type
property. If a match is found, the function returns true
. If no match
is found, it returns false
.
::: code-example [js]{.language-name}
// https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types
const fileTypes = [
"image/apng",
"image/bmp",
"image/gif",
"image/jpeg",
"image/pjpeg",
"image/png",
"image/svg+xml",
"image/tiff",
"image/webp",
"image/x-icon",
];
function validFileType(file) {
return fileTypes.includes(file.type);
}
:::
The returnFileSize()
function takes a number (of bytes, taken from the
current file's size
property), and turns it into a nicely formatted
size in bytes/KB/MB.
::: code-example [js]{.language-name}
function returnFileSize(number) {
if (number < 1024) {
return `${number} bytes`;
} else if (number >= 1024 && number < 1048576) {
return `${(number / 1024).toFixed(1)} KB`;
} else if (number >= 1048576) {
return `${(number / 1048576).toFixed(1)} MB`;
}
}
:::
The example looks like this; have a play:
::: {#sect10 .code-example} ::: iframe ::: ::: :::
Technical summary #
::: section-content
Value | A string representing the path to the selected file. |
Events | change
and input |
Supported common attributes | required |
Additional Attributes | accept , capture , multiple |
IDL attributes | files and value |
DOM interface | |
Methods | select() |
Implicit ARIA Role | no corresponding role |
Specifications #
::: _table #
Specification #
HTML Standard
[#
file-upload-state-(type=file)]{.small}
:::
Browser compatibility #
::: _table #
Desktop Mobile
Chrome Edge Firefox Internet Opera Safari WebView Chrome Firefox Opera Safari Samsung
Explorer Android Android for Android on IOS Internet
Android
file
1 12 1 Yes 11 1 4.4 18 4 11 1 1.0
You can set as well as get the value of
`HTMLInputElement.files` in all modern
browsers; this was most recently added
to Firefox, in version 57 (see [bug
1384030](https://bugzil.la/1384030)).
:::
See also #
::: section-content
- Using files from web
applications
— contains a number of other useful examples related to
<input type="file">
and the File API. - Compatibility of CSS properties :::
::: _attribution
© 2005–2023 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5
or later.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file{._attribution-link}
:::