About this set
Two drag-and-drop file upload zones built around a real file input. Dropzone with file list is the familiar dashed box with an upload icon, a Drag and drop or browse line and the rules spelled out underneath: PDF, PNG or JPG, up to 10 MB each, five files at most. Chosen files appear below as rows with a coloured type badge, the name, the size and a remove button. Compact, single file squeezes the same idea into one row for a CSV import, with a Browse button on the right that hides on narrow screens. The technique is simple and robust: the input is stretched over the zone with opacity 0, so a click, Enter or Space, and a file dropped from the desktop all land on the input itself and need no drop handler. A short script adds the rest: a dragover state on the face, checks against the accept list, size and file count with messages that name the file and the rule it broke, a running list that is written back to input.files with DataTransfer so the form submits exactly what is shown, and announcements in a live region. Use the large zone when uploading is the main task on the page and the compact row inside longer forms.
What’s included
- Real file input stretched over the zone, so drop and click are native
- Hover, keyboard focus and dragover states
- Type, size and file-count checks with specific messages
- File list with type badges and remove buttons
- input.files kept in step with the list through DataTransfer
Accessibility
The input is labelled by the visible drop text and described by the limits and the error message. Keyboard users tab to the zone, see a focus ring around it and open the picker with Enter or Space. Each remove button is named after its file, focus moves to the next file or back to the zone after a removal, and additions, removals and rejections are announced in a polite live region. The hover and drag animations switch off under prefers-reduced-motion.
Customise it
Set --dz-accent, --dz-accent-ink, --dz-tint and --dz-line on .dz, and the limits with accept, data-max-size (bytes), data-max-files and data-types on the input. Bootstrap uses the same variables plus .alert and .btn-close; Tailwind reads the dz colours from @theme.





