Basic single-file picker
The only required content is one file input and its associated label.
Any file type
Without accept or multiple,
the first dropped file is selected and any additional
files are rejected with an accessible announcement.
<form-dropzone>
<label for="basic-file">Choose a file</label>
<input
id="basic-file"
name="basic-file"
type="file" />
</form-dropzone>
Multiple files and accept
Dropped files are checked against extension, exact MIME, and wildcard MIME accept tokens.
Mixed accept syntax
This input accepts PDF filenames, plain text MIME types, and any image MIME type. A mixed drop keeps the valid files and announces each rejection.
<form-dropzone>
<label for="mixed-files">Choose documents or images</label>
<input
id="mixed-files"
name="mixed-files"
type="file"
accept=".pdf,text/plain,image/*"
multiple />
</form-dropzone>
Image previews
The boolean preview-images attribute renders
image selections from the picker or a drop in a responsive
Light DOM grid.
Multiple image preview grid
Non-image files can remain selected when allowed by the input, but only image MIME types are previewed.
<form-dropzone preview-images>
<label for="preview-images">Choose images</label>
<input
id="preview-images"
name="preview-images"
type="file"
accept="image/*"
multiple />
</form-dropzone>
Localization and custom announcements
Visible instructions and all drop-result messages can be
translated independently. Announcement templates support
{count} and {files}.
Custom English announcements
Drop multiple PDFs plus a non-PDF file to produce received, file-type rejection, and single-file limit messages in one announcement. The visible log mirrors the component's visually hidden live region for this demo.
The default announcement templates are:
-
received-message="Received: {files}." -
rejected-type-message="Rejected because the file type is not accepted: {files}." -
rejected-multiple-message="Rejected because only one file is allowed: {files}."
<form-dropzone
received-message="Ready to upload {count}: {files}."
rejected-type-message="Not accepted: {files}. Choose a PDF."
rejected-multiple-message="Only the first PDF was added. Extra: {files}.">
<label for="custom-announcements">Choose one PDF</label>
<input
id="custom-announcements"
name="custom-announcements"
type="file"
accept=".pdf" />
</form-dropzone>
French text and messages
Drop more than one PDF to hear both the received and single-file rejection messages.
<form-dropzone
drop-label="Déposez les fichiers ici"
separator-label="ou"
received-message="{count} fichier(s) reçu(s) : {files}."
rejected-type-message="Type refusé : {files}."
rejected-multiple-message="Un seul fichier est autorisé. Refusé : {files}.">
<label for="french-pdf">Choisir un PDF</label>
<input
id="french-pdf"
name="french-pdf"
type="file"
accept=".pdf" />
</form-dropzone>
Wrapping label association
The native label may use for/id
or wrap the file input directly.
Input nested in its label
This pattern remains fully functional before custom element registration and when drag-and-drop is unavailable.
<form-dropzone>
<label>
Choose a spreadsheet
<input
name="spreadsheet"
type="file"
accept=".csv,.xlsx" />
</label>
</form-dropzone>
Custom Light DOM styling
Default rules use low-specificity selectors, so normal author CSS can override alignment, borders, drag state, and preview elements.
Left-aligned circular previews
This example uses the enhancement state class and generated Light DOM preview classes.
<style>
.custom-dropzone {
align-items: start;
min-block-size: 10rem;
text-align: start;
}
.custom-dropzone input[type="file"] {
background: transparent;
border: 0;
padding: 0;
}
.custom-dropzone input[type="file"]::file-selector-button {
background: #4f3ca7;
border: 0;
border-radius: 0.5rem;
color: white;
cursor: pointer;
font: inherit;
margin-inline-end: 0.75rem;
padding: 0.65rem 1rem;
}
.custom-dropzone input[type="file"]::file-selector-button:hover {
background: #392b7a;
}
.custom-dropzone .form-dropzone__preview-image {
border-radius: 50%;
max-block-size: 200px;
max-inline-size: 200px;
}
</style>
<form-dropzone
class="custom-dropzone"
preview-images>
<label for="styled-images">Choose profile images</label>
<input
id="styled-images"
name="styled-images"
type="file"
accept="image/*"
multiple />
</form-dropzone>
API reference
For complete attribute, property, styling-hook, progressive-enhancement, and browser-support documentation, see the README.